Mercurial > hg > segmenter-vamp-plugin
comparison armadillo-3.900.4/include/armadillo_bits/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 Cube | |
10 //! @{ | |
11 | |
12 | |
13 template<typename eT> | |
14 inline | |
15 Cube<eT>::~Cube() | |
16 { | |
17 arma_extra_debug_sigprint_this(this); | |
18 | |
19 delete_mat(); | |
20 | |
21 if(mem_state == 0) | |
22 { | |
23 if(n_elem > Cube_prealloc::mem_n_elem) | |
24 { | |
25 memory::release( access::rw(mem) ); | |
26 } | |
27 } | |
28 | |
29 if(arma_config::debug == true) | |
30 { | |
31 // try to expose buggy user code that accesses deleted objects | |
32 access::rw(mat_ptrs) = 0; | |
33 access::rw(mem) = 0; | |
34 } | |
35 | |
36 arma_type_check(( is_supported_elem_type<eT>::value == false )); | |
37 } | |
38 | |
39 | |
40 | |
41 template<typename eT> | |
42 inline | |
43 Cube<eT>::Cube() | |
44 : n_rows(0) | |
45 , n_cols(0) | |
46 , n_elem_slice(0) | |
47 , n_slices(0) | |
48 , n_elem(0) | |
49 , mem_state(0) | |
50 , mat_ptrs() | |
51 , mem() | |
52 { | |
53 arma_extra_debug_sigprint_this(this); | |
54 } | |
55 | |
56 | |
57 | |
58 //! construct the cube to have user specified dimensions | |
59 template<typename eT> | |
60 inline | |
61 Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices) | |
62 : n_rows(in_n_rows) | |
63 , n_cols(in_n_cols) | |
64 , n_elem_slice(in_n_rows*in_n_cols) | |
65 , n_slices(in_n_slices) | |
66 , n_elem(in_n_rows*in_n_cols*in_n_slices) | |
67 , mem_state(0) | |
68 , mat_ptrs() | |
69 , mem() | |
70 { | |
71 arma_extra_debug_sigprint_this(this); | |
72 | |
73 init_cold(); | |
74 } | |
75 | |
76 | |
77 | |
78 template<typename eT> | |
79 inline | |
80 void | |
81 Cube<eT>::init_cold() | |
82 { | |
83 arma_extra_debug_sigprint( arma_boost::format("n_rows = %d, n_cols = %d, n_slices = %d") % n_rows % n_cols % n_slices ); | |
84 | |
85 arma_debug_check | |
86 ( | |
87 ( | |
88 ( (n_rows > 0x0FFF) || (n_cols > 0x0FFF) || (n_slices > 0xFF) ) | |
89 ? ( (float(n_rows) * float(n_cols) * float(n_slices)) > float(ARMA_MAX_UWORD) ) | |
90 : false | |
91 ), | |
92 "Cube::init(): requested size is too large" | |
93 ); | |
94 | |
95 if(n_elem <= Cube_prealloc::mem_n_elem) | |
96 { | |
97 access::rw(mem) = mem_local; | |
98 } | |
99 else | |
100 { | |
101 arma_extra_debug_print("Cube::init(): allocating memory"); | |
102 | |
103 access::rw(mem) = memory::acquire<eT>(n_elem); | |
104 | |
105 arma_check_bad_alloc( (mem == 0), "Cube::init(): out of memory" ); | |
106 } | |
107 | |
108 | |
109 if(n_elem == 0) | |
110 { | |
111 access::rw(n_rows) = 0; | |
112 access::rw(n_cols) = 0; | |
113 access::rw(n_elem_slice) = 0; | |
114 access::rw(n_slices) = 0; | |
115 } | |
116 else | |
117 { | |
118 create_mat(); | |
119 } | |
120 } | |
121 | |
122 | |
123 | |
124 //! internal cube construction; if the requested size is small enough, memory from the stack is used. | |
125 //! otherwise memory is allocated via 'new' | |
126 template<typename eT> | |
127 inline | |
128 void | |
129 Cube<eT>::init_warm(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices) | |
130 { | |
131 arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d, in_n_slices = %d") % in_n_rows % in_n_cols % in_n_slices ); | |
132 | |
133 if( (n_rows == in_n_rows) && (n_cols == in_n_cols) && (n_slices == in_n_slices) ) | |
134 { | |
135 return; | |
136 } | |
137 | |
138 const uword t_mem_state = mem_state; | |
139 | |
140 bool err_state = false; | |
141 char* err_msg = 0; | |
142 | |
143 arma_debug_set_error | |
144 ( | |
145 err_state, | |
146 err_msg, | |
147 (t_mem_state == 3), | |
148 "Cube::init(): size is fixed and hence cannot be changed" | |
149 ); | |
150 | |
151 arma_debug_set_error | |
152 ( | |
153 err_state, | |
154 err_msg, | |
155 ( | |
156 ( (in_n_rows > 0x0FFF) || (in_n_cols > 0x0FFF) || (in_n_slices > 0xFF) ) | |
157 ? ( (float(in_n_rows) * float(in_n_cols) * float(in_n_slices)) > float(ARMA_MAX_UWORD) ) | |
158 : false | |
159 ), | |
160 "Cube::init(): requested size is too large" | |
161 ); | |
162 | |
163 arma_debug_check(err_state, err_msg); | |
164 | |
165 const uword old_n_elem = n_elem; | |
166 const uword new_n_elem = in_n_rows * in_n_cols * in_n_slices; | |
167 | |
168 if(old_n_elem == new_n_elem) | |
169 { | |
170 delete_mat(); | |
171 | |
172 if(new_n_elem > 0) | |
173 { | |
174 access::rw(n_rows) = in_n_rows; | |
175 access::rw(n_cols) = in_n_cols; | |
176 access::rw(n_elem_slice) = in_n_rows*in_n_cols; | |
177 access::rw(n_slices) = in_n_slices; | |
178 | |
179 create_mat(); | |
180 } | |
181 } | |
182 else | |
183 { | |
184 arma_debug_check( (t_mem_state == 2), "Cube::init(): requested size is not compatible with the size of auxiliary memory" ); | |
185 | |
186 delete_mat(); | |
187 | |
188 if(t_mem_state == 0) | |
189 { | |
190 if(n_elem > Cube_prealloc::mem_n_elem ) | |
191 { | |
192 arma_extra_debug_print("Cube::init(): freeing memory"); | |
193 | |
194 memory::release( access::rw(mem) ); | |
195 } | |
196 } | |
197 | |
198 access::rw(mem_state) = 0; | |
199 | |
200 if(new_n_elem <= Cube_prealloc::mem_n_elem) | |
201 { | |
202 access::rw(mem) = mem_local; | |
203 } | |
204 else | |
205 { | |
206 arma_extra_debug_print("Cube::init(): allocating memory"); | |
207 | |
208 access::rw(mem) = memory::acquire<eT>(new_n_elem); | |
209 | |
210 arma_check_bad_alloc( (mem == 0), "Cube::init(): out of memory" ); | |
211 } | |
212 | |
213 if(new_n_elem > 0) | |
214 { | |
215 access::rw(n_rows) = in_n_rows; | |
216 access::rw(n_cols) = in_n_cols; | |
217 access::rw(n_elem_slice) = in_n_rows*in_n_cols; | |
218 access::rw(n_slices) = in_n_slices; | |
219 access::rw(n_elem) = new_n_elem; | |
220 | |
221 create_mat(); | |
222 } | |
223 } | |
224 | |
225 | |
226 if(new_n_elem == 0) | |
227 { | |
228 access::rw(n_rows) = 0; | |
229 access::rw(n_cols) = 0; | |
230 access::rw(n_elem_slice) = 0; | |
231 access::rw(n_slices) = 0; | |
232 access::rw(n_elem) = 0; | |
233 } | |
234 } | |
235 | |
236 | |
237 | |
238 //! for constructing a complex cube out of two non-complex cubes | |
239 template<typename eT> | |
240 template<typename T1, typename T2> | |
241 inline | |
242 void | |
243 Cube<eT>::init | |
244 ( | |
245 const BaseCube<typename Cube<eT>::pod_type,T1>& X, | |
246 const BaseCube<typename Cube<eT>::pod_type,T2>& Y | |
247 ) | |
248 { | |
249 arma_extra_debug_sigprint(); | |
250 | |
251 typedef typename T1::elem_type T; | |
252 | |
253 arma_type_check(( is_complex<eT>::value == false )); //!< compile-time abort if eT isn't std::complex | |
254 arma_type_check(( is_complex< T>::value == true )); //!< compile-time abort if T is std::complex | |
255 | |
256 arma_type_check(( is_same_type< std::complex<T>, eT >::value == false )); //!< compile-time abort if types are not compatible | |
257 | |
258 const ProxyCube<T1> PX(X.get_ref()); | |
259 const ProxyCube<T2> PY(Y.get_ref()); | |
260 | |
261 arma_debug_assert_same_size(PX, PY, "Cube()"); | |
262 | |
263 const uword local_n_rows = PX.get_n_rows(); | |
264 const uword local_n_cols = PX.get_n_cols(); | |
265 const uword local_n_slices = PX.get_n_slices(); | |
266 | |
267 init_warm(local_n_rows, local_n_cols, local_n_slices); | |
268 | |
269 eT* out_mem = (*this).memptr(); | |
270 | |
271 const bool prefer_at_accessor = ( ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor ); | |
272 | |
273 if(prefer_at_accessor == false) | |
274 { | |
275 typedef typename ProxyCube<T1>::ea_type ea_type1; | |
276 typedef typename ProxyCube<T2>::ea_type ea_type2; | |
277 | |
278 const uword N = n_elem; | |
279 | |
280 ea_type1 A = PX.get_ea(); | |
281 ea_type2 B = PY.get_ea(); | |
282 | |
283 for(uword i=0; i<N; ++i) | |
284 { | |
285 out_mem[i] = std::complex<T>(A[i], B[i]); | |
286 } | |
287 } | |
288 else | |
289 { | |
290 for(uword uslice = 0; uslice < local_n_slices; ++uslice) | |
291 for(uword ucol = 0; ucol < local_n_cols; ++ucol ) | |
292 for(uword urow = 0; urow < local_n_rows; ++urow ) | |
293 { | |
294 *out_mem = std::complex<T>( PX.at(urow,ucol,uslice), PY.at(urow,ucol,uslice) ); | |
295 out_mem++; | |
296 } | |
297 } | |
298 } | |
299 | |
300 | |
301 | |
302 template<typename eT> | |
303 inline | |
304 void | |
305 Cube<eT>::delete_mat() | |
306 { | |
307 arma_extra_debug_sigprint(); | |
308 | |
309 for(uword uslice = 0; uslice < n_slices; ++uslice) | |
310 { | |
311 delete access::rw(mat_ptrs[uslice]); | |
312 } | |
313 | |
314 if(mem_state <= 2) | |
315 { | |
316 if(n_slices > Cube_prealloc::mat_ptrs_size) | |
317 { | |
318 delete [] mat_ptrs; | |
319 } | |
320 } | |
321 } | |
322 | |
323 | |
324 | |
325 template<typename eT> | |
326 inline | |
327 void | |
328 Cube<eT>::create_mat() | |
329 { | |
330 arma_extra_debug_sigprint(); | |
331 | |
332 if(mem_state <= 2) | |
333 { | |
334 if(n_slices <= Cube_prealloc::mat_ptrs_size) | |
335 { | |
336 access::rw(mat_ptrs) = const_cast< const Mat<eT>** >(mat_ptrs_local); | |
337 } | |
338 else | |
339 { | |
340 access::rw(mat_ptrs) = new(std::nothrow) const Mat<eT>*[n_slices]; | |
341 | |
342 arma_check_bad_alloc( (mat_ptrs == 0), "Cube::create_mat(): out of memory" ); | |
343 } | |
344 } | |
345 | |
346 for(uword uslice = 0; uslice < n_slices; ++uslice) | |
347 { | |
348 mat_ptrs[uslice] = new Mat<eT>('j', slice_memptr(uslice), n_rows, n_cols); | |
349 } | |
350 } | |
351 | |
352 | |
353 | |
354 //! Set the cube to be equal to the specified scalar. | |
355 //! NOTE: the size of the cube will be 1x1x1 | |
356 template<typename eT> | |
357 arma_inline | |
358 const Cube<eT>& | |
359 Cube<eT>::operator=(const eT val) | |
360 { | |
361 arma_extra_debug_sigprint(); | |
362 | |
363 init_warm(1,1,1); | |
364 access::rw(mem[0]) = val; | |
365 return *this; | |
366 } | |
367 | |
368 | |
369 | |
370 //! In-place addition of a scalar to all elements of the cube | |
371 template<typename eT> | |
372 arma_inline | |
373 const Cube<eT>& | |
374 Cube<eT>::operator+=(const eT val) | |
375 { | |
376 arma_extra_debug_sigprint(); | |
377 | |
378 arrayops::inplace_plus( memptr(), val, n_elem ); | |
379 | |
380 return *this; | |
381 } | |
382 | |
383 | |
384 | |
385 //! In-place subtraction of a scalar from all elements of the cube | |
386 template<typename eT> | |
387 arma_inline | |
388 const Cube<eT>& | |
389 Cube<eT>::operator-=(const eT val) | |
390 { | |
391 arma_extra_debug_sigprint(); | |
392 | |
393 arrayops::inplace_minus( memptr(), val, n_elem ); | |
394 | |
395 return *this; | |
396 } | |
397 | |
398 | |
399 | |
400 //! In-place multiplication of all elements of the cube with a scalar | |
401 template<typename eT> | |
402 arma_inline | |
403 const Cube<eT>& | |
404 Cube<eT>::operator*=(const eT val) | |
405 { | |
406 arma_extra_debug_sigprint(); | |
407 | |
408 arrayops::inplace_mul( memptr(), val, n_elem ); | |
409 | |
410 return *this; | |
411 } | |
412 | |
413 | |
414 | |
415 //! In-place division of all elements of the cube with a scalar | |
416 template<typename eT> | |
417 arma_inline | |
418 const Cube<eT>& | |
419 Cube<eT>::operator/=(const eT val) | |
420 { | |
421 arma_extra_debug_sigprint(); | |
422 | |
423 arrayops::inplace_div( memptr(), val, n_elem ); | |
424 | |
425 return *this; | |
426 } | |
427 | |
428 | |
429 | |
430 //! construct a cube from a given cube | |
431 template<typename eT> | |
432 inline | |
433 Cube<eT>::Cube(const Cube<eT>& x) | |
434 : n_rows(x.n_rows) | |
435 , n_cols(x.n_cols) | |
436 , n_elem_slice(x.n_elem_slice) | |
437 , n_slices(x.n_slices) | |
438 , n_elem(x.n_elem) | |
439 , mem_state(0) | |
440 , mat_ptrs() | |
441 , mem() | |
442 { | |
443 arma_extra_debug_sigprint_this(this); | |
444 arma_extra_debug_sigprint(arma_boost::format("this = %x in_cube = %x") % this % &x); | |
445 | |
446 init_cold(); | |
447 | |
448 arrayops::copy( memptr(), x.mem, n_elem ); | |
449 } | |
450 | |
451 | |
452 | |
453 //! construct a cube from a given cube | |
454 template<typename eT> | |
455 inline | |
456 const Cube<eT>& | |
457 Cube<eT>::operator=(const Cube<eT>& x) | |
458 { | |
459 arma_extra_debug_sigprint(arma_boost::format("this = %x in_cube = %x") % this % &x); | |
460 | |
461 if(this != &x) | |
462 { | |
463 init_warm(x.n_rows, x.n_cols, x.n_slices); | |
464 | |
465 arrayops::copy( memptr(), x.mem, n_elem ); | |
466 } | |
467 | |
468 return *this; | |
469 } | |
470 | |
471 | |
472 | |
473 //! construct a cube from a given auxiliary array of eTs. | |
474 //! if copy_aux_mem is true, new memory is allocated and the array is copied. | |
475 //! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying). | |
476 //! note that in the latter case | |
477 //! the default is to copy the array. | |
478 | |
479 template<typename eT> | |
480 inline | |
481 Cube<eT>::Cube(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices, const bool copy_aux_mem, const bool strict) | |
482 : n_rows ( aux_n_rows ) | |
483 , n_cols ( aux_n_cols ) | |
484 , n_elem_slice( aux_n_rows*aux_n_cols ) | |
485 , n_slices ( aux_n_slices ) | |
486 , n_elem ( aux_n_rows*aux_n_cols*aux_n_slices ) | |
487 , mem_state ( copy_aux_mem ? 0 : (strict ? 2 : 1) ) | |
488 , mat_ptrs ( 0 ) | |
489 , mem ( copy_aux_mem ? 0 : aux_mem ) | |
490 { | |
491 arma_extra_debug_sigprint_this(this); | |
492 | |
493 if(copy_aux_mem == true) | |
494 { | |
495 init_cold(); | |
496 | |
497 arrayops::copy( memptr(), aux_mem, n_elem ); | |
498 } | |
499 else | |
500 { | |
501 create_mat(); | |
502 } | |
503 } | |
504 | |
505 | |
506 | |
507 //! construct a cube from a given auxiliary read-only array of eTs. | |
508 //! the array is copied. | |
509 template<typename eT> | |
510 inline | |
511 Cube<eT>::Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices) | |
512 : n_rows(aux_n_rows) | |
513 , n_cols(aux_n_cols) | |
514 , n_elem_slice(aux_n_rows*aux_n_cols) | |
515 , n_slices(aux_n_slices) | |
516 , n_elem(aux_n_rows*aux_n_cols*aux_n_slices) | |
517 , mem_state(0) | |
518 , mat_ptrs() | |
519 , mem() | |
520 { | |
521 arma_extra_debug_sigprint_this(this); | |
522 | |
523 init_cold(); | |
524 | |
525 arrayops::copy( memptr(), aux_mem, n_elem ); | |
526 } | |
527 | |
528 | |
529 | |
530 //! in-place cube addition | |
531 template<typename eT> | |
532 inline | |
533 const Cube<eT>& | |
534 Cube<eT>::operator+=(const Cube<eT>& m) | |
535 { | |
536 arma_extra_debug_sigprint(); | |
537 | |
538 arma_debug_assert_same_size(*this, m, "addition"); | |
539 | |
540 arrayops::inplace_plus( memptr(), m.memptr(), n_elem ); | |
541 | |
542 return *this; | |
543 } | |
544 | |
545 | |
546 | |
547 //! in-place cube subtraction | |
548 template<typename eT> | |
549 inline | |
550 const Cube<eT>& | |
551 Cube<eT>::operator-=(const Cube<eT>& m) | |
552 { | |
553 arma_extra_debug_sigprint(); | |
554 | |
555 arma_debug_assert_same_size(*this, m, "subtraction"); | |
556 | |
557 arrayops::inplace_minus( memptr(), m.memptr(), n_elem ); | |
558 | |
559 return *this; | |
560 } | |
561 | |
562 | |
563 | |
564 //! in-place element-wise cube multiplication | |
565 template<typename eT> | |
566 inline | |
567 const Cube<eT>& | |
568 Cube<eT>::operator%=(const Cube<eT>& m) | |
569 { | |
570 arma_extra_debug_sigprint(); | |
571 | |
572 arma_debug_assert_same_size(*this, m, "element-wise multiplication"); | |
573 | |
574 arrayops::inplace_mul( memptr(), m.memptr(), n_elem ); | |
575 | |
576 return *this; | |
577 } | |
578 | |
579 | |
580 | |
581 //! in-place element-wise cube division | |
582 template<typename eT> | |
583 inline | |
584 const Cube<eT>& | |
585 Cube<eT>::operator/=(const Cube<eT>& m) | |
586 { | |
587 arma_extra_debug_sigprint(); | |
588 | |
589 arma_debug_assert_same_size(*this, m, "element-wise division"); | |
590 | |
591 arrayops::inplace_div( memptr(), m.memptr(), n_elem ); | |
592 | |
593 return *this; | |
594 } | |
595 | |
596 | |
597 | |
598 //! for constructing a complex cube out of two non-complex cubes | |
599 template<typename eT> | |
600 template<typename T1, typename T2> | |
601 inline | |
602 Cube<eT>::Cube | |
603 ( | |
604 const BaseCube<typename Cube<eT>::pod_type,T1>& A, | |
605 const BaseCube<typename Cube<eT>::pod_type,T2>& B | |
606 ) | |
607 : n_rows(0) | |
608 , n_cols(0) | |
609 , n_elem_slice(0) | |
610 , n_slices(0) | |
611 , n_elem(0) | |
612 , mem_state(0) | |
613 , mat_ptrs() | |
614 , mem() | |
615 { | |
616 arma_extra_debug_sigprint_this(this); | |
617 | |
618 init(A,B); | |
619 } | |
620 | |
621 | |
622 | |
623 //! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation) | |
624 template<typename eT> | |
625 inline | |
626 Cube<eT>::Cube(const subview_cube<eT>& X) | |
627 : n_rows(X.n_rows) | |
628 , n_cols(X.n_cols) | |
629 , n_elem_slice(X.n_elem_slice) | |
630 , n_slices(X.n_slices) | |
631 , n_elem(X.n_elem) | |
632 , mem_state(0) | |
633 , mat_ptrs() | |
634 , mem() | |
635 { | |
636 arma_extra_debug_sigprint_this(this); | |
637 | |
638 init_cold(); | |
639 | |
640 subview_cube<eT>::extract(*this, X); | |
641 } | |
642 | |
643 | |
644 | |
645 //! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation) | |
646 template<typename eT> | |
647 inline | |
648 const Cube<eT>& | |
649 Cube<eT>::operator=(const subview_cube<eT>& X) | |
650 { | |
651 arma_extra_debug_sigprint(); | |
652 | |
653 const bool alias = (this == &(X.m)); | |
654 | |
655 if(alias == false) | |
656 { | |
657 init_warm(X.n_rows, X.n_cols, X.n_slices); | |
658 | |
659 subview_cube<eT>::extract(*this, X); | |
660 } | |
661 else | |
662 { | |
663 Cube<eT> tmp(X); | |
664 | |
665 steal_mem(tmp); | |
666 } | |
667 | |
668 return *this; | |
669 } | |
670 | |
671 | |
672 | |
673 //! in-place cube addition (using a subcube on the right-hand-side) | |
674 template<typename eT> | |
675 inline | |
676 const Cube<eT>& | |
677 Cube<eT>::operator+=(const subview_cube<eT>& X) | |
678 { | |
679 arma_extra_debug_sigprint(); | |
680 | |
681 subview_cube<eT>::plus_inplace(*this, X); | |
682 | |
683 return *this; | |
684 } | |
685 | |
686 | |
687 | |
688 //! in-place cube subtraction (using a subcube on the right-hand-side) | |
689 template<typename eT> | |
690 inline | |
691 const Cube<eT>& | |
692 Cube<eT>::operator-=(const subview_cube<eT>& X) | |
693 { | |
694 arma_extra_debug_sigprint(); | |
695 | |
696 subview_cube<eT>::minus_inplace(*this, X); | |
697 | |
698 return *this; | |
699 } | |
700 | |
701 | |
702 | |
703 //! in-place element-wise cube mutiplication (using a subcube on the right-hand-side) | |
704 template<typename eT> | |
705 inline | |
706 const Cube<eT>& | |
707 Cube<eT>::operator%=(const subview_cube<eT>& X) | |
708 { | |
709 arma_extra_debug_sigprint(); | |
710 | |
711 subview_cube<eT>::schur_inplace(*this, X); | |
712 | |
713 return *this; | |
714 } | |
715 | |
716 | |
717 | |
718 //! in-place element-wise cube division (using a subcube on the right-hand-side) | |
719 template<typename eT> | |
720 inline | |
721 const Cube<eT>& | |
722 Cube<eT>::operator/=(const subview_cube<eT>& X) | |
723 { | |
724 arma_extra_debug_sigprint(); | |
725 | |
726 subview_cube<eT>::div_inplace(*this, X); | |
727 | |
728 return *this; | |
729 } | |
730 | |
731 | |
732 | |
733 //! provide the reference to the matrix representing a single slice | |
734 template<typename eT> | |
735 arma_inline | |
736 Mat<eT>& | |
737 Cube<eT>::slice(const uword in_slice) | |
738 { | |
739 arma_extra_debug_sigprint(); | |
740 | |
741 arma_debug_check | |
742 ( | |
743 (in_slice >= n_slices), | |
744 "Cube::slice(): index out of bounds" | |
745 ); | |
746 | |
747 return const_cast< Mat<eT>& >( *(mat_ptrs[in_slice]) ); | |
748 } | |
749 | |
750 | |
751 | |
752 //! provide the reference to the matrix representing a single slice | |
753 template<typename eT> | |
754 arma_inline | |
755 const Mat<eT>& | |
756 Cube<eT>::slice(const uword in_slice) const | |
757 { | |
758 arma_extra_debug_sigprint(); | |
759 | |
760 arma_debug_check | |
761 ( | |
762 (in_slice >= n_slices), | |
763 "Cube::slice(): index out of bounds" | |
764 ); | |
765 | |
766 return *(mat_ptrs[in_slice]); | |
767 } | |
768 | |
769 | |
770 | |
771 //! creation of subview_cube (subcube comprised of specified slices) | |
772 template<typename eT> | |
773 arma_inline | |
774 subview_cube<eT> | |
775 Cube<eT>::slices(const uword in_slice1, const uword in_slice2) | |
776 { | |
777 arma_extra_debug_sigprint(); | |
778 | |
779 arma_debug_check | |
780 ( | |
781 (in_slice1 > in_slice2) || (in_slice2 >= n_slices), | |
782 "Cube::slices(): indices out of bounds or incorrectly used" | |
783 ); | |
784 | |
785 const uword subcube_n_slices = in_slice2 - in_slice1 + 1; | |
786 | |
787 return subview_cube<eT>(*this, 0, 0, in_slice1, n_rows, n_cols, subcube_n_slices); | |
788 } | |
789 | |
790 | |
791 | |
792 //! creation of subview_cube (subcube comprised of specified slices) | |
793 template<typename eT> | |
794 arma_inline | |
795 const subview_cube<eT> | |
796 Cube<eT>::slices(const uword in_slice1, const uword in_slice2) const | |
797 { | |
798 arma_extra_debug_sigprint(); | |
799 | |
800 arma_debug_check | |
801 ( | |
802 (in_slice1 > in_slice2) || (in_slice2 >= n_slices), | |
803 "Cube::rows(): indices out of bounds or incorrectly used" | |
804 ); | |
805 | |
806 const uword subcube_n_slices = in_slice2 - in_slice1 + 1; | |
807 | |
808 return subview_cube<eT>(*this, 0, 0, in_slice1, n_rows, n_cols, subcube_n_slices); | |
809 } | |
810 | |
811 | |
812 | |
813 //! creation of subview_cube (generic subcube) | |
814 template<typename eT> | |
815 arma_inline | |
816 subview_cube<eT> | |
817 Cube<eT>::subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2) | |
818 { | |
819 arma_extra_debug_sigprint(); | |
820 | |
821 arma_debug_check | |
822 ( | |
823 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_slice1 > in_slice2) || | |
824 (in_row2 >= n_rows) || (in_col2 >= n_cols) || (in_slice2 >= n_slices), | |
825 "Cube::subcube(): indices out of bounds or incorrectly used" | |
826 ); | |
827 | |
828 const uword subcube_n_rows = in_row2 - in_row1 + 1; | |
829 const uword subcube_n_cols = in_col2 - in_col1 + 1; | |
830 const uword subcube_n_slices = in_slice2 - in_slice1 + 1; | |
831 | |
832 return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices); | |
833 } | |
834 | |
835 | |
836 | |
837 //! creation of subview_cube (generic subcube) | |
838 template<typename eT> | |
839 arma_inline | |
840 const subview_cube<eT> | |
841 Cube<eT>::subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2) const | |
842 { | |
843 arma_extra_debug_sigprint(); | |
844 | |
845 arma_debug_check | |
846 ( | |
847 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_slice1 > in_slice2) || | |
848 (in_row2 >= n_rows) || (in_col2 >= n_cols) || (in_slice2 >= n_slices), | |
849 "Cube::subcube(): indices out of bounds or incorrectly used" | |
850 ); | |
851 | |
852 const uword subcube_n_rows = in_row2 - in_row1 + 1; | |
853 const uword subcube_n_cols = in_col2 - in_col1 + 1; | |
854 const uword subcube_n_slices = in_slice2 - in_slice1 + 1; | |
855 | |
856 return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices); | |
857 } | |
858 | |
859 | |
860 | |
861 //! creation of subview_cube (generic subcube) | |
862 template<typename eT> | |
863 inline | |
864 subview_cube<eT> | |
865 Cube<eT>::subcube(const span& row_span, const span& col_span, const span& slice_span) | |
866 { | |
867 arma_extra_debug_sigprint(); | |
868 | |
869 const bool row_all = row_span.whole; | |
870 const bool col_all = col_span.whole; | |
871 const bool slice_all = slice_span.whole; | |
872 | |
873 const uword local_n_rows = n_rows; | |
874 const uword local_n_cols = n_cols; | |
875 const uword local_n_slices = n_slices; | |
876 | |
877 const uword in_row1 = row_all ? 0 : row_span.a; | |
878 const uword in_row2 = row_span.b; | |
879 const uword subcube_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; | |
880 | |
881 const uword in_col1 = col_all ? 0 : col_span.a; | |
882 const uword in_col2 = col_span.b; | |
883 const uword subcube_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; | |
884 | |
885 const uword in_slice1 = slice_all ? 0 : slice_span.a; | |
886 const uword in_slice2 = slice_span.b; | |
887 const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1; | |
888 | |
889 arma_debug_check | |
890 ( | |
891 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) | |
892 || | |
893 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ) | |
894 || | |
895 ( slice_all ? false : ((in_slice1 > in_slice2) || (in_slice2 >= local_n_slices)) ) | |
896 , | |
897 "Cube::subcube(): indices out of bounds or incorrectly used" | |
898 ); | |
899 | |
900 return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices); | |
901 } | |
902 | |
903 | |
904 | |
905 //! creation of subview_cube (generic subcube) | |
906 template<typename eT> | |
907 inline | |
908 const subview_cube<eT> | |
909 Cube<eT>::subcube(const span& row_span, const span& col_span, const span& slice_span) const | |
910 { | |
911 arma_extra_debug_sigprint(); | |
912 | |
913 const bool row_all = row_span.whole; | |
914 const bool col_all = col_span.whole; | |
915 const bool slice_all = slice_span.whole; | |
916 | |
917 const uword local_n_rows = n_rows; | |
918 const uword local_n_cols = n_cols; | |
919 const uword local_n_slices = n_slices; | |
920 | |
921 const uword in_row1 = row_all ? 0 : row_span.a; | |
922 const uword in_row2 = row_span.b; | |
923 const uword subcube_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; | |
924 | |
925 const uword in_col1 = col_all ? 0 : col_span.a; | |
926 const uword in_col2 = col_span.b; | |
927 const uword subcube_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; | |
928 | |
929 const uword in_slice1 = slice_all ? 0 : slice_span.a; | |
930 const uword in_slice2 = slice_span.b; | |
931 const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1; | |
932 | |
933 arma_debug_check | |
934 ( | |
935 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) | |
936 || | |
937 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ) | |
938 || | |
939 ( slice_all ? false : ((in_slice1 > in_slice2) || (in_slice2 >= local_n_slices)) ) | |
940 , | |
941 "Cube::subcube(): indices out of bounds or incorrectly used" | |
942 ); | |
943 | |
944 return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices); | |
945 } | |
946 | |
947 | |
948 | |
949 template<typename eT> | |
950 inline | |
951 subview_cube<eT> | |
952 Cube<eT>::operator()(const span& row_span, const span& col_span, const span& slice_span) | |
953 { | |
954 arma_extra_debug_sigprint(); | |
955 | |
956 return (*this).subcube(row_span, col_span, slice_span); | |
957 } | |
958 | |
959 | |
960 | |
961 template<typename eT> | |
962 inline | |
963 const subview_cube<eT> | |
964 Cube<eT>::operator()(const span& row_span, const span& col_span, const span& slice_span) const | |
965 { | |
966 arma_extra_debug_sigprint(); | |
967 | |
968 return (*this).subcube(row_span, col_span, slice_span); | |
969 } | |
970 | |
971 | |
972 | |
973 //! remove specified slice | |
974 template<typename eT> | |
975 inline | |
976 void | |
977 Cube<eT>::shed_slice(const uword slice_num) | |
978 { | |
979 arma_extra_debug_sigprint(); | |
980 | |
981 arma_debug_check( slice_num >= n_slices, "Cube::shed_slice(): index out of bounds"); | |
982 | |
983 shed_slices(slice_num, slice_num); | |
984 } | |
985 | |
986 | |
987 | |
988 //! remove specified slices | |
989 template<typename eT> | |
990 inline | |
991 void | |
992 Cube<eT>::shed_slices(const uword in_slice1, const uword in_slice2) | |
993 { | |
994 arma_extra_debug_sigprint(); | |
995 | |
996 arma_debug_check | |
997 ( | |
998 (in_slice1 > in_slice2) || (in_slice2 >= n_slices), | |
999 "Cube::shed_slices(): indices out of bounds or incorrectly used" | |
1000 ); | |
1001 | |
1002 const uword n_keep_front = in_slice1; | |
1003 const uword n_keep_back = n_slices - (in_slice2 + 1); | |
1004 | |
1005 Cube<eT> X(n_rows, n_cols, n_keep_front + n_keep_back); | |
1006 | |
1007 if(n_keep_front > 0) | |
1008 { | |
1009 X.slices( 0, (n_keep_front-1) ) = slices( 0, (in_slice1-1) ); | |
1010 } | |
1011 | |
1012 if(n_keep_back > 0) | |
1013 { | |
1014 X.slices( n_keep_front, (n_keep_front+n_keep_back-1) ) = slices( (in_slice2+1), (n_slices-1) ); | |
1015 } | |
1016 | |
1017 steal_mem(X); | |
1018 } | |
1019 | |
1020 | |
1021 | |
1022 //! insert N slices at the specified slice position, | |
1023 //! optionally setting the elements of the inserted slices to zero | |
1024 template<typename eT> | |
1025 inline | |
1026 void | |
1027 Cube<eT>::insert_slices(const uword slice_num, const uword N, const bool set_to_zero) | |
1028 { | |
1029 arma_extra_debug_sigprint(); | |
1030 | |
1031 const uword t_n_slices = n_slices; | |
1032 | |
1033 const uword A_n_slices = slice_num; | |
1034 const uword B_n_slices = t_n_slices - slice_num; | |
1035 | |
1036 // insertion at slice_num == n_slices is in effect an append operation | |
1037 arma_debug_check( (slice_num > t_n_slices), "Cube::insert_slices(): index out of bounds"); | |
1038 | |
1039 if(N > 0) | |
1040 { | |
1041 Cube<eT> out(n_rows, n_cols, t_n_slices + N); | |
1042 | |
1043 if(A_n_slices > 0) | |
1044 { | |
1045 out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1); | |
1046 } | |
1047 | |
1048 if(B_n_slices > 0) | |
1049 { | |
1050 out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices-1); | |
1051 } | |
1052 | |
1053 if(set_to_zero == true) | |
1054 { | |
1055 //out.slices(slice_num, slice_num + N - 1).zeros(); | |
1056 | |
1057 for(uword i=slice_num; i < (slice_num + N); ++i) | |
1058 { | |
1059 out.slice(i).zeros(); | |
1060 } | |
1061 } | |
1062 | |
1063 steal_mem(out); | |
1064 } | |
1065 } | |
1066 | |
1067 | |
1068 | |
1069 //! insert the given object at the specified slice position; | |
1070 //! the given object must have the same number of rows and columns as the cube | |
1071 template<typename eT> | |
1072 template<typename T1> | |
1073 inline | |
1074 void | |
1075 Cube<eT>::insert_slices(const uword slice_num, const BaseCube<eT,T1>& X) | |
1076 { | |
1077 arma_extra_debug_sigprint(); | |
1078 | |
1079 const unwrap_cube<T1> tmp(X.get_ref()); | |
1080 const Cube<eT>& C = tmp.M; | |
1081 | |
1082 const uword N = C.n_slices; | |
1083 | |
1084 const uword t_n_slices = n_slices; | |
1085 | |
1086 const uword A_n_slices = slice_num; | |
1087 const uword B_n_slices = t_n_slices - slice_num; | |
1088 | |
1089 // insertion at slice_num == n_slices is in effect an append operation | |
1090 arma_debug_check( (slice_num > t_n_slices), "Cube::insert_slices(): index out of bounds"); | |
1091 | |
1092 arma_debug_check | |
1093 ( | |
1094 ( (C.n_rows != n_rows) || (C.n_cols != n_cols) ), | |
1095 "Cube::insert_slices(): given object has incompatible dimensions" | |
1096 ); | |
1097 | |
1098 if(N > 0) | |
1099 { | |
1100 Cube<eT> out(n_rows, n_cols, t_n_slices + N); | |
1101 | |
1102 if(A_n_slices > 0) | |
1103 { | |
1104 out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1); | |
1105 } | |
1106 | |
1107 if(B_n_slices > 0) | |
1108 { | |
1109 out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices - 1); | |
1110 } | |
1111 | |
1112 out.slices(slice_num, slice_num + N - 1) = C; | |
1113 | |
1114 steal_mem(out); | |
1115 } | |
1116 } | |
1117 | |
1118 | |
1119 | |
1120 //! create a cube from OpCube, i.e. run the previously delayed unary operations | |
1121 template<typename eT> | |
1122 template<typename gen_type> | |
1123 inline | |
1124 Cube<eT>::Cube(const GenCube<eT, gen_type>& X) | |
1125 : n_rows(X.n_rows) | |
1126 , n_cols(X.n_cols) | |
1127 , n_elem_slice(X.n_rows*X.n_cols) | |
1128 , n_slices(X.n_slices) | |
1129 , n_elem(X.n_rows*X.n_cols*X.n_slices) | |
1130 , mem_state(0) | |
1131 , mat_ptrs() | |
1132 , mem() | |
1133 { | |
1134 arma_extra_debug_sigprint_this(this); | |
1135 | |
1136 init_cold(); | |
1137 | |
1138 X.apply(*this); | |
1139 } | |
1140 | |
1141 | |
1142 | |
1143 template<typename eT> | |
1144 template<typename gen_type> | |
1145 inline | |
1146 const Cube<eT>& | |
1147 Cube<eT>::operator=(const GenCube<eT, gen_type>& X) | |
1148 { | |
1149 arma_extra_debug_sigprint(); | |
1150 | |
1151 init_warm(X.n_rows, X.n_cols, X.n_slices); | |
1152 | |
1153 X.apply(*this); | |
1154 | |
1155 return *this; | |
1156 } | |
1157 | |
1158 | |
1159 | |
1160 template<typename eT> | |
1161 template<typename gen_type> | |
1162 inline | |
1163 const Cube<eT>& | |
1164 Cube<eT>::operator+=(const GenCube<eT, gen_type>& X) | |
1165 { | |
1166 arma_extra_debug_sigprint(); | |
1167 | |
1168 X.apply_inplace_plus(*this); | |
1169 | |
1170 return *this; | |
1171 } | |
1172 | |
1173 | |
1174 | |
1175 template<typename eT> | |
1176 template<typename gen_type> | |
1177 inline | |
1178 const Cube<eT>& | |
1179 Cube<eT>::operator-=(const GenCube<eT, gen_type>& X) | |
1180 { | |
1181 arma_extra_debug_sigprint(); | |
1182 | |
1183 X.apply_inplace_minus(*this); | |
1184 | |
1185 return *this; | |
1186 } | |
1187 | |
1188 | |
1189 | |
1190 template<typename eT> | |
1191 template<typename gen_type> | |
1192 inline | |
1193 const Cube<eT>& | |
1194 Cube<eT>::operator%=(const GenCube<eT, gen_type>& X) | |
1195 { | |
1196 arma_extra_debug_sigprint(); | |
1197 | |
1198 X.apply_inplace_schur(*this); | |
1199 | |
1200 return *this; | |
1201 } | |
1202 | |
1203 | |
1204 | |
1205 template<typename eT> | |
1206 template<typename gen_type> | |
1207 inline | |
1208 const Cube<eT>& | |
1209 Cube<eT>::operator/=(const GenCube<eT, gen_type>& X) | |
1210 { | |
1211 arma_extra_debug_sigprint(); | |
1212 | |
1213 X.apply_inplace_div(*this); | |
1214 | |
1215 return *this; | |
1216 } | |
1217 | |
1218 | |
1219 | |
1220 //! create a cube from OpCube, i.e. run the previously delayed unary operations | |
1221 template<typename eT> | |
1222 template<typename T1, typename op_type> | |
1223 inline | |
1224 Cube<eT>::Cube(const OpCube<T1, op_type>& X) | |
1225 : n_rows(0) | |
1226 , n_cols(0) | |
1227 , n_elem_slice(0) | |
1228 , n_slices(0) | |
1229 , n_elem(0) | |
1230 , mem_state(0) | |
1231 , mat_ptrs() | |
1232 , mem() | |
1233 { | |
1234 arma_extra_debug_sigprint_this(this); | |
1235 | |
1236 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1237 | |
1238 op_type::apply(*this, X); | |
1239 } | |
1240 | |
1241 | |
1242 | |
1243 //! create a cube from OpCube, i.e. run the previously delayed unary operations | |
1244 template<typename eT> | |
1245 template<typename T1, typename op_type> | |
1246 inline | |
1247 const Cube<eT>& | |
1248 Cube<eT>::operator=(const OpCube<T1, op_type>& X) | |
1249 { | |
1250 arma_extra_debug_sigprint(); | |
1251 | |
1252 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1253 | |
1254 op_type::apply(*this, X); | |
1255 | |
1256 return *this; | |
1257 } | |
1258 | |
1259 | |
1260 | |
1261 //! in-place cube addition, with the right-hand-side operand having delayed operations | |
1262 template<typename eT> | |
1263 template<typename T1, typename op_type> | |
1264 inline | |
1265 const Cube<eT>& | |
1266 Cube<eT>::operator+=(const OpCube<T1, op_type>& X) | |
1267 { | |
1268 arma_extra_debug_sigprint(); | |
1269 | |
1270 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1271 | |
1272 const Cube<eT> m(X); | |
1273 | |
1274 return (*this).operator+=(m); | |
1275 } | |
1276 | |
1277 | |
1278 | |
1279 //! in-place cube subtraction, with the right-hand-side operand having delayed operations | |
1280 template<typename eT> | |
1281 template<typename T1, typename op_type> | |
1282 inline | |
1283 const Cube<eT>& | |
1284 Cube<eT>::operator-=(const OpCube<T1, op_type>& X) | |
1285 { | |
1286 arma_extra_debug_sigprint(); | |
1287 | |
1288 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1289 | |
1290 const Cube<eT> m(X); | |
1291 | |
1292 return (*this).operator-=(m); | |
1293 } | |
1294 | |
1295 | |
1296 | |
1297 //! in-place cube element-wise multiplication, with the right-hand-side operand having delayed operations | |
1298 template<typename eT> | |
1299 template<typename T1, typename op_type> | |
1300 inline | |
1301 const Cube<eT>& | |
1302 Cube<eT>::operator%=(const OpCube<T1, op_type>& X) | |
1303 { | |
1304 arma_extra_debug_sigprint(); | |
1305 | |
1306 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1307 | |
1308 const Cube<eT> m(X); | |
1309 | |
1310 return (*this).operator%=(m); | |
1311 } | |
1312 | |
1313 | |
1314 | |
1315 //! in-place cube element-wise division, with the right-hand-side operand having delayed operations | |
1316 template<typename eT> | |
1317 template<typename T1, typename op_type> | |
1318 inline | |
1319 const Cube<eT>& | |
1320 Cube<eT>::operator/=(const OpCube<T1, op_type>& X) | |
1321 { | |
1322 arma_extra_debug_sigprint(); | |
1323 | |
1324 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1325 | |
1326 const Cube<eT> m(X); | |
1327 | |
1328 return (*this).operator/=(m); | |
1329 } | |
1330 | |
1331 | |
1332 | |
1333 //! create a cube from eOpCube, i.e. run the previously delayed unary operations | |
1334 template<typename eT> | |
1335 template<typename T1, typename eop_type> | |
1336 inline | |
1337 Cube<eT>::Cube(const eOpCube<T1, eop_type>& X) | |
1338 : n_rows(X.get_n_rows()) | |
1339 , n_cols(X.get_n_cols()) | |
1340 , n_elem_slice(X.get_n_elem_slice()) | |
1341 , n_slices(X.get_n_slices()) | |
1342 , n_elem(X.get_n_elem()) | |
1343 , mem_state(0) | |
1344 , mat_ptrs() | |
1345 , mem() | |
1346 { | |
1347 arma_extra_debug_sigprint_this(this); | |
1348 | |
1349 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1350 | |
1351 init_cold(); | |
1352 | |
1353 eop_type::apply(*this, X); | |
1354 } | |
1355 | |
1356 | |
1357 | |
1358 //! create a cube from eOpCube, i.e. run the previously delayed unary operations | |
1359 template<typename eT> | |
1360 template<typename T1, typename eop_type> | |
1361 inline | |
1362 const Cube<eT>& | |
1363 Cube<eT>::operator=(const eOpCube<T1, eop_type>& X) | |
1364 { | |
1365 arma_extra_debug_sigprint(); | |
1366 | |
1367 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1368 | |
1369 const bool bad_alias = ( X.P.has_subview && X.P.is_alias(*this) ); | |
1370 | |
1371 if(bad_alias == false) | |
1372 { | |
1373 init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices()); | |
1374 | |
1375 eop_type::apply(*this, X); | |
1376 } | |
1377 else | |
1378 { | |
1379 Cube<eT> tmp(X); | |
1380 | |
1381 steal_mem(tmp); | |
1382 } | |
1383 | |
1384 return *this; | |
1385 } | |
1386 | |
1387 | |
1388 | |
1389 //! in-place cube addition, with the right-hand-side operand having delayed operations | |
1390 template<typename eT> | |
1391 template<typename T1, typename eop_type> | |
1392 inline | |
1393 const Cube<eT>& | |
1394 Cube<eT>::operator+=(const eOpCube<T1, eop_type>& X) | |
1395 { | |
1396 arma_extra_debug_sigprint(); | |
1397 | |
1398 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1399 | |
1400 eop_type::apply_inplace_plus(*this, X); | |
1401 | |
1402 return *this; | |
1403 } | |
1404 | |
1405 | |
1406 | |
1407 //! in-place cube subtraction, with the right-hand-side operand having delayed operations | |
1408 template<typename eT> | |
1409 template<typename T1, typename eop_type> | |
1410 inline | |
1411 const Cube<eT>& | |
1412 Cube<eT>::operator-=(const eOpCube<T1, eop_type>& X) | |
1413 { | |
1414 arma_extra_debug_sigprint(); | |
1415 | |
1416 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1417 | |
1418 eop_type::apply_inplace_minus(*this, X); | |
1419 | |
1420 return *this; | |
1421 } | |
1422 | |
1423 | |
1424 | |
1425 //! in-place cube element-wise multiplication, with the right-hand-side operand having delayed operations | |
1426 template<typename eT> | |
1427 template<typename T1, typename eop_type> | |
1428 inline | |
1429 const Cube<eT>& | |
1430 Cube<eT>::operator%=(const eOpCube<T1, eop_type>& X) | |
1431 { | |
1432 arma_extra_debug_sigprint(); | |
1433 | |
1434 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1435 | |
1436 eop_type::apply_inplace_schur(*this, X); | |
1437 | |
1438 return *this; | |
1439 } | |
1440 | |
1441 | |
1442 | |
1443 //! in-place cube element-wise division, with the right-hand-side operand having delayed operations | |
1444 template<typename eT> | |
1445 template<typename T1, typename eop_type> | |
1446 inline | |
1447 const Cube<eT>& | |
1448 Cube<eT>::operator/=(const eOpCube<T1, eop_type>& X) | |
1449 { | |
1450 arma_extra_debug_sigprint(); | |
1451 | |
1452 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1453 | |
1454 eop_type::apply_inplace_div(*this, X); | |
1455 | |
1456 return *this; | |
1457 } | |
1458 | |
1459 | |
1460 | |
1461 //! EXPERIMENTAL | |
1462 template<typename eT> | |
1463 template<typename T1, typename op_type> | |
1464 inline | |
1465 Cube<eT>::Cube(const mtOpCube<eT, T1, op_type>& X) | |
1466 : n_rows(0) | |
1467 , n_cols(0) | |
1468 , n_elem_slice(0) | |
1469 , n_slices(0) | |
1470 , n_elem(0) | |
1471 , mem_state(0) | |
1472 , mat_ptrs() | |
1473 , mem() | |
1474 { | |
1475 arma_extra_debug_sigprint_this(this); | |
1476 | |
1477 op_type::apply(*this, X); | |
1478 } | |
1479 | |
1480 | |
1481 | |
1482 //! EXPERIMENTAL | |
1483 template<typename eT> | |
1484 template<typename T1, typename op_type> | |
1485 inline | |
1486 const Cube<eT>& | |
1487 Cube<eT>::operator=(const mtOpCube<eT, T1, op_type>& X) | |
1488 { | |
1489 arma_extra_debug_sigprint(); | |
1490 | |
1491 op_type::apply(*this, X); | |
1492 | |
1493 return *this; | |
1494 } | |
1495 | |
1496 | |
1497 | |
1498 //! EXPERIMENTAL | |
1499 template<typename eT> | |
1500 template<typename T1, typename op_type> | |
1501 inline | |
1502 const Cube<eT>& | |
1503 Cube<eT>::operator+=(const mtOpCube<eT, T1, op_type>& X) | |
1504 { | |
1505 arma_extra_debug_sigprint(); | |
1506 | |
1507 const Cube<eT> m(X); | |
1508 | |
1509 return (*this).operator+=(m); | |
1510 } | |
1511 | |
1512 | |
1513 | |
1514 //! EXPERIMENTAL | |
1515 template<typename eT> | |
1516 template<typename T1, typename op_type> | |
1517 inline | |
1518 const Cube<eT>& | |
1519 Cube<eT>::operator-=(const mtOpCube<eT, T1, op_type>& X) | |
1520 { | |
1521 arma_extra_debug_sigprint(); | |
1522 | |
1523 const Cube<eT> m(X); | |
1524 | |
1525 return (*this).operator-=(m); | |
1526 } | |
1527 | |
1528 | |
1529 | |
1530 //! EXPERIMENTAL | |
1531 template<typename eT> | |
1532 template<typename T1, typename op_type> | |
1533 inline | |
1534 const Cube<eT>& | |
1535 Cube<eT>::operator%=(const mtOpCube<eT, T1, op_type>& X) | |
1536 { | |
1537 arma_extra_debug_sigprint(); | |
1538 | |
1539 const Cube<eT> m(X); | |
1540 | |
1541 return (*this).operator%=(m); | |
1542 } | |
1543 | |
1544 | |
1545 | |
1546 //! EXPERIMENTAL | |
1547 template<typename eT> | |
1548 template<typename T1, typename op_type> | |
1549 inline | |
1550 const Cube<eT>& | |
1551 Cube<eT>::operator/=(const mtOpCube<eT, T1, op_type>& X) | |
1552 { | |
1553 arma_extra_debug_sigprint(); | |
1554 | |
1555 const Cube<eT> m(X); | |
1556 | |
1557 return (*this).operator/=(m); | |
1558 } | |
1559 | |
1560 | |
1561 | |
1562 //! create a cube from Glue, i.e. run the previously delayed binary operations | |
1563 template<typename eT> | |
1564 template<typename T1, typename T2, typename glue_type> | |
1565 inline | |
1566 Cube<eT>::Cube(const GlueCube<T1, T2, glue_type>& X) | |
1567 : n_rows(0) | |
1568 , n_cols(0) | |
1569 , n_elem_slice(0) | |
1570 , n_slices(0) | |
1571 , n_elem(0) | |
1572 , mem_state(0) | |
1573 , mat_ptrs() | |
1574 , mem() | |
1575 { | |
1576 arma_extra_debug_sigprint_this(this); | |
1577 this->operator=(X); | |
1578 } | |
1579 | |
1580 | |
1581 | |
1582 //! create a cube from Glue, i.e. run the previously delayed binary operations | |
1583 template<typename eT> | |
1584 template<typename T1, typename T2, typename glue_type> | |
1585 inline | |
1586 const Cube<eT>& | |
1587 Cube<eT>::operator=(const GlueCube<T1, T2, glue_type>& X) | |
1588 { | |
1589 arma_extra_debug_sigprint(); | |
1590 | |
1591 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1592 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1593 | |
1594 glue_type::apply(*this, X); | |
1595 | |
1596 return *this; | |
1597 } | |
1598 | |
1599 | |
1600 //! in-place cube addition, with the right-hand-side operands having delayed operations | |
1601 template<typename eT> | |
1602 template<typename T1, typename T2, typename glue_type> | |
1603 inline | |
1604 const Cube<eT>& | |
1605 Cube<eT>::operator+=(const GlueCube<T1, T2, glue_type>& X) | |
1606 { | |
1607 arma_extra_debug_sigprint(); | |
1608 | |
1609 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1610 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1611 | |
1612 const Cube<eT> m(X); | |
1613 | |
1614 return (*this).operator+=(m); | |
1615 } | |
1616 | |
1617 | |
1618 | |
1619 //! in-place cube subtraction, with the right-hand-side operands having delayed operations | |
1620 template<typename eT> | |
1621 template<typename T1, typename T2, typename glue_type> | |
1622 inline | |
1623 const Cube<eT>& | |
1624 Cube<eT>::operator-=(const GlueCube<T1, T2, glue_type>& X) | |
1625 { | |
1626 arma_extra_debug_sigprint(); | |
1627 | |
1628 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1629 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1630 | |
1631 const Cube<eT> m(X); | |
1632 | |
1633 return (*this).operator-=(m); | |
1634 } | |
1635 | |
1636 | |
1637 | |
1638 //! in-place cube element-wise multiplication, with the right-hand-side operands having delayed operations | |
1639 template<typename eT> | |
1640 template<typename T1, typename T2, typename glue_type> | |
1641 inline | |
1642 const Cube<eT>& | |
1643 Cube<eT>::operator%=(const GlueCube<T1, T2, glue_type>& X) | |
1644 { | |
1645 arma_extra_debug_sigprint(); | |
1646 | |
1647 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1648 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1649 | |
1650 const Cube<eT> m(X); | |
1651 | |
1652 return (*this).operator%=(m); | |
1653 } | |
1654 | |
1655 | |
1656 | |
1657 //! in-place cube element-wise division, with the right-hand-side operands having delayed operations | |
1658 template<typename eT> | |
1659 template<typename T1, typename T2, typename glue_type> | |
1660 inline | |
1661 const Cube<eT>& | |
1662 Cube<eT>::operator/=(const GlueCube<T1, T2, glue_type>& X) | |
1663 { | |
1664 arma_extra_debug_sigprint(); | |
1665 | |
1666 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1667 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1668 | |
1669 const Cube<eT> m(X); | |
1670 | |
1671 return (*this).operator/=(m); | |
1672 } | |
1673 | |
1674 | |
1675 | |
1676 //! create a cube from eGlue, i.e. run the previously delayed binary operations | |
1677 template<typename eT> | |
1678 template<typename T1, typename T2, typename eglue_type> | |
1679 inline | |
1680 Cube<eT>::Cube(const eGlueCube<T1, T2, eglue_type>& X) | |
1681 : n_rows(X.get_n_rows()) | |
1682 , n_cols(X.get_n_cols()) | |
1683 , n_elem_slice(X.get_n_elem_slice()) | |
1684 , n_slices(X.get_n_slices()) | |
1685 , n_elem(X.get_n_elem()) | |
1686 , mem_state(0) | |
1687 , mat_ptrs() | |
1688 , mem() | |
1689 { | |
1690 arma_extra_debug_sigprint_this(this); | |
1691 | |
1692 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1693 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1694 | |
1695 init_cold(); | |
1696 | |
1697 eglue_type::apply(*this, X); | |
1698 } | |
1699 | |
1700 | |
1701 | |
1702 //! create a cube from Glue, i.e. run the previously delayed binary operations | |
1703 template<typename eT> | |
1704 template<typename T1, typename T2, typename eglue_type> | |
1705 inline | |
1706 const Cube<eT>& | |
1707 Cube<eT>::operator=(const eGlueCube<T1, T2, eglue_type>& X) | |
1708 { | |
1709 arma_extra_debug_sigprint(); | |
1710 | |
1711 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1712 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1713 | |
1714 const bool bad_alias = ( (X.P1.has_subview && X.P1.is_alias(*this)) || (X.P2.has_subview && X.P2.is_alias(*this)) ); | |
1715 | |
1716 if(bad_alias == false) | |
1717 { | |
1718 init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices()); | |
1719 | |
1720 eglue_type::apply(*this, X); | |
1721 } | |
1722 else | |
1723 { | |
1724 Cube<eT> tmp(X); | |
1725 | |
1726 steal_mem(tmp); | |
1727 } | |
1728 | |
1729 return *this; | |
1730 } | |
1731 | |
1732 | |
1733 | |
1734 //! in-place cube addition, with the right-hand-side operands having delayed operations | |
1735 template<typename eT> | |
1736 template<typename T1, typename T2, typename eglue_type> | |
1737 inline | |
1738 const Cube<eT>& | |
1739 Cube<eT>::operator+=(const eGlueCube<T1, T2, eglue_type>& X) | |
1740 { | |
1741 arma_extra_debug_sigprint(); | |
1742 | |
1743 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1744 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1745 | |
1746 eglue_type::apply_inplace_plus(*this, X); | |
1747 | |
1748 return *this; | |
1749 } | |
1750 | |
1751 | |
1752 | |
1753 //! in-place cube subtraction, with the right-hand-side operands having delayed operations | |
1754 template<typename eT> | |
1755 template<typename T1, typename T2, typename eglue_type> | |
1756 inline | |
1757 const Cube<eT>& | |
1758 Cube<eT>::operator-=(const eGlueCube<T1, T2, eglue_type>& X) | |
1759 { | |
1760 arma_extra_debug_sigprint(); | |
1761 | |
1762 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1763 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1764 | |
1765 eglue_type::apply_inplace_minus(*this, X); | |
1766 | |
1767 return *this; | |
1768 } | |
1769 | |
1770 | |
1771 | |
1772 //! in-place cube element-wise multiplication, with the right-hand-side operands having delayed operations | |
1773 template<typename eT> | |
1774 template<typename T1, typename T2, typename eglue_type> | |
1775 inline | |
1776 const Cube<eT>& | |
1777 Cube<eT>::operator%=(const eGlueCube<T1, T2, eglue_type>& X) | |
1778 { | |
1779 arma_extra_debug_sigprint(); | |
1780 | |
1781 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1782 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1783 | |
1784 eglue_type::apply_inplace_schur(*this, X); | |
1785 | |
1786 return *this; | |
1787 } | |
1788 | |
1789 | |
1790 | |
1791 //! in-place cube element-wise division, with the right-hand-side operands having delayed operations | |
1792 template<typename eT> | |
1793 template<typename T1, typename T2, typename eglue_type> | |
1794 inline | |
1795 const Cube<eT>& | |
1796 Cube<eT>::operator/=(const eGlueCube<T1, T2, eglue_type>& X) | |
1797 { | |
1798 arma_extra_debug_sigprint(); | |
1799 | |
1800 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); | |
1801 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); | |
1802 | |
1803 eglue_type::apply_inplace_div(*this, X); | |
1804 | |
1805 return *this; | |
1806 } | |
1807 | |
1808 | |
1809 | |
1810 //! EXPERIMENTAL | |
1811 template<typename eT> | |
1812 template<typename T1, typename T2, typename glue_type> | |
1813 inline | |
1814 Cube<eT>::Cube(const mtGlueCube<eT, T1, T2, glue_type>& X) | |
1815 : n_rows(0) | |
1816 , n_cols(0) | |
1817 , n_elem_slice(0) | |
1818 , n_slices(0) | |
1819 , n_elem(0) | |
1820 , mem_state(0) | |
1821 , mat_ptrs() | |
1822 , mem() | |
1823 { | |
1824 arma_extra_debug_sigprint_this(this); | |
1825 | |
1826 glue_type::apply(*this, X); | |
1827 } | |
1828 | |
1829 | |
1830 | |
1831 //! EXPERIMENTAL | |
1832 template<typename eT> | |
1833 template<typename T1, typename T2, typename glue_type> | |
1834 inline | |
1835 const Cube<eT>& | |
1836 Cube<eT>::operator=(const mtGlueCube<eT, T1, T2, glue_type>& X) | |
1837 { | |
1838 arma_extra_debug_sigprint(); | |
1839 | |
1840 glue_type::apply(*this, X); | |
1841 | |
1842 return *this; | |
1843 } | |
1844 | |
1845 | |
1846 | |
1847 //! EXPERIMENTAL | |
1848 template<typename eT> | |
1849 template<typename T1, typename T2, typename glue_type> | |
1850 inline | |
1851 const Cube<eT>& | |
1852 Cube<eT>::operator+=(const mtGlueCube<eT, T1, T2, glue_type>& X) | |
1853 { | |
1854 arma_extra_debug_sigprint(); | |
1855 | |
1856 const Cube<eT> m(X); | |
1857 | |
1858 return (*this).operator+=(m); | |
1859 } | |
1860 | |
1861 | |
1862 | |
1863 //! EXPERIMENTAL | |
1864 template<typename eT> | |
1865 template<typename T1, typename T2, typename glue_type> | |
1866 inline | |
1867 const Cube<eT>& | |
1868 Cube<eT>::operator-=(const mtGlueCube<eT, T1, T2, glue_type>& X) | |
1869 { | |
1870 arma_extra_debug_sigprint(); | |
1871 | |
1872 const Cube<eT> m(X); | |
1873 | |
1874 return (*this).operator-=(m); | |
1875 } | |
1876 | |
1877 | |
1878 | |
1879 //! EXPERIMENTAL | |
1880 template<typename eT> | |
1881 template<typename T1, typename T2, typename glue_type> | |
1882 inline | |
1883 const Cube<eT>& | |
1884 Cube<eT>::operator%=(const mtGlueCube<eT, T1, T2, glue_type>& X) | |
1885 { | |
1886 arma_extra_debug_sigprint(); | |
1887 | |
1888 const Cube<eT> m(X); | |
1889 | |
1890 return (*this).operator%=(m); | |
1891 } | |
1892 | |
1893 | |
1894 | |
1895 //! EXPERIMENTAL | |
1896 template<typename eT> | |
1897 template<typename T1, typename T2, typename glue_type> | |
1898 inline | |
1899 const Cube<eT>& | |
1900 Cube<eT>::operator/=(const mtGlueCube<eT, T1, T2, glue_type>& X) | |
1901 { | |
1902 arma_extra_debug_sigprint(); | |
1903 | |
1904 const Cube<eT> m(X); | |
1905 | |
1906 return (*this).operator/=(m); | |
1907 } | |
1908 | |
1909 | |
1910 | |
1911 //! linear element accessor (treats the cube as a vector); no bounds check; assumes memory is aligned | |
1912 template<typename eT> | |
1913 arma_inline | |
1914 arma_warn_unused | |
1915 const eT& | |
1916 Cube<eT>::at_alt(const uword i) const | |
1917 { | |
1918 const eT* mem_aligned = mem; | |
1919 memory::mark_as_aligned(mem_aligned); | |
1920 | |
1921 return mem_aligned[i]; | |
1922 } | |
1923 | |
1924 | |
1925 | |
1926 //! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined | |
1927 template<typename eT> | |
1928 arma_inline | |
1929 arma_warn_unused | |
1930 eT& | |
1931 Cube<eT>::operator() (const uword i) | |
1932 { | |
1933 arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds"); | |
1934 return access::rw(mem[i]); | |
1935 } | |
1936 | |
1937 | |
1938 | |
1939 //! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined | |
1940 template<typename eT> | |
1941 arma_inline | |
1942 arma_warn_unused | |
1943 const eT& | |
1944 Cube<eT>::operator() (const uword i) const | |
1945 { | |
1946 arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds"); | |
1947 return mem[i]; | |
1948 } | |
1949 | |
1950 | |
1951 //! linear element accessor (treats the cube as a vector); no bounds check. | |
1952 template<typename eT> | |
1953 arma_inline | |
1954 arma_warn_unused | |
1955 eT& | |
1956 Cube<eT>::operator[] (const uword i) | |
1957 { | |
1958 return access::rw(mem[i]); | |
1959 } | |
1960 | |
1961 | |
1962 | |
1963 //! linear element accessor (treats the cube as a vector); no bounds check | |
1964 template<typename eT> | |
1965 arma_inline | |
1966 arma_warn_unused | |
1967 const eT& | |
1968 Cube<eT>::operator[] (const uword i) const | |
1969 { | |
1970 return mem[i]; | |
1971 } | |
1972 | |
1973 | |
1974 | |
1975 //! linear element accessor (treats the cube as a vector); no bounds check. | |
1976 template<typename eT> | |
1977 arma_inline | |
1978 arma_warn_unused | |
1979 eT& | |
1980 Cube<eT>::at(const uword i) | |
1981 { | |
1982 return access::rw(mem[i]); | |
1983 } | |
1984 | |
1985 | |
1986 | |
1987 //! linear element accessor (treats the cube as a vector); no bounds check | |
1988 template<typename eT> | |
1989 arma_inline | |
1990 arma_warn_unused | |
1991 const eT& | |
1992 Cube<eT>::at(const uword i) const | |
1993 { | |
1994 return mem[i]; | |
1995 } | |
1996 | |
1997 | |
1998 | |
1999 //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined | |
2000 template<typename eT> | |
2001 arma_inline | |
2002 arma_warn_unused | |
2003 eT& | |
2004 Cube<eT>::operator() (const uword in_row, const uword in_col, const uword in_slice) | |
2005 { | |
2006 arma_debug_check | |
2007 ( | |
2008 (in_row >= n_rows) || | |
2009 (in_col >= n_cols) || | |
2010 (in_slice >= n_slices) | |
2011 , | |
2012 "Cube::operator(): index out of bounds" | |
2013 ); | |
2014 | |
2015 return access::rw(mem[in_slice*n_elem_slice + in_col*n_rows + in_row]); | |
2016 } | |
2017 | |
2018 | |
2019 | |
2020 //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined | |
2021 template<typename eT> | |
2022 arma_inline | |
2023 arma_warn_unused | |
2024 const eT& | |
2025 Cube<eT>::operator() (const uword in_row, const uword in_col, const uword in_slice) const | |
2026 { | |
2027 arma_debug_check | |
2028 ( | |
2029 (in_row >= n_rows) || | |
2030 (in_col >= n_cols) || | |
2031 (in_slice >= n_slices) | |
2032 , | |
2033 "Cube::operator(): index out of bounds" | |
2034 ); | |
2035 | |
2036 return mem[in_slice*n_elem_slice + in_col*n_rows + in_row]; | |
2037 } | |
2038 | |
2039 | |
2040 | |
2041 //! element accessor; no bounds check | |
2042 template<typename eT> | |
2043 arma_inline | |
2044 arma_warn_unused | |
2045 eT& | |
2046 Cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice) | |
2047 { | |
2048 return access::rw( mem[in_slice*n_elem_slice + in_col*n_rows + in_row] ); | |
2049 } | |
2050 | |
2051 | |
2052 | |
2053 //! element accessor; no bounds check | |
2054 template<typename eT> | |
2055 arma_inline | |
2056 arma_warn_unused | |
2057 const eT& | |
2058 Cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice) const | |
2059 { | |
2060 return mem[in_slice*n_elem_slice + in_col*n_rows + in_row]; | |
2061 } | |
2062 | |
2063 | |
2064 | |
2065 //! prefix ++ | |
2066 template<typename eT> | |
2067 arma_inline | |
2068 const Cube<eT>& | |
2069 Cube<eT>::operator++() | |
2070 { | |
2071 Cube_aux::prefix_pp(*this); | |
2072 return *this; | |
2073 } | |
2074 | |
2075 | |
2076 | |
2077 //! postfix ++ (must not return the object by reference) | |
2078 template<typename eT> | |
2079 arma_inline | |
2080 void | |
2081 Cube<eT>::operator++(int) | |
2082 { | |
2083 Cube_aux::postfix_pp(*this); | |
2084 } | |
2085 | |
2086 | |
2087 | |
2088 //! prefix -- | |
2089 template<typename eT> | |
2090 arma_inline | |
2091 const Cube<eT>& | |
2092 Cube<eT>::operator--() | |
2093 { | |
2094 Cube_aux::prefix_mm(*this); | |
2095 return *this; | |
2096 } | |
2097 | |
2098 | |
2099 | |
2100 //! postfix -- (must not return the object by reference) | |
2101 template<typename eT> | |
2102 arma_inline | |
2103 void | |
2104 Cube<eT>::operator--(int) | |
2105 { | |
2106 Cube_aux::postfix_mm(*this); | |
2107 } | |
2108 | |
2109 | |
2110 | |
2111 //! returns true if all of the elements are finite | |
2112 template<typename eT> | |
2113 arma_inline | |
2114 arma_warn_unused | |
2115 bool | |
2116 Cube<eT>::is_finite() const | |
2117 { | |
2118 return arrayops::is_finite( memptr(), n_elem ); | |
2119 } | |
2120 | |
2121 | |
2122 | |
2123 //! returns true if the cube has no elements | |
2124 template<typename eT> | |
2125 arma_inline | |
2126 arma_warn_unused | |
2127 bool | |
2128 Cube<eT>::is_empty() const | |
2129 { | |
2130 return (n_elem == 0); | |
2131 } | |
2132 | |
2133 | |
2134 | |
2135 //! returns true if the given index is currently in range | |
2136 template<typename eT> | |
2137 arma_inline | |
2138 arma_warn_unused | |
2139 bool | |
2140 Cube<eT>::in_range(const uword i) const | |
2141 { | |
2142 return (i < n_elem); | |
2143 } | |
2144 | |
2145 | |
2146 | |
2147 //! returns true if the given start and end indices are currently in range | |
2148 template<typename eT> | |
2149 arma_inline | |
2150 arma_warn_unused | |
2151 bool | |
2152 Cube<eT>::in_range(const span& x) const | |
2153 { | |
2154 arma_extra_debug_sigprint(); | |
2155 | |
2156 if(x.whole == true) | |
2157 { | |
2158 return true; | |
2159 } | |
2160 else | |
2161 { | |
2162 const uword a = x.a; | |
2163 const uword b = x.b; | |
2164 | |
2165 return ( (a <= b) && (b < n_elem) ); | |
2166 } | |
2167 } | |
2168 | |
2169 | |
2170 | |
2171 //! returns true if the given location is currently in range | |
2172 template<typename eT> | |
2173 arma_inline | |
2174 arma_warn_unused | |
2175 bool | |
2176 Cube<eT>::in_range(const uword in_row, const uword in_col, const uword in_slice) const | |
2177 { | |
2178 return ( (in_row < n_rows) && (in_col < n_cols) && (in_slice < n_slices) ); | |
2179 } | |
2180 | |
2181 | |
2182 | |
2183 template<typename eT> | |
2184 inline | |
2185 arma_warn_unused | |
2186 bool | |
2187 Cube<eT>::in_range(const span& row_span, const span& col_span, const span& slice_span) const | |
2188 { | |
2189 arma_extra_debug_sigprint(); | |
2190 | |
2191 const uword in_row1 = row_span.a; | |
2192 const uword in_row2 = row_span.b; | |
2193 | |
2194 const uword in_col1 = col_span.a; | |
2195 const uword in_col2 = col_span.b; | |
2196 | |
2197 const uword in_slice1 = slice_span.a; | |
2198 const uword in_slice2 = slice_span.b; | |
2199 | |
2200 | |
2201 const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) ); | |
2202 const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) ); | |
2203 const bool slices_ok = slice_span.whole ? true : ( (in_slice1 <= in_slice2) && (in_slice2 < n_slices) ); | |
2204 | |
2205 | |
2206 return ( (rows_ok == true) && (cols_ok == true) && (slices_ok == true) ); | |
2207 } | |
2208 | |
2209 | |
2210 | |
2211 //! returns a pointer to array of eTs used by the cube | |
2212 template<typename eT> | |
2213 arma_inline | |
2214 arma_warn_unused | |
2215 eT* | |
2216 Cube<eT>::memptr() | |
2217 { | |
2218 return const_cast<eT*>(mem); | |
2219 } | |
2220 | |
2221 | |
2222 | |
2223 //! returns a pointer to array of eTs used by the cube | |
2224 template<typename eT> | |
2225 arma_inline | |
2226 arma_warn_unused | |
2227 const eT* | |
2228 Cube<eT>::memptr() const | |
2229 { | |
2230 return mem; | |
2231 } | |
2232 | |
2233 | |
2234 | |
2235 //! returns a pointer to array of eTs used by the specified slice in the cube | |
2236 template<typename eT> | |
2237 arma_inline | |
2238 arma_warn_unused | |
2239 eT* | |
2240 Cube<eT>::slice_memptr(const uword uslice) | |
2241 { | |
2242 return const_cast<eT*>( &mem[ uslice*n_elem_slice ] ); | |
2243 } | |
2244 | |
2245 | |
2246 | |
2247 //! returns a pointer to array of eTs used by the specified slice in the cube | |
2248 template<typename eT> | |
2249 arma_inline | |
2250 arma_warn_unused | |
2251 const eT* | |
2252 Cube<eT>::slice_memptr(const uword uslice) const | |
2253 { | |
2254 return &mem[ uslice*n_elem_slice ]; | |
2255 } | |
2256 | |
2257 | |
2258 | |
2259 //! returns a pointer to array of eTs used by the specified slice in the cube | |
2260 template<typename eT> | |
2261 arma_inline | |
2262 arma_warn_unused | |
2263 eT* | |
2264 Cube<eT>::slice_colptr(const uword uslice, const uword col) | |
2265 { | |
2266 return const_cast<eT*>( &mem[ uslice*n_elem_slice + col*n_rows] ); | |
2267 } | |
2268 | |
2269 | |
2270 | |
2271 //! returns a pointer to array of eTs used by the specified slice in the cube | |
2272 template<typename eT> | |
2273 arma_inline | |
2274 arma_warn_unused | |
2275 const eT* | |
2276 Cube<eT>::slice_colptr(const uword uslice, const uword col) const | |
2277 { | |
2278 return &mem[ uslice*n_elem_slice + col*n_rows ]; | |
2279 } | |
2280 | |
2281 | |
2282 | |
2283 //! print contents of the cube (to the cout stream), | |
2284 //! optionally preceding with a user specified line of text. | |
2285 //! the precision and cell width are modified. | |
2286 //! on return, the stream's state are restored to their original values. | |
2287 template<typename eT> | |
2288 inline | |
2289 void | |
2290 Cube<eT>::impl_print(const std::string& extra_text) const | |
2291 { | |
2292 arma_extra_debug_sigprint(); | |
2293 | |
2294 if(extra_text.length() != 0) | |
2295 { | |
2296 ARMA_DEFAULT_OSTREAM << extra_text << '\n'; | |
2297 } | |
2298 | |
2299 arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, true); | |
2300 } | |
2301 | |
2302 | |
2303 //! print contents of the cube to a user specified stream, | |
2304 //! optionally preceding with a user specified line of text. | |
2305 //! the precision and cell width are modified. | |
2306 //! on return, the stream's state are restored to their original values. | |
2307 template<typename eT> | |
2308 inline | |
2309 void | |
2310 Cube<eT>::impl_print(std::ostream& user_stream, const std::string& extra_text) const | |
2311 { | |
2312 arma_extra_debug_sigprint(); | |
2313 | |
2314 if(extra_text.length() != 0) | |
2315 { | |
2316 user_stream << extra_text << '\n'; | |
2317 } | |
2318 | |
2319 arma_ostream::print(user_stream, *this, true); | |
2320 } | |
2321 | |
2322 | |
2323 | |
2324 //! print contents of the cube (to the cout stream), | |
2325 //! optionally preceding with a user specified line of text. | |
2326 //! the stream's state are used as is and are not modified | |
2327 //! (i.e. the precision and cell width are not modified). | |
2328 template<typename eT> | |
2329 inline | |
2330 void | |
2331 Cube<eT>::impl_raw_print(const std::string& extra_text) const | |
2332 { | |
2333 arma_extra_debug_sigprint(); | |
2334 | |
2335 if(extra_text.length() != 0) | |
2336 { | |
2337 ARMA_DEFAULT_OSTREAM << extra_text << '\n'; | |
2338 } | |
2339 | |
2340 arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, false); | |
2341 } | |
2342 | |
2343 | |
2344 | |
2345 //! print contents of the cube to a user specified stream, | |
2346 //! optionally preceding with a user specified line of text. | |
2347 //! the stream's state are used as is and are not modified. | |
2348 //! (i.e. the precision and cell width are not modified). | |
2349 template<typename eT> | |
2350 inline | |
2351 void | |
2352 Cube<eT>::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const | |
2353 { | |
2354 arma_extra_debug_sigprint(); | |
2355 | |
2356 if(extra_text.length() != 0) | |
2357 { | |
2358 user_stream << extra_text << '\n'; | |
2359 } | |
2360 | |
2361 arma_ostream::print(user_stream, *this, false); | |
2362 } | |
2363 | |
2364 | |
2365 | |
2366 //! change the cube to have user specified dimensions (data is not preserved) | |
2367 template<typename eT> | |
2368 inline | |
2369 void | |
2370 Cube<eT>::set_size(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices) | |
2371 { | |
2372 arma_extra_debug_sigprint(); | |
2373 | |
2374 init_warm(in_n_rows, in_n_cols, in_n_slices); | |
2375 } | |
2376 | |
2377 | |
2378 | |
2379 //! change the cube to have user specified dimensions (data is preserved) | |
2380 template<typename eT> | |
2381 inline | |
2382 void | |
2383 Cube<eT>::reshape(const uword in_rows, const uword in_cols, const uword in_slices, const uword dim) | |
2384 { | |
2385 arma_extra_debug_sigprint(); | |
2386 | |
2387 *this = arma::reshape(*this, in_rows, in_cols, in_slices, dim); | |
2388 } | |
2389 | |
2390 | |
2391 | |
2392 //! change the cube to have user specified dimensions (data is preserved) | |
2393 template<typename eT> | |
2394 inline | |
2395 void | |
2396 Cube<eT>::resize(const uword in_rows, const uword in_cols, const uword in_slices) | |
2397 { | |
2398 arma_extra_debug_sigprint(); | |
2399 | |
2400 *this = arma::resize(*this, in_rows, in_cols, in_slices); | |
2401 } | |
2402 | |
2403 | |
2404 | |
2405 //! change the cube (without preserving data) to have the same dimensions as the given cube | |
2406 template<typename eT> | |
2407 template<typename eT2> | |
2408 inline | |
2409 void | |
2410 Cube<eT>::copy_size(const Cube<eT2>& m) | |
2411 { | |
2412 arma_extra_debug_sigprint(); | |
2413 | |
2414 init_warm(m.n_rows, m.n_cols, m.n_slices); | |
2415 } | |
2416 | |
2417 | |
2418 | |
2419 //! transform each element in the cube using a functor | |
2420 template<typename eT> | |
2421 template<typename functor> | |
2422 inline | |
2423 const Cube<eT>& | |
2424 Cube<eT>::transform(functor F) | |
2425 { | |
2426 arma_extra_debug_sigprint(); | |
2427 | |
2428 eT* out_mem = memptr(); | |
2429 | |
2430 const uword N = n_elem; | |
2431 | |
2432 uword ii, jj; | |
2433 | |
2434 for(ii=0, jj=1; jj < N; ii+=2, jj+=2) | |
2435 { | |
2436 eT tmp_ii = out_mem[ii]; | |
2437 eT tmp_jj = out_mem[jj]; | |
2438 | |
2439 tmp_ii = eT( F(tmp_ii) ); | |
2440 tmp_jj = eT( F(tmp_jj) ); | |
2441 | |
2442 out_mem[ii] = tmp_ii; | |
2443 out_mem[jj] = tmp_jj; | |
2444 } | |
2445 | |
2446 if(ii < N) | |
2447 { | |
2448 out_mem[ii] = eT( F(out_mem[ii]) ); | |
2449 } | |
2450 | |
2451 return *this; | |
2452 } | |
2453 | |
2454 | |
2455 | |
2456 //! imbue (fill) the cube with values provided by a functor | |
2457 template<typename eT> | |
2458 template<typename functor> | |
2459 inline | |
2460 const Cube<eT>& | |
2461 Cube<eT>::imbue(functor F) | |
2462 { | |
2463 arma_extra_debug_sigprint(); | |
2464 | |
2465 eT* out_mem = memptr(); | |
2466 | |
2467 const uword N = n_elem; | |
2468 | |
2469 uword ii, jj; | |
2470 | |
2471 for(ii=0, jj=1; jj < N; ii+=2, jj+=2) | |
2472 { | |
2473 const eT tmp_ii = eT( F() ); | |
2474 const eT tmp_jj = eT( F() ); | |
2475 | |
2476 out_mem[ii] = tmp_ii; | |
2477 out_mem[jj] = tmp_jj; | |
2478 } | |
2479 | |
2480 if(ii < N) | |
2481 { | |
2482 out_mem[ii] = eT( F() ); | |
2483 } | |
2484 | |
2485 return *this; | |
2486 } | |
2487 | |
2488 | |
2489 | |
2490 //! fill the cube with the specified value | |
2491 template<typename eT> | |
2492 inline | |
2493 const Cube<eT>& | |
2494 Cube<eT>::fill(const eT val) | |
2495 { | |
2496 arma_extra_debug_sigprint(); | |
2497 | |
2498 arrayops::inplace_set( memptr(), val, n_elem ); | |
2499 | |
2500 return *this; | |
2501 } | |
2502 | |
2503 | |
2504 | |
2505 template<typename eT> | |
2506 inline | |
2507 const Cube<eT>& | |
2508 Cube<eT>::zeros() | |
2509 { | |
2510 arma_extra_debug_sigprint(); | |
2511 | |
2512 return (*this).fill(eT(0)); | |
2513 } | |
2514 | |
2515 | |
2516 | |
2517 template<typename eT> | |
2518 inline | |
2519 const Cube<eT>& | |
2520 Cube<eT>::zeros(const uword in_rows, const uword in_cols, const uword in_slices) | |
2521 { | |
2522 arma_extra_debug_sigprint(); | |
2523 | |
2524 set_size(in_rows, in_cols, in_slices); | |
2525 | |
2526 return (*this).fill(eT(0)); | |
2527 } | |
2528 | |
2529 | |
2530 | |
2531 template<typename eT> | |
2532 inline | |
2533 const Cube<eT>& | |
2534 Cube<eT>::ones() | |
2535 { | |
2536 arma_extra_debug_sigprint(); | |
2537 | |
2538 return (*this).fill(eT(1)); | |
2539 } | |
2540 | |
2541 | |
2542 | |
2543 template<typename eT> | |
2544 inline | |
2545 const Cube<eT>& | |
2546 Cube<eT>::ones(const uword in_rows, const uword in_cols, const uword in_slices) | |
2547 { | |
2548 arma_extra_debug_sigprint(); | |
2549 | |
2550 set_size(in_rows, in_cols, in_slices); | |
2551 | |
2552 return (*this).fill(eT(1)); | |
2553 } | |
2554 | |
2555 | |
2556 | |
2557 template<typename eT> | |
2558 inline | |
2559 const Cube<eT>& | |
2560 Cube<eT>::randu() | |
2561 { | |
2562 arma_extra_debug_sigprint(); | |
2563 | |
2564 eop_aux_randu<eT>::fill( memptr(), n_elem ); | |
2565 | |
2566 return *this; | |
2567 } | |
2568 | |
2569 | |
2570 | |
2571 template<typename eT> | |
2572 inline | |
2573 const Cube<eT>& | |
2574 Cube<eT>::randu(const uword in_rows, const uword in_cols, const uword in_slices) | |
2575 { | |
2576 arma_extra_debug_sigprint(); | |
2577 | |
2578 set_size(in_rows, in_cols, in_slices); | |
2579 | |
2580 return (*this).randu(); | |
2581 } | |
2582 | |
2583 | |
2584 | |
2585 template<typename eT> | |
2586 inline | |
2587 const Cube<eT>& | |
2588 Cube<eT>::randn() | |
2589 { | |
2590 arma_extra_debug_sigprint(); | |
2591 | |
2592 eop_aux_randn<eT>::fill( memptr(), n_elem ); | |
2593 | |
2594 return *this; | |
2595 } | |
2596 | |
2597 | |
2598 | |
2599 template<typename eT> | |
2600 inline | |
2601 const Cube<eT>& | |
2602 Cube<eT>::randn(const uword in_rows, const uword in_cols, const uword in_slices) | |
2603 { | |
2604 arma_extra_debug_sigprint(); | |
2605 | |
2606 set_size(in_rows, in_cols, in_slices); | |
2607 | |
2608 return (*this).randn(); | |
2609 } | |
2610 | |
2611 | |
2612 | |
2613 template<typename eT> | |
2614 inline | |
2615 void | |
2616 Cube<eT>::reset() | |
2617 { | |
2618 arma_extra_debug_sigprint(); | |
2619 | |
2620 init_warm(0,0,0); | |
2621 } | |
2622 | |
2623 | |
2624 | |
2625 template<typename eT> | |
2626 template<typename T1> | |
2627 inline | |
2628 void | |
2629 Cube<eT>::set_real(const BaseCube<typename Cube<eT>::pod_type,T1>& X) | |
2630 { | |
2631 arma_extra_debug_sigprint(); | |
2632 | |
2633 Cube_aux::set_real(*this, X); | |
2634 } | |
2635 | |
2636 | |
2637 | |
2638 template<typename eT> | |
2639 template<typename T1> | |
2640 inline | |
2641 void | |
2642 Cube<eT>::set_imag(const BaseCube<typename Cube<eT>::pod_type,T1>& X) | |
2643 { | |
2644 arma_extra_debug_sigprint(); | |
2645 | |
2646 Cube_aux::set_imag(*this, X); | |
2647 } | |
2648 | |
2649 | |
2650 | |
2651 template<typename eT> | |
2652 inline | |
2653 arma_warn_unused | |
2654 eT | |
2655 Cube<eT>::min() const | |
2656 { | |
2657 arma_extra_debug_sigprint(); | |
2658 | |
2659 arma_debug_check( (n_elem == 0), "min(): object has no elements" ); | |
2660 | |
2661 return op_min::direct_min(memptr(), n_elem); | |
2662 } | |
2663 | |
2664 | |
2665 | |
2666 template<typename eT> | |
2667 inline | |
2668 arma_warn_unused | |
2669 eT | |
2670 Cube<eT>::max() const | |
2671 { | |
2672 arma_extra_debug_sigprint(); | |
2673 | |
2674 arma_debug_check( (n_elem == 0), "max(): object has no elements" ); | |
2675 | |
2676 return op_max::direct_max(memptr(), n_elem); | |
2677 } | |
2678 | |
2679 | |
2680 | |
2681 template<typename eT> | |
2682 inline | |
2683 eT | |
2684 Cube<eT>::min(uword& index_of_min_val) const | |
2685 { | |
2686 arma_extra_debug_sigprint(); | |
2687 | |
2688 arma_debug_check( (n_elem == 0), "min(): object has no elements" ); | |
2689 | |
2690 return op_min::direct_min(memptr(), n_elem, index_of_min_val); | |
2691 } | |
2692 | |
2693 | |
2694 | |
2695 template<typename eT> | |
2696 inline | |
2697 eT | |
2698 Cube<eT>::max(uword& index_of_max_val) const | |
2699 { | |
2700 arma_extra_debug_sigprint(); | |
2701 | |
2702 arma_debug_check( (n_elem == 0), "max(): object has no elements" ); | |
2703 | |
2704 return op_max::direct_max(memptr(), n_elem, index_of_max_val); | |
2705 } | |
2706 | |
2707 | |
2708 | |
2709 template<typename eT> | |
2710 inline | |
2711 eT | |
2712 Cube<eT>::min(uword& row_of_min_val, uword& col_of_min_val, uword& slice_of_min_val) const | |
2713 { | |
2714 arma_extra_debug_sigprint(); | |
2715 | |
2716 arma_debug_check( (n_elem == 0), "min(): object has no elements" ); | |
2717 | |
2718 uword i; | |
2719 | |
2720 eT val = op_min::direct_min(memptr(), n_elem, i); | |
2721 | |
2722 const uword in_slice = i / n_elem_slice; | |
2723 const uword offset = in_slice * n_elem_slice; | |
2724 const uword j = i - offset; | |
2725 | |
2726 row_of_min_val = j % n_rows; | |
2727 col_of_min_val = j / n_rows; | |
2728 slice_of_min_val = in_slice; | |
2729 | |
2730 return val; | |
2731 } | |
2732 | |
2733 | |
2734 | |
2735 template<typename eT> | |
2736 inline | |
2737 eT | |
2738 Cube<eT>::max(uword& row_of_max_val, uword& col_of_max_val, uword& slice_of_max_val) const | |
2739 { | |
2740 arma_extra_debug_sigprint(); | |
2741 | |
2742 arma_debug_check( (n_elem == 0), "max(): object has no elements" ); | |
2743 | |
2744 uword i; | |
2745 | |
2746 eT val = op_max::direct_max(memptr(), n_elem, i); | |
2747 | |
2748 const uword in_slice = i / n_elem_slice; | |
2749 const uword offset = in_slice * n_elem_slice; | |
2750 const uword j = i - offset; | |
2751 | |
2752 row_of_max_val = j % n_rows; | |
2753 col_of_max_val = j / n_rows; | |
2754 slice_of_max_val = in_slice; | |
2755 | |
2756 return val; | |
2757 } | |
2758 | |
2759 | |
2760 | |
2761 //! save the cube to a file | |
2762 template<typename eT> | |
2763 inline | |
2764 bool | |
2765 Cube<eT>::save(const std::string name, const file_type type, const bool print_status) const | |
2766 { | |
2767 arma_extra_debug_sigprint(); | |
2768 | |
2769 bool save_okay; | |
2770 | |
2771 switch(type) | |
2772 { | |
2773 case raw_ascii: | |
2774 save_okay = diskio::save_raw_ascii(*this, name); | |
2775 break; | |
2776 | |
2777 case arma_ascii: | |
2778 save_okay = diskio::save_arma_ascii(*this, name); | |
2779 break; | |
2780 | |
2781 case raw_binary: | |
2782 save_okay = diskio::save_raw_binary(*this, name); | |
2783 break; | |
2784 | |
2785 case arma_binary: | |
2786 save_okay = diskio::save_arma_binary(*this, name); | |
2787 break; | |
2788 | |
2789 case ppm_binary: | |
2790 save_okay = diskio::save_ppm_binary(*this, name); | |
2791 break; | |
2792 | |
2793 case hdf5_binary: | |
2794 save_okay = diskio::save_hdf5_binary(*this, name); | |
2795 break; | |
2796 | |
2797 default: | |
2798 arma_warn(print_status, "Cube::save(): unsupported file type"); | |
2799 save_okay = false; | |
2800 } | |
2801 | |
2802 arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to ", name); | |
2803 | |
2804 return save_okay; | |
2805 } | |
2806 | |
2807 | |
2808 | |
2809 //! save the cube to a stream | |
2810 template<typename eT> | |
2811 inline | |
2812 bool | |
2813 Cube<eT>::save(std::ostream& os, const file_type type, const bool print_status) const | |
2814 { | |
2815 arma_extra_debug_sigprint(); | |
2816 | |
2817 bool save_okay; | |
2818 | |
2819 switch(type) | |
2820 { | |
2821 case raw_ascii: | |
2822 save_okay = diskio::save_raw_ascii(*this, os); | |
2823 break; | |
2824 | |
2825 case arma_ascii: | |
2826 save_okay = diskio::save_arma_ascii(*this, os); | |
2827 break; | |
2828 | |
2829 case raw_binary: | |
2830 save_okay = diskio::save_raw_binary(*this, os); | |
2831 break; | |
2832 | |
2833 case arma_binary: | |
2834 save_okay = diskio::save_arma_binary(*this, os); | |
2835 break; | |
2836 | |
2837 case ppm_binary: | |
2838 save_okay = diskio::save_ppm_binary(*this, os); | |
2839 break; | |
2840 | |
2841 default: | |
2842 arma_warn(print_status, "Cube::save(): unsupported file type"); | |
2843 save_okay = false; | |
2844 } | |
2845 | |
2846 arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to given stream"); | |
2847 | |
2848 return save_okay; | |
2849 } | |
2850 | |
2851 | |
2852 | |
2853 //! load a cube from a file | |
2854 template<typename eT> | |
2855 inline | |
2856 bool | |
2857 Cube<eT>::load(const std::string name, const file_type type, const bool print_status) | |
2858 { | |
2859 arma_extra_debug_sigprint(); | |
2860 | |
2861 bool load_okay; | |
2862 std::string err_msg; | |
2863 | |
2864 switch(type) | |
2865 { | |
2866 case auto_detect: | |
2867 load_okay = diskio::load_auto_detect(*this, name, err_msg); | |
2868 break; | |
2869 | |
2870 case raw_ascii: | |
2871 load_okay = diskio::load_raw_ascii(*this, name, err_msg); | |
2872 break; | |
2873 | |
2874 case arma_ascii: | |
2875 load_okay = diskio::load_arma_ascii(*this, name, err_msg); | |
2876 break; | |
2877 | |
2878 case raw_binary: | |
2879 load_okay = diskio::load_raw_binary(*this, name, err_msg); | |
2880 break; | |
2881 | |
2882 case arma_binary: | |
2883 load_okay = diskio::load_arma_binary(*this, name, err_msg); | |
2884 break; | |
2885 | |
2886 case ppm_binary: | |
2887 load_okay = diskio::load_ppm_binary(*this, name, err_msg); | |
2888 break; | |
2889 | |
2890 case hdf5_binary: | |
2891 load_okay = diskio::load_hdf5_binary(*this, name, err_msg); | |
2892 break; | |
2893 | |
2894 default: | |
2895 arma_warn(print_status, "Cube::load(): unsupported file type"); | |
2896 load_okay = false; | |
2897 } | |
2898 | |
2899 if( (print_status == true) && (load_okay == false) ) | |
2900 { | |
2901 if(err_msg.length() > 0) | |
2902 { | |
2903 arma_warn(true, "Cube::load(): ", err_msg, name); | |
2904 } | |
2905 else | |
2906 { | |
2907 arma_warn(true, "Cube::load(): couldn't read ", name); | |
2908 } | |
2909 } | |
2910 | |
2911 if(load_okay == false) | |
2912 { | |
2913 (*this).reset(); | |
2914 } | |
2915 | |
2916 return load_okay; | |
2917 } | |
2918 | |
2919 | |
2920 | |
2921 //! load a cube from a stream | |
2922 template<typename eT> | |
2923 inline | |
2924 bool | |
2925 Cube<eT>::load(std::istream& is, const file_type type, const bool print_status) | |
2926 { | |
2927 arma_extra_debug_sigprint(); | |
2928 | |
2929 bool load_okay; | |
2930 std::string err_msg; | |
2931 | |
2932 switch(type) | |
2933 { | |
2934 case auto_detect: | |
2935 load_okay = diskio::load_auto_detect(*this, is, err_msg); | |
2936 break; | |
2937 | |
2938 case raw_ascii: | |
2939 load_okay = diskio::load_raw_ascii(*this, is, err_msg); | |
2940 break; | |
2941 | |
2942 case arma_ascii: | |
2943 load_okay = diskio::load_arma_ascii(*this, is, err_msg); | |
2944 break; | |
2945 | |
2946 case raw_binary: | |
2947 load_okay = diskio::load_raw_binary(*this, is, err_msg); | |
2948 break; | |
2949 | |
2950 case arma_binary: | |
2951 load_okay = diskio::load_arma_binary(*this, is, err_msg); | |
2952 break; | |
2953 | |
2954 case ppm_binary: | |
2955 load_okay = diskio::load_ppm_binary(*this, is, err_msg); | |
2956 break; | |
2957 | |
2958 default: | |
2959 arma_warn(print_status, "Cube::load(): unsupported file type"); | |
2960 load_okay = false; | |
2961 } | |
2962 | |
2963 | |
2964 if( (print_status == true) && (load_okay == false) ) | |
2965 { | |
2966 if(err_msg.length() > 0) | |
2967 { | |
2968 arma_warn(true, "Cube::load(): ", err_msg, "the given stream"); | |
2969 } | |
2970 else | |
2971 { | |
2972 arma_warn(true, "Cube::load(): couldn't load from the given stream"); | |
2973 } | |
2974 } | |
2975 | |
2976 if(load_okay == false) | |
2977 { | |
2978 (*this).reset(); | |
2979 } | |
2980 | |
2981 return load_okay; | |
2982 } | |
2983 | |
2984 | |
2985 | |
2986 //! save the cube to a file, without printing any error messages | |
2987 template<typename eT> | |
2988 inline | |
2989 bool | |
2990 Cube<eT>::quiet_save(const std::string name, const file_type type) const | |
2991 { | |
2992 arma_extra_debug_sigprint(); | |
2993 | |
2994 return (*this).save(name, type, false); | |
2995 } | |
2996 | |
2997 | |
2998 | |
2999 //! save the cube to a stream, without printing any error messages | |
3000 template<typename eT> | |
3001 inline | |
3002 bool | |
3003 Cube<eT>::quiet_save(std::ostream& os, const file_type type) const | |
3004 { | |
3005 arma_extra_debug_sigprint(); | |
3006 | |
3007 return (*this).save(os, type, false); | |
3008 } | |
3009 | |
3010 | |
3011 | |
3012 //! load a cube from a file, without printing any error messages | |
3013 template<typename eT> | |
3014 inline | |
3015 bool | |
3016 Cube<eT>::quiet_load(const std::string name, const file_type type) | |
3017 { | |
3018 arma_extra_debug_sigprint(); | |
3019 | |
3020 return (*this).load(name, type, false); | |
3021 } | |
3022 | |
3023 | |
3024 | |
3025 //! load a cube from a stream, without printing any error messages | |
3026 template<typename eT> | |
3027 inline | |
3028 bool | |
3029 Cube<eT>::quiet_load(std::istream& is, const file_type type) | |
3030 { | |
3031 arma_extra_debug_sigprint(); | |
3032 | |
3033 return (*this).load(is, type, false); | |
3034 } | |
3035 | |
3036 | |
3037 | |
3038 template<typename eT> | |
3039 inline | |
3040 typename Cube<eT>::iterator | |
3041 Cube<eT>::begin() | |
3042 { | |
3043 arma_extra_debug_sigprint(); | |
3044 | |
3045 return memptr(); | |
3046 } | |
3047 | |
3048 | |
3049 | |
3050 template<typename eT> | |
3051 inline | |
3052 typename Cube<eT>::const_iterator | |
3053 Cube<eT>::begin() const | |
3054 { | |
3055 arma_extra_debug_sigprint(); | |
3056 | |
3057 return memptr(); | |
3058 } | |
3059 | |
3060 | |
3061 | |
3062 template<typename eT> | |
3063 inline | |
3064 typename Cube<eT>::const_iterator | |
3065 Cube<eT>::cbegin() const | |
3066 { | |
3067 arma_extra_debug_sigprint(); | |
3068 | |
3069 return memptr(); | |
3070 } | |
3071 | |
3072 | |
3073 | |
3074 template<typename eT> | |
3075 inline | |
3076 typename Cube<eT>::iterator | |
3077 Cube<eT>::end() | |
3078 { | |
3079 arma_extra_debug_sigprint(); | |
3080 | |
3081 return memptr() + n_elem; | |
3082 } | |
3083 | |
3084 | |
3085 | |
3086 template<typename eT> | |
3087 inline | |
3088 typename Cube<eT>::const_iterator | |
3089 Cube<eT>::end() const | |
3090 { | |
3091 arma_extra_debug_sigprint(); | |
3092 | |
3093 return memptr() + n_elem; | |
3094 } | |
3095 | |
3096 | |
3097 | |
3098 template<typename eT> | |
3099 inline | |
3100 typename Cube<eT>::const_iterator | |
3101 Cube<eT>::cend() const | |
3102 { | |
3103 arma_extra_debug_sigprint(); | |
3104 | |
3105 return memptr() + n_elem; | |
3106 } | |
3107 | |
3108 | |
3109 | |
3110 template<typename eT> | |
3111 inline | |
3112 typename Cube<eT>::slice_iterator | |
3113 Cube<eT>::begin_slice(const uword slice_num) | |
3114 { | |
3115 arma_extra_debug_sigprint(); | |
3116 | |
3117 arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds"); | |
3118 | |
3119 return slice_memptr(slice_num); | |
3120 } | |
3121 | |
3122 | |
3123 | |
3124 template<typename eT> | |
3125 inline | |
3126 typename Cube<eT>::const_slice_iterator | |
3127 Cube<eT>::begin_slice(const uword slice_num) const | |
3128 { | |
3129 arma_extra_debug_sigprint(); | |
3130 | |
3131 arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds"); | |
3132 | |
3133 return slice_memptr(slice_num); | |
3134 } | |
3135 | |
3136 | |
3137 | |
3138 template<typename eT> | |
3139 inline | |
3140 typename Cube<eT>::slice_iterator | |
3141 Cube<eT>::end_slice(const uword slice_num) | |
3142 { | |
3143 arma_extra_debug_sigprint(); | |
3144 | |
3145 arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds"); | |
3146 | |
3147 return slice_memptr(slice_num) + n_elem_slice; | |
3148 } | |
3149 | |
3150 | |
3151 | |
3152 template<typename eT> | |
3153 inline | |
3154 typename Cube<eT>::const_slice_iterator | |
3155 Cube<eT>::end_slice(const uword slice_num) const | |
3156 { | |
3157 arma_extra_debug_sigprint(); | |
3158 | |
3159 arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds"); | |
3160 | |
3161 return slice_memptr(slice_num) + n_elem_slice; | |
3162 } | |
3163 | |
3164 | |
3165 | |
3166 //! resets this cube to an empty matrix | |
3167 template<typename eT> | |
3168 inline | |
3169 void | |
3170 Cube<eT>::clear() | |
3171 { | |
3172 reset(); | |
3173 } | |
3174 | |
3175 | |
3176 | |
3177 //! returns true if the cube has no elements | |
3178 template<typename eT> | |
3179 inline | |
3180 bool | |
3181 Cube<eT>::empty() const | |
3182 { | |
3183 return (n_elem == 0); | |
3184 } | |
3185 | |
3186 | |
3187 | |
3188 //! returns the number of elements in this cube | |
3189 template<typename eT> | |
3190 inline | |
3191 uword | |
3192 Cube<eT>::size() const | |
3193 { | |
3194 return n_elem; | |
3195 } | |
3196 | |
3197 | |
3198 | |
3199 // template<typename eT> | |
3200 // inline | |
3201 // void | |
3202 // Cube<eT>::swap(Cube<eT>& B) | |
3203 // { | |
3204 // // TODO | |
3205 // } | |
3206 | |
3207 | |
3208 | |
3209 //! try to steal the memory from a given cube; | |
3210 //! if memory can't be stolen, copy the given cube | |
3211 template<typename eT> | |
3212 inline | |
3213 void | |
3214 Cube<eT>::steal_mem(Cube<eT>& x) | |
3215 { | |
3216 arma_extra_debug_sigprint(); | |
3217 | |
3218 if(this != &x) | |
3219 { | |
3220 if( (x.mem_state == 0) && (x.n_elem > Cube_prealloc::mem_n_elem) ) | |
3221 { | |
3222 reset(); | |
3223 | |
3224 const uword x_n_slices = x.n_slices; | |
3225 | |
3226 access::rw(n_rows) = x.n_rows; | |
3227 access::rw(n_cols) = x.n_cols; | |
3228 access::rw(n_elem_slice) = x.n_elem_slice; | |
3229 access::rw(n_slices) = x_n_slices; | |
3230 access::rw(n_elem) = x.n_elem; | |
3231 access::rw(mem) = x.mem; | |
3232 | |
3233 if(x_n_slices > Cube_prealloc::mat_ptrs_size) | |
3234 { | |
3235 access::rw( mat_ptrs) = x.mat_ptrs; | |
3236 access::rw(x.mat_ptrs) = 0; | |
3237 } | |
3238 else | |
3239 { | |
3240 access::rw(mat_ptrs) = const_cast< const Mat<eT>** >(mat_ptrs_local); | |
3241 | |
3242 for(uword i=0; i < x_n_slices; ++i) | |
3243 { | |
3244 mat_ptrs[i] = x.mat_ptrs[i]; | |
3245 x.mat_ptrs[i] = 0; | |
3246 } | |
3247 } | |
3248 | |
3249 access::rw(x.n_rows) = 0; | |
3250 access::rw(x.n_cols) = 0; | |
3251 access::rw(x.n_elem_slice) = 0; | |
3252 access::rw(x.n_slices) = 0; | |
3253 access::rw(x.n_elem) = 0; | |
3254 access::rw(x.mem) = 0; | |
3255 } | |
3256 else | |
3257 { | |
3258 (*this).operator=(x); | |
3259 } | |
3260 } | |
3261 } | |
3262 | |
3263 | |
3264 | |
3265 template<typename eT> | |
3266 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3267 arma_inline | |
3268 void | |
3269 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::mem_setup() | |
3270 { | |
3271 arma_extra_debug_sigprint_this(this); | |
3272 | |
3273 if(fixed_n_elem > 0) | |
3274 { | |
3275 access::rw(Cube<eT>::n_rows) = fixed_n_rows; | |
3276 access::rw(Cube<eT>::n_cols) = fixed_n_cols; | |
3277 access::rw(Cube<eT>::n_elem_slice) = fixed_n_rows * fixed_n_cols; | |
3278 access::rw(Cube<eT>::n_slices) = fixed_n_slices; | |
3279 access::rw(Cube<eT>::n_elem) = fixed_n_elem; | |
3280 access::rw(Cube<eT>::mem_state) = 3; | |
3281 access::rw(Cube<eT>::mat_ptrs) = const_cast< const Mat<eT>** >( \ | |
3282 (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_ptrs_local_extra : mat_ptrs_local ); | |
3283 access::rw(Cube<eT>::mem) = (fixed_n_elem > Cube_prealloc::mem_n_elem) ? mem_local_extra : mem_local; | |
3284 | |
3285 create_mat(); | |
3286 } | |
3287 else | |
3288 { | |
3289 access::rw(Cube<eT>::n_rows) = 0; | |
3290 access::rw(Cube<eT>::n_cols) = 0; | |
3291 access::rw(Cube<eT>::n_elem_slice) = 0; | |
3292 access::rw(Cube<eT>::n_slices) = 0; | |
3293 access::rw(Cube<eT>::n_elem) = 0; | |
3294 access::rw(Cube<eT>::mem_state) = 3; | |
3295 access::rw(Cube<eT>::mat_ptrs) = 0; | |
3296 access::rw(Cube<eT>::mem) = 0; | |
3297 } | |
3298 } | |
3299 | |
3300 | |
3301 | |
3302 template<typename eT> | |
3303 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3304 arma_inline | |
3305 arma_warn_unused | |
3306 eT& | |
3307 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator[] (const uword i) | |
3308 { | |
3309 return (use_extra) ? mem_local_extra[i] : mem_local[i]; | |
3310 } | |
3311 | |
3312 | |
3313 | |
3314 template<typename eT> | |
3315 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3316 arma_inline | |
3317 arma_warn_unused | |
3318 const eT& | |
3319 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator[] (const uword i) const | |
3320 { | |
3321 return (use_extra) ? mem_local_extra[i] : mem_local[i]; | |
3322 } | |
3323 | |
3324 | |
3325 | |
3326 template<typename eT> | |
3327 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3328 arma_inline | |
3329 arma_warn_unused | |
3330 eT& | |
3331 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::at(const uword i) | |
3332 { | |
3333 return (use_extra) ? mem_local_extra[i] : mem_local[i]; | |
3334 } | |
3335 | |
3336 | |
3337 | |
3338 template<typename eT> | |
3339 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3340 arma_inline | |
3341 arma_warn_unused | |
3342 const eT& | |
3343 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::at(const uword i) const | |
3344 { | |
3345 return (use_extra) ? mem_local_extra[i] : mem_local[i]; | |
3346 } | |
3347 | |
3348 | |
3349 | |
3350 template<typename eT> | |
3351 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3352 arma_inline | |
3353 arma_warn_unused | |
3354 eT& | |
3355 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator() (const uword i) | |
3356 { | |
3357 arma_debug_check( (i >= fixed_n_elem), "Cube::operator(): index out of bounds"); | |
3358 | |
3359 return (use_extra) ? mem_local_extra[i] : mem_local[i]; | |
3360 } | |
3361 | |
3362 | |
3363 | |
3364 template<typename eT> | |
3365 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3366 arma_inline | |
3367 arma_warn_unused | |
3368 const eT& | |
3369 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator() (const uword i) const | |
3370 { | |
3371 arma_debug_check( (i >= fixed_n_elem), "Cube::operator(): index out of bounds"); | |
3372 | |
3373 return (use_extra) ? mem_local_extra[i] : mem_local[i]; | |
3374 } | |
3375 | |
3376 | |
3377 | |
3378 template<typename eT> | |
3379 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3380 arma_inline | |
3381 arma_warn_unused | |
3382 eT& | |
3383 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::at(const uword in_row, const uword in_col, const uword in_slice) | |
3384 { | |
3385 const uword i = in_slice*fixed_n_elem_slice + in_col*fixed_n_rows + in_row; | |
3386 | |
3387 return (use_extra) ? mem_local_extra[i] : mem_local[i]; | |
3388 } | |
3389 | |
3390 | |
3391 | |
3392 template<typename eT> | |
3393 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3394 arma_inline | |
3395 arma_warn_unused | |
3396 const eT& | |
3397 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::at(const uword in_row, const uword in_col, const uword in_slice) const | |
3398 { | |
3399 const uword i = in_slice*fixed_n_elem_slice + in_col*fixed_n_rows + in_row; | |
3400 | |
3401 return (use_extra) ? mem_local_extra[i] : mem_local[i]; | |
3402 } | |
3403 | |
3404 | |
3405 | |
3406 template<typename eT> | |
3407 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3408 arma_inline | |
3409 arma_warn_unused | |
3410 eT& | |
3411 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator() (const uword in_row, const uword in_col, const uword in_slice) | |
3412 { | |
3413 arma_debug_check | |
3414 ( | |
3415 (in_row >= fixed_n_rows ) || | |
3416 (in_col >= fixed_n_cols ) || | |
3417 (in_slice >= fixed_n_slices) | |
3418 , | |
3419 "operator(): index out of bounds" | |
3420 ); | |
3421 | |
3422 const uword i = in_slice*fixed_n_elem_slice + in_col*fixed_n_rows + in_row; | |
3423 | |
3424 return (use_extra) ? mem_local_extra[i] : mem_local[i]; | |
3425 } | |
3426 | |
3427 | |
3428 | |
3429 template<typename eT> | |
3430 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> | |
3431 arma_inline | |
3432 arma_warn_unused | |
3433 const eT& | |
3434 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator() (const uword in_row, const uword in_col, const uword in_slice) const | |
3435 { | |
3436 arma_debug_check | |
3437 ( | |
3438 (in_row >= fixed_n_rows ) || | |
3439 (in_col >= fixed_n_cols ) || | |
3440 (in_slice >= fixed_n_slices) | |
3441 , | |
3442 "Cube::operator(): index out of bounds" | |
3443 ); | |
3444 | |
3445 const uword i = in_slice*fixed_n_elem_slice + in_col*fixed_n_rows + in_row; | |
3446 | |
3447 return (use_extra) ? mem_local_extra[i] : mem_local[i]; | |
3448 } | |
3449 | |
3450 | |
3451 | |
3452 //! prefix ++ | |
3453 template<typename eT> | |
3454 arma_inline | |
3455 void | |
3456 Cube_aux::prefix_pp(Cube<eT>& x) | |
3457 { | |
3458 eT* memptr = x.memptr(); | |
3459 const uword n_elem = x.n_elem; | |
3460 | |
3461 uword i,j; | |
3462 | |
3463 for(i=0, j=1; j<n_elem; i+=2, j+=2) | |
3464 { | |
3465 ++(memptr[i]); | |
3466 ++(memptr[j]); | |
3467 } | |
3468 | |
3469 if(i < n_elem) | |
3470 { | |
3471 ++(memptr[i]); | |
3472 } | |
3473 } | |
3474 | |
3475 | |
3476 | |
3477 //! prefix ++ for complex numbers (work around for limitations of the std::complex class) | |
3478 template<typename T> | |
3479 arma_inline | |
3480 void | |
3481 Cube_aux::prefix_pp(Cube< std::complex<T> >& x) | |
3482 { | |
3483 x += T(1); | |
3484 } | |
3485 | |
3486 | |
3487 | |
3488 //! postfix ++ | |
3489 template<typename eT> | |
3490 arma_inline | |
3491 void | |
3492 Cube_aux::postfix_pp(Cube<eT>& x) | |
3493 { | |
3494 eT* memptr = x.memptr(); | |
3495 const uword n_elem = x.n_elem; | |
3496 | |
3497 uword i,j; | |
3498 | |
3499 for(i=0, j=1; j<n_elem; i+=2, j+=2) | |
3500 { | |
3501 (memptr[i])++; | |
3502 (memptr[j])++; | |
3503 } | |
3504 | |
3505 if(i < n_elem) | |
3506 { | |
3507 (memptr[i])++; | |
3508 } | |
3509 } | |
3510 | |
3511 | |
3512 | |
3513 //! postfix ++ for complex numbers (work around for limitations of the std::complex class) | |
3514 template<typename T> | |
3515 arma_inline | |
3516 void | |
3517 Cube_aux::postfix_pp(Cube< std::complex<T> >& x) | |
3518 { | |
3519 x += T(1); | |
3520 } | |
3521 | |
3522 | |
3523 | |
3524 //! prefix -- | |
3525 template<typename eT> | |
3526 arma_inline | |
3527 void | |
3528 Cube_aux::prefix_mm(Cube<eT>& x) | |
3529 { | |
3530 eT* memptr = x.memptr(); | |
3531 const uword n_elem = x.n_elem; | |
3532 | |
3533 uword i,j; | |
3534 | |
3535 for(i=0, j=1; j<n_elem; i+=2, j+=2) | |
3536 { | |
3537 --(memptr[i]); | |
3538 --(memptr[j]); | |
3539 } | |
3540 | |
3541 if(i < n_elem) | |
3542 { | |
3543 --(memptr[i]); | |
3544 } | |
3545 } | |
3546 | |
3547 | |
3548 | |
3549 //! prefix -- for complex numbers (work around for limitations of the std::complex class) | |
3550 template<typename T> | |
3551 arma_inline | |
3552 void | |
3553 Cube_aux::prefix_mm(Cube< std::complex<T> >& x) | |
3554 { | |
3555 x -= T(1); | |
3556 } | |
3557 | |
3558 | |
3559 | |
3560 //! postfix -- | |
3561 template<typename eT> | |
3562 arma_inline | |
3563 void | |
3564 Cube_aux::postfix_mm(Cube<eT>& x) | |
3565 { | |
3566 eT* memptr = x.memptr(); | |
3567 const uword n_elem = x.n_elem; | |
3568 | |
3569 uword i,j; | |
3570 | |
3571 for(i=0, j=1; j<n_elem; i+=2, j+=2) | |
3572 { | |
3573 (memptr[i])--; | |
3574 (memptr[j])--; | |
3575 } | |
3576 | |
3577 if(i < n_elem) | |
3578 { | |
3579 (memptr[i])--; | |
3580 } | |
3581 } | |
3582 | |
3583 | |
3584 | |
3585 //! postfix ++ for complex numbers (work around for limitations of the std::complex class) | |
3586 template<typename T> | |
3587 arma_inline | |
3588 void | |
3589 Cube_aux::postfix_mm(Cube< std::complex<T> >& x) | |
3590 { | |
3591 x -= T(1); | |
3592 } | |
3593 | |
3594 | |
3595 | |
3596 template<typename eT, typename T1> | |
3597 inline | |
3598 void | |
3599 Cube_aux::set_real(Cube<eT>& out, const BaseCube<eT,T1>& X) | |
3600 { | |
3601 arma_extra_debug_sigprint(); | |
3602 | |
3603 const unwrap_cube<T1> tmp(X.get_ref()); | |
3604 const Cube<eT>& A = tmp.M; | |
3605 | |
3606 arma_debug_assert_same_size( out, A, "Cube::set_real()" ); | |
3607 | |
3608 out = A; | |
3609 } | |
3610 | |
3611 | |
3612 | |
3613 template<typename eT, typename T1> | |
3614 inline | |
3615 void | |
3616 Cube_aux::set_imag(Cube<eT>&, const BaseCube<eT,T1>&) | |
3617 { | |
3618 arma_extra_debug_sigprint(); | |
3619 } | |
3620 | |
3621 | |
3622 | |
3623 template<typename T, typename T1> | |
3624 inline | |
3625 void | |
3626 Cube_aux::set_real(Cube< std::complex<T> >& out, const BaseCube<T,T1>& X) | |
3627 { | |
3628 arma_extra_debug_sigprint(); | |
3629 | |
3630 typedef typename std::complex<T> eT; | |
3631 | |
3632 const ProxyCube<T1> P(X.get_ref()); | |
3633 | |
3634 const uword local_n_rows = P.get_n_rows(); | |
3635 const uword local_n_cols = P.get_n_cols(); | |
3636 const uword local_n_slices = P.get_n_slices(); | |
3637 | |
3638 arma_debug_assert_same_size | |
3639 ( | |
3640 out.n_rows, out.n_cols, out.n_slices, | |
3641 local_n_rows, local_n_cols, local_n_slices, | |
3642 "Cube::set_real()" | |
3643 ); | |
3644 | |
3645 eT* out_mem = out.memptr(); | |
3646 | |
3647 if(ProxyCube<T1>::prefer_at_accessor == false) | |
3648 { | |
3649 typedef typename ProxyCube<T1>::ea_type ea_type; | |
3650 | |
3651 ea_type A = P.get_ea(); | |
3652 | |
3653 const uword N = out.n_elem; | |
3654 | |
3655 for(uword i=0; i<N; ++i) | |
3656 { | |
3657 //out_mem[i].real() = PA[i]; | |
3658 out_mem[i] = std::complex<T>( A[i], out_mem[i].imag() ); | |
3659 } | |
3660 } | |
3661 else | |
3662 { | |
3663 for(uword slice = 0; slice < local_n_slices; ++slice) | |
3664 for(uword col = 0; col < local_n_cols; ++col ) | |
3665 for(uword row = 0; row < local_n_rows; ++row ) | |
3666 { | |
3667 (*out_mem) = std::complex<T>( P.at(row,col,slice), (*out_mem).imag() ); | |
3668 out_mem++; | |
3669 } | |
3670 } | |
3671 } | |
3672 | |
3673 | |
3674 | |
3675 template<typename T, typename T1> | |
3676 inline | |
3677 void | |
3678 Cube_aux::set_imag(Cube< std::complex<T> >& out, const BaseCube<T,T1>& X) | |
3679 { | |
3680 arma_extra_debug_sigprint(); | |
3681 | |
3682 typedef typename std::complex<T> eT; | |
3683 | |
3684 const ProxyCube<T1> P(X.get_ref()); | |
3685 | |
3686 const uword local_n_rows = P.get_n_rows(); | |
3687 const uword local_n_cols = P.get_n_cols(); | |
3688 const uword local_n_slices = P.get_n_slices(); | |
3689 | |
3690 arma_debug_assert_same_size | |
3691 ( | |
3692 out.n_rows, out.n_cols, out.n_slices, | |
3693 local_n_rows, local_n_cols, local_n_slices, | |
3694 "Cube::set_imag()" | |
3695 ); | |
3696 | |
3697 eT* out_mem = out.memptr(); | |
3698 | |
3699 if(ProxyCube<T1>::prefer_at_accessor == false) | |
3700 { | |
3701 typedef typename ProxyCube<T1>::ea_type ea_type; | |
3702 | |
3703 ea_type A = P.get_ea(); | |
3704 | |
3705 const uword N = out.n_elem; | |
3706 | |
3707 for(uword i=0; i<N; ++i) | |
3708 { | |
3709 //out_mem[i].imag() = PA[i]; | |
3710 out_mem[i] = std::complex<T>( out_mem[i].real(), A[i] ); | |
3711 } | |
3712 } | |
3713 else | |
3714 { | |
3715 for(uword slice = 0; slice < local_n_slices; ++slice) | |
3716 for(uword col = 0; col < local_n_cols; ++col ) | |
3717 for(uword row = 0; row < local_n_rows; ++row ) | |
3718 { | |
3719 (*out_mem) = std::complex<T>( (*out_mem).real(), P.at(row,col,slice) ); | |
3720 out_mem++; | |
3721 } | |
3722 } | |
3723 } | |
3724 | |
3725 | |
3726 | |
3727 #ifdef ARMA_EXTRA_CUBE_MEAT | |
3728 #include ARMA_INCFILE_WRAP(ARMA_EXTRA_CUBE_MEAT) | |
3729 #endif | |
3730 | |
3731 | |
3732 | |
3733 //! @} |