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_cube_each
20 //! @{
21
22
23 //
24 //
25 // subview_cube_each_common
26
27 template<typename eT>
28 inline
subview_cube_each_common(const Cube<eT> & in_p)29 subview_cube_each_common<eT>::subview_cube_each_common(const Cube<eT>& in_p)
30 : P(in_p)
31 {
32 arma_extra_debug_sigprint();
33 }
34
35
36
37 template<typename eT>
38 inline
39 void
check_size(const Mat<eT> & A) const40 subview_cube_each_common<eT>::check_size(const Mat<eT>& A) const
41 {
42 if(arma_config::debug)
43 {
44 if( (A.n_rows != P.n_rows) || (A.n_cols != P.n_cols) )
45 {
46 arma_stop_logic_error( incompat_size_string(A) );
47 }
48 }
49 }
50
51
52
53 template<typename eT>
54 arma_cold
55 inline
56 const std::string
incompat_size_string(const Mat<eT> & A) const57 subview_cube_each_common<eT>::incompat_size_string(const Mat<eT>& A) const
58 {
59 std::ostringstream tmp;
60
61 tmp << "each_slice(): incompatible size; expected " << P.n_rows << 'x' << P.n_cols << ", got " << A.n_rows << 'x' << A.n_cols;
62
63 return tmp.str();
64 }
65
66
67
68 //
69 //
70 // subview_cube_each1
71
72
73
74 template<typename eT>
75 inline
~subview_cube_each1()76 subview_cube_each1<eT>::~subview_cube_each1()
77 {
78 arma_extra_debug_sigprint();
79 }
80
81
82
83 template<typename eT>
84 inline
subview_cube_each1(const Cube<eT> & in_p)85 subview_cube_each1<eT>::subview_cube_each1(const Cube<eT>& in_p)
86 : subview_cube_each_common<eT>::subview_cube_each_common(in_p)
87 {
88 arma_extra_debug_sigprint();
89 }
90
91
92
93 template<typename eT>
94 template<typename T1>
95 inline
96 void
operator =(const Base<eT,T1> & in)97 subview_cube_each1<eT>::operator= (const Base<eT,T1>& in)
98 {
99 arma_extra_debug_sigprint();
100
101 Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P);
102
103 const unwrap<T1> tmp( in.get_ref() );
104 const Mat<eT>& A = tmp.M;
105
106 subview_cube_each_common<eT>::check_size(A);
107
108 const uword p_n_slices = p.n_slices;
109 const uword p_n_elem_slice = p.n_elem_slice;
110
111 const eT* A_mem = A.memptr();
112
113 for(uword i=0; i < p_n_slices; ++i) { arrayops::copy( p.slice_memptr(i), A_mem, p_n_elem_slice ); }
114 }
115
116
117
118 template<typename eT>
119 template<typename T1>
120 inline
121 void
operator +=(const Base<eT,T1> & in)122 subview_cube_each1<eT>::operator+= (const Base<eT,T1>& in)
123 {
124 arma_extra_debug_sigprint();
125
126 Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P);
127
128 const unwrap<T1> tmp( in.get_ref() );
129 const Mat<eT>& A = tmp.M;
130
131 subview_cube_each_common<eT>::check_size(A);
132
133 const uword p_n_slices = p.n_slices;
134 const uword p_n_elem_slice = p.n_elem_slice;
135
136 const eT* A_mem = A.memptr();
137
138 for(uword i=0; i < p_n_slices; ++i) { arrayops::inplace_plus( p.slice_memptr(i), A_mem, p_n_elem_slice ); }
139 }
140
141
142
143 template<typename eT>
144 template<typename T1>
145 inline
146 void
operator -=(const Base<eT,T1> & in)147 subview_cube_each1<eT>::operator-= (const Base<eT,T1>& in)
148 {
149 arma_extra_debug_sigprint();
150
151 Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P);
152
153 const unwrap<T1> tmp( in.get_ref() );
154 const Mat<eT>& A = tmp.M;
155
156 subview_cube_each_common<eT>::check_size(A);
157
158 const uword p_n_slices = p.n_slices;
159 const uword p_n_elem_slice = p.n_elem_slice;
160
161 const eT* A_mem = A.memptr();
162
163 for(uword i=0; i < p_n_slices; ++i) { arrayops::inplace_minus( p.slice_memptr(i), A_mem, p_n_elem_slice ); }
164 }
165
166
167
168 template<typename eT>
169 template<typename T1>
170 inline
171 void
operator %=(const Base<eT,T1> & in)172 subview_cube_each1<eT>::operator%= (const Base<eT,T1>& in)
173 {
174 arma_extra_debug_sigprint();
175
176 Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P);
177
178 const unwrap<T1> tmp( in.get_ref() );
179 const Mat<eT>& A = tmp.M;
180
181 subview_cube_each_common<eT>::check_size(A);
182
183 const uword p_n_slices = p.n_slices;
184 const uword p_n_elem_slice = p.n_elem_slice;
185
186 const eT* A_mem = A.memptr();
187
188 for(uword i=0; i < p_n_slices; ++i) { arrayops::inplace_mul( p.slice_memptr(i), A_mem, p_n_elem_slice ); }
189 }
190
191
192
193 template<typename eT>
194 template<typename T1>
195 inline
196 void
operator /=(const Base<eT,T1> & in)197 subview_cube_each1<eT>::operator/= (const Base<eT,T1>& in)
198 {
199 arma_extra_debug_sigprint();
200
201 Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P);
202
203 const unwrap<T1> tmp( in.get_ref() );
204 const Mat<eT>& A = tmp.M;
205
206 subview_cube_each_common<eT>::check_size(A);
207
208 const uword p_n_slices = p.n_slices;
209 const uword p_n_elem_slice = p.n_elem_slice;
210
211 const eT* A_mem = A.memptr();
212
213 for(uword i=0; i < p_n_slices; ++i) { arrayops::inplace_div( p.slice_memptr(i), A_mem, p_n_elem_slice ); }
214 }
215
216
217
218 template<typename eT>
219 template<typename T1>
220 inline
221 void
operator *=(const Base<eT,T1> & in)222 subview_cube_each1<eT>::operator*= (const Base<eT,T1>& in)
223 {
224 arma_extra_debug_sigprint();
225
226 Cube<eT>& C = access::rw(subview_cube_each_common<eT>::P);
227
228 C = C.each_slice() * in.get_ref();
229 }
230
231
232
233 //
234 //
235 // subview_cube_each2
236
237
238
239 template<typename eT, typename TB>
240 inline
~subview_cube_each2()241 subview_cube_each2<eT,TB>::~subview_cube_each2()
242 {
243 arma_extra_debug_sigprint();
244 }
245
246
247
248 template<typename eT, typename TB>
249 inline
subview_cube_each2(const Cube<eT> & in_p,const Base<uword,TB> & in_indices)250 subview_cube_each2<eT,TB>::subview_cube_each2(const Cube<eT>& in_p, const Base<uword, TB>& in_indices)
251 : subview_cube_each_common<eT>::subview_cube_each_common(in_p)
252 , base_indices(in_indices)
253 {
254 arma_extra_debug_sigprint();
255 }
256
257
258
259 template<typename eT, typename TB>
260 inline
261 void
check_indices(const Mat<uword> & indices) const262 subview_cube_each2<eT,TB>::check_indices(const Mat<uword>& indices) const
263 {
264 arma_debug_check( ((indices.is_vec() == false) && (indices.is_empty() == false)), "each_slice(): list of indices must be a vector" );
265 }
266
267
268
269 template<typename eT, typename TB>
270 template<typename T1>
271 inline
272 void
operator =(const Base<eT,T1> & in)273 subview_cube_each2<eT,TB>::operator= (const Base<eT,T1>& in)
274 {
275 arma_extra_debug_sigprint();
276
277 Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P);
278
279 const unwrap<T1> tmp( in.get_ref() );
280 const Mat<eT>& A = tmp.M;
281
282 subview_cube_each_common<eT>::check_size(A);
283
284 const unwrap<TB> U( base_indices.get_ref() );
285
286 check_indices(U.M);
287
288 const uword p_n_slices = p.n_slices;
289 const uword p_n_elem_slice = p.n_elem_slice;
290
291 const uword* indices_mem = U.M.memptr();
292 const uword N = U.M.n_elem;
293
294 const eT* A_mem = A.memptr();
295
296 for(uword i=0; i < N; ++i)
297 {
298 const uword slice = indices_mem[i];
299
300 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
301
302 arrayops::copy(p.slice_memptr(slice), A_mem, p_n_elem_slice);
303 }
304 }
305
306
307
308 template<typename eT, typename TB>
309 template<typename T1>
310 inline
311 void
operator +=(const Base<eT,T1> & in)312 subview_cube_each2<eT,TB>::operator+= (const Base<eT,T1>& in)
313 {
314 arma_extra_debug_sigprint();
315
316 Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P);
317
318 const unwrap<T1> tmp( in.get_ref() );
319 const Mat<eT>& A = tmp.M;
320
321 subview_cube_each_common<eT>::check_size(A);
322
323 const unwrap<TB> U( base_indices.get_ref() );
324
325 check_indices(U.M);
326
327 const uword p_n_slices = p.n_slices;
328 const uword p_n_elem_slice = p.n_elem_slice;
329
330 const uword* indices_mem = U.M.memptr();
331 const uword N = U.M.n_elem;
332
333 const eT* A_mem = A.memptr();
334
335 for(uword i=0; i < N; ++i)
336 {
337 const uword slice = indices_mem[i];
338
339 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
340
341 arrayops::inplace_plus(p.slice_memptr(slice), A_mem, p_n_elem_slice);
342 }
343 }
344
345
346
347 template<typename eT, typename TB>
348 template<typename T1>
349 inline
350 void
operator -=(const Base<eT,T1> & in)351 subview_cube_each2<eT,TB>::operator-= (const Base<eT,T1>& in)
352 {
353 arma_extra_debug_sigprint();
354
355 Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P);
356
357 const unwrap<T1> tmp( in.get_ref() );
358 const Mat<eT>& A = tmp.M;
359
360 subview_cube_each_common<eT>::check_size(A);
361
362 const unwrap<TB> U( base_indices.get_ref() );
363
364 check_indices(U.M);
365
366 const uword p_n_slices = p.n_slices;
367 const uword p_n_elem_slice = p.n_elem_slice;
368
369 const uword* indices_mem = U.M.memptr();
370 const uword N = U.M.n_elem;
371
372 const eT* A_mem = A.memptr();
373
374 for(uword i=0; i < N; ++i)
375 {
376 const uword slice = indices_mem[i];
377
378 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
379
380 arrayops::inplace_minus(p.slice_memptr(slice), A_mem, p_n_elem_slice);
381 }
382 }
383
384
385
386 template<typename eT, typename TB>
387 template<typename T1>
388 inline
389 void
operator %=(const Base<eT,T1> & in)390 subview_cube_each2<eT,TB>::operator%= (const Base<eT,T1>& in)
391 {
392 arma_extra_debug_sigprint();
393
394 Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P);
395
396 const unwrap<T1> tmp( in.get_ref() );
397 const Mat<eT>& A = tmp.M;
398
399 subview_cube_each_common<eT>::check_size(A);
400
401 const unwrap<TB> U( base_indices.get_ref() );
402
403 check_indices(U.M);
404
405 const uword p_n_slices = p.n_slices;
406 const uword p_n_elem_slice = p.n_elem_slice;
407
408 const uword* indices_mem = U.M.memptr();
409 const uword N = U.M.n_elem;
410
411 const eT* A_mem = A.memptr();
412
413 for(uword i=0; i < N; ++i)
414 {
415 const uword slice = indices_mem[i];
416
417 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
418
419 arrayops::inplace_mul(p.slice_memptr(slice), A_mem, p_n_elem_slice);
420 }
421 }
422
423
424
425 template<typename eT, typename TB>
426 template<typename T1>
427 inline
428 void
operator /=(const Base<eT,T1> & in)429 subview_cube_each2<eT,TB>::operator/= (const Base<eT,T1>& in)
430 {
431 arma_extra_debug_sigprint();
432
433 Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P);
434
435 const unwrap<T1> tmp( in.get_ref() );
436 const Mat<eT>& A = tmp.M;
437
438 subview_cube_each_common<eT>::check_size(A);
439
440 const unwrap<TB> U( base_indices.get_ref() );
441
442 check_indices(U.M);
443
444 const uword p_n_slices = p.n_slices;
445 const uword p_n_elem_slice = p.n_elem_slice;
446
447 const uword* indices_mem = U.M.memptr();
448 const uword N = U.M.n_elem;
449
450 const eT* A_mem = A.memptr();
451
452 for(uword i=0; i < N; ++i)
453 {
454 const uword slice = indices_mem[i];
455
456 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
457
458 arrayops::inplace_div(p.slice_memptr(slice), A_mem, p_n_elem_slice);
459 }
460 }
461
462
463
464 //
465 //
466 // subview_cube_each1_aux
467
468
469
470 template<typename eT, typename T2>
471 inline
472 Cube<eT>
operator_plus(const subview_cube_each1<eT> & X,const Base<eT,T2> & Y)473 subview_cube_each1_aux::operator_plus
474 (
475 const subview_cube_each1<eT>& X,
476 const Base<eT,T2>& Y
477 )
478 {
479 arma_extra_debug_sigprint();
480
481 const Cube<eT>& p = X.P;
482
483 const uword p_n_rows = p.n_rows;
484 const uword p_n_cols = p.n_cols;
485 const uword p_n_slices = p.n_slices;
486
487 Cube<eT> out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator());
488
489 const unwrap<T2> tmp(Y.get_ref());
490 const Mat<eT>& A = tmp.M;
491
492 X.check_size(A);
493
494 for(uword i=0; i < p_n_slices; ++i)
495 {
496 Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
497 const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
498
499 out_slice = p_slice + A;
500 }
501
502 return out;
503 }
504
505
506
507 template<typename eT, typename T2>
508 inline
509 Cube<eT>
operator_minus(const subview_cube_each1<eT> & X,const Base<eT,T2> & Y)510 subview_cube_each1_aux::operator_minus
511 (
512 const subview_cube_each1<eT>& X,
513 const Base<eT,T2>& Y
514 )
515 {
516 arma_extra_debug_sigprint();
517
518 const Cube<eT>& p = X.P;
519
520 const uword p_n_rows = p.n_rows;
521 const uword p_n_cols = p.n_cols;
522 const uword p_n_slices = p.n_slices;
523
524 Cube<eT> out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator());
525
526 const unwrap<T2> tmp(Y.get_ref());
527 const Mat<eT>& A = tmp.M;
528
529 X.check_size(A);
530
531 for(uword i=0; i < p_n_slices; ++i)
532 {
533 Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
534 const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
535
536 out_slice = p_slice - A;
537 }
538
539 return out;
540 }
541
542
543
544 template<typename T1, typename eT>
545 inline
546 Cube<eT>
operator_minus(const Base<eT,T1> & X,const subview_cube_each1<eT> & Y)547 subview_cube_each1_aux::operator_minus
548 (
549 const Base<eT,T1>& X,
550 const subview_cube_each1<eT>& Y
551 )
552 {
553 arma_extra_debug_sigprint();
554
555 const Cube<eT>& p = Y.P;
556
557 const uword p_n_rows = p.n_rows;
558 const uword p_n_cols = p.n_cols;
559 const uword p_n_slices = p.n_slices;
560
561 Cube<eT> out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator());
562
563 const unwrap<T1> tmp(X.get_ref());
564 const Mat<eT>& A = tmp.M;
565
566 Y.check_size(A);
567
568 for(uword i=0; i < p_n_slices; ++i)
569 {
570 Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
571 const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
572
573 out_slice = A - p_slice;
574 }
575
576 return out;
577 }
578
579
580
581 template<typename eT, typename T2>
582 inline
583 Cube<eT>
operator_schur(const subview_cube_each1<eT> & X,const Base<eT,T2> & Y)584 subview_cube_each1_aux::operator_schur
585 (
586 const subview_cube_each1<eT>& X,
587 const Base<eT,T2>& Y
588 )
589 {
590 arma_extra_debug_sigprint();
591
592 const Cube<eT>& p = X.P;
593
594 const uword p_n_rows = p.n_rows;
595 const uword p_n_cols = p.n_cols;
596 const uword p_n_slices = p.n_slices;
597
598 Cube<eT> out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator());
599
600 const unwrap<T2> tmp(Y.get_ref());
601 const Mat<eT>& A = tmp.M;
602
603 X.check_size(A);
604
605 for(uword i=0; i < p_n_slices; ++i)
606 {
607 Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
608 const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
609
610 out_slice = p_slice % A;
611 }
612
613 return out;
614 }
615
616
617
618 template<typename eT, typename T2>
619 inline
620 Cube<eT>
operator_div(const subview_cube_each1<eT> & X,const Base<eT,T2> & Y)621 subview_cube_each1_aux::operator_div
622 (
623 const subview_cube_each1<eT>& X,
624 const Base<eT,T2>& Y
625 )
626 {
627 arma_extra_debug_sigprint();
628
629 const Cube<eT>& p = X.P;
630
631 const uword p_n_rows = p.n_rows;
632 const uword p_n_cols = p.n_cols;
633 const uword p_n_slices = p.n_slices;
634
635 Cube<eT> out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator());
636
637 const unwrap<T2> tmp(Y.get_ref());
638 const Mat<eT>& A = tmp.M;
639
640 X.check_size(A);
641
642 for(uword i=0; i < p_n_slices; ++i)
643 {
644 Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
645 const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
646
647 out_slice = p_slice / A;
648 }
649
650 return out;
651 }
652
653
654
655 template<typename T1, typename eT>
656 inline
657 Cube<eT>
operator_div(const Base<eT,T1> & X,const subview_cube_each1<eT> & Y)658 subview_cube_each1_aux::operator_div
659 (
660 const Base<eT,T1>& X,
661 const subview_cube_each1<eT>& Y
662 )
663 {
664 arma_extra_debug_sigprint();
665
666 const Cube<eT>& p = Y.P;
667
668 const uword p_n_rows = p.n_rows;
669 const uword p_n_cols = p.n_cols;
670 const uword p_n_slices = p.n_slices;
671
672 Cube<eT> out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator());
673
674 const unwrap<T1> tmp(X.get_ref());
675 const Mat<eT>& A = tmp.M;
676
677 Y.check_size(A);
678
679 for(uword i=0; i < p_n_slices; ++i)
680 {
681 Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
682 const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
683
684 out_slice = A / p_slice;
685 }
686
687 return out;
688 }
689
690
691
692 template<typename eT, typename T2>
693 inline
694 Cube<eT>
operator_times(const subview_cube_each1<eT> & X,const Base<eT,T2> & Y)695 subview_cube_each1_aux::operator_times
696 (
697 const subview_cube_each1<eT>& X,
698 const Base<eT,T2>& Y
699 )
700 {
701 arma_extra_debug_sigprint();
702
703 const Cube<eT>& C = X.P;
704
705 const unwrap<T2> tmp(Y.get_ref());
706 const Mat<eT>& M = tmp.M;
707
708 Cube<eT> out(C.n_rows, M.n_cols, C.n_slices, arma_nozeros_indicator());
709
710 for(uword i=0; i < C.n_slices; ++i)
711 {
712 Mat<eT> out_slice( out.slice_memptr(i), C.n_rows, M.n_cols, false, true);
713 const Mat<eT> C_slice(const_cast<eT*>(C.slice_memptr(i)), C.n_rows, C.n_cols, false, true);
714
715 out_slice = C_slice * M;
716 }
717
718 return out;
719 }
720
721
722
723 template<typename T1, typename eT>
724 inline
725 Cube<eT>
operator_times(const Base<eT,T1> & X,const subview_cube_each1<eT> & Y)726 subview_cube_each1_aux::operator_times
727 (
728 const Base<eT,T1>& X,
729 const subview_cube_each1<eT>& Y
730 )
731 {
732 arma_extra_debug_sigprint();
733
734 const unwrap<T1> tmp(X.get_ref());
735 const Mat<eT>& M = tmp.M;
736
737 const Cube<eT>& C = Y.P;
738
739 Cube<eT> out(M.n_rows, C.n_cols, C.n_slices, arma_nozeros_indicator());
740
741 for(uword i=0; i < C.n_slices; ++i)
742 {
743 Mat<eT> out_slice( out.slice_memptr(i), M.n_rows, C.n_cols, false, true);
744 const Mat<eT> C_slice(const_cast<eT*>(C.slice_memptr(i)), C.n_rows, C.n_cols, false, true);
745
746 out_slice = M * C_slice;
747 }
748
749 return out;
750 }
751
752
753
754 //
755 //
756 // subview_cube_each2_aux
757
758
759
760 template<typename eT, typename TB, typename T2>
761 inline
762 Cube<eT>
operator_plus(const subview_cube_each2<eT,TB> & X,const Base<eT,T2> & Y)763 subview_cube_each2_aux::operator_plus
764 (
765 const subview_cube_each2<eT,TB>& X,
766 const Base<eT,T2>& Y
767 )
768 {
769 arma_extra_debug_sigprint();
770
771 const Cube<eT>& p = X.P;
772
773 const uword p_n_slices = p.n_slices;
774 const uword p_n_elem_slice = p.n_elem_slice;
775
776 Cube<eT> out = p;
777
778 const unwrap<T2> tmp(Y.get_ref());
779 const Mat<eT>& A = tmp.M;
780
781 const unwrap<TB> U(X.base_indices.get_ref());
782
783 X.check_size(A);
784 X.check_indices(U.M);
785
786 const uword* indices_mem = U.M.memptr();
787 const uword N = U.M.n_elem;
788
789 const eT* A_mem = A.memptr();
790
791 for(uword i=0; i < N; ++i)
792 {
793 const uword slice = indices_mem[i];
794
795 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
796
797 arrayops::inplace_plus(out.slice_memptr(slice), A_mem, p_n_elem_slice);
798 }
799
800 return out;
801 }
802
803
804
805 template<typename eT, typename TB, typename T2>
806 inline
807 Cube<eT>
operator_minus(const subview_cube_each2<eT,TB> & X,const Base<eT,T2> & Y)808 subview_cube_each2_aux::operator_minus
809 (
810 const subview_cube_each2<eT,TB>& X,
811 const Base<eT,T2>& Y
812 )
813 {
814 arma_extra_debug_sigprint();
815
816 const Cube<eT>& p = X.P;
817
818 const uword p_n_slices = p.n_slices;
819 const uword p_n_elem_slice = p.n_elem_slice;
820
821 Cube<eT> out = p;
822
823 const unwrap<T2> tmp(Y.get_ref());
824 const Mat<eT>& A = tmp.M;
825
826 const unwrap<TB> U(X.base_indices.get_ref());
827
828 X.check_size(A);
829 X.check_indices(U.M);
830
831 const uword* indices_mem = U.M.memptr();
832 const uword N = U.M.n_elem;
833
834 const eT* A_mem = A.memptr();
835
836 for(uword i=0; i < N; ++i)
837 {
838 const uword slice = indices_mem[i];
839
840 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
841
842 arrayops::inplace_minus(out.slice_memptr(slice), A_mem, p_n_elem_slice);
843 }
844
845 return out;
846 }
847
848
849
850 template<typename T1, typename eT, typename TB>
851 inline
852 Cube<eT>
operator_minus(const Base<eT,T1> & X,const subview_cube_each2<eT,TB> & Y)853 subview_cube_each2_aux::operator_minus
854 (
855 const Base<eT,T1>& X,
856 const subview_cube_each2<eT,TB>& Y
857 )
858 {
859 arma_extra_debug_sigprint();
860
861 const Cube<eT>& p = Y.P;
862
863 const uword p_n_rows = p.n_rows;
864 const uword p_n_cols = p.n_cols;
865 const uword p_n_slices = p.n_slices;
866
867 Cube<eT> out = p;
868
869 const unwrap<T1> tmp(X.get_ref());
870 const Mat<eT>& A = tmp.M;
871
872 const unwrap<TB> U(Y.base_indices.get_ref());
873
874 Y.check_size(A);
875 Y.check_indices(U.M);
876
877 const uword* indices_mem = U.M.memptr();
878 const uword N = U.M.n_elem;
879
880 for(uword i=0; i < N; ++i)
881 {
882 const uword slice = indices_mem[i];
883
884 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
885
886 Mat<eT> out_slice( out.slice_memptr(slice), p_n_rows, p_n_cols, false, true);
887 const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(slice)), p_n_rows, p_n_cols, false, true);
888
889 out_slice = A - p_slice;
890 }
891
892 return out;
893 }
894
895
896
897 template<typename eT, typename TB, typename T2>
898 inline
899 Cube<eT>
operator_schur(const subview_cube_each2<eT,TB> & X,const Base<eT,T2> & Y)900 subview_cube_each2_aux::operator_schur
901 (
902 const subview_cube_each2<eT,TB>& X,
903 const Base<eT,T2>& Y
904 )
905 {
906 arma_extra_debug_sigprint();
907
908 const Cube<eT>& p = X.P;
909
910 const uword p_n_slices = p.n_slices;
911 const uword p_n_elem_slice = p.n_elem_slice;
912
913 Cube<eT> out = p;
914
915 const unwrap<T2> tmp(Y.get_ref());
916 const Mat<eT>& A = tmp.M;
917
918 const unwrap<TB> U(X.base_indices.get_ref());
919
920 X.check_size(A);
921 X.check_indices(U.M);
922
923 const uword* indices_mem = U.M.memptr();
924 const uword N = U.M.n_elem;
925
926 const eT* A_mem = A.memptr();
927
928 for(uword i=0; i < N; ++i)
929 {
930 const uword slice = indices_mem[i];
931
932 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
933
934 arrayops::inplace_mul(out.slice_memptr(slice), A_mem, p_n_elem_slice);
935 }
936
937 return out;
938 }
939
940
941
942 template<typename eT, typename TB, typename T2>
943 inline
944 Cube<eT>
operator_div(const subview_cube_each2<eT,TB> & X,const Base<eT,T2> & Y)945 subview_cube_each2_aux::operator_div
946 (
947 const subview_cube_each2<eT,TB>& X,
948 const Base<eT,T2>& Y
949 )
950 {
951 arma_extra_debug_sigprint();
952
953 const Cube<eT>& p = X.P;
954
955 const uword p_n_slices = p.n_slices;
956 const uword p_n_elem_slice = p.n_elem_slice;
957
958 Cube<eT> out = p;
959
960 const unwrap<T2> tmp(Y.get_ref());
961 const Mat<eT>& A = tmp.M;
962
963 const unwrap<TB> U(X.base_indices.get_ref());
964
965 X.check_size(A);
966 X.check_indices(U.M);
967
968 const uword* indices_mem = U.M.memptr();
969 const uword N = U.M.n_elem;
970
971 const eT* A_mem = A.memptr();
972
973 for(uword i=0; i < N; ++i)
974 {
975 const uword slice = indices_mem[i];
976
977 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
978
979 arrayops::inplace_div(out.slice_memptr(slice), A_mem, p_n_elem_slice);
980 }
981
982 return out;
983 }
984
985
986
987 template<typename T1, typename eT, typename TB>
988 inline
989 Cube<eT>
operator_div(const Base<eT,T1> & X,const subview_cube_each2<eT,TB> & Y)990 subview_cube_each2_aux::operator_div
991 (
992 const Base<eT,T1>& X,
993 const subview_cube_each2<eT,TB>& Y
994 )
995 {
996 arma_extra_debug_sigprint();
997
998 const Cube<eT>& p = Y.P;
999
1000 const uword p_n_rows = p.n_rows;
1001 const uword p_n_cols = p.n_cols;
1002 const uword p_n_slices = p.n_slices;
1003
1004 Cube<eT> out = p;
1005
1006 const unwrap<T1> tmp(X.get_ref());
1007 const Mat<eT>& A = tmp.M;
1008
1009 const unwrap<TB> U(Y.base_indices.get_ref());
1010
1011 Y.check_size(A);
1012 Y.check_indices(U.M);
1013
1014 const uword* indices_mem = U.M.memptr();
1015 const uword N = U.M.n_elem;
1016
1017 for(uword i=0; i < N; ++i)
1018 {
1019 const uword slice = indices_mem[i];
1020
1021 arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
1022
1023 Mat<eT> out_slice( out.slice_memptr(slice), p_n_rows, p_n_cols, false, true);
1024 const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(slice)), p_n_rows, p_n_cols, false, true);
1025
1026 out_slice = A / p_slice;
1027 }
1028
1029 return out;
1030 }
1031
1032
1033
1034 //! @}
1035