Mercurial > hg > segmenter-vamp-plugin
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 //! @} |