annotate armadillo-3.900.4/include/armadillo_bits/Cube_meat.hpp @ 84:55a047986812 tip

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