~ubuntu-branches/ubuntu/utopic/r-cran-rcpparmadillo/utopic

« back to all changes in this revision

Viewing changes to inst/include/armadillo_bits/Mat_meat.hpp

  • Committer: Package Import Robot
  • Author(s): Dirk Eddelbuettel
  • Date: 2013-12-09 18:13:21 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20131209181321-cc9ycvs53xfiz5ow
Tags: 0.3.930.1-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
160
160
  
161
161
  if(n_elem <= arma_config::mat_prealloc)
162
162
    {
 
163
    arma_extra_debug_print("Mat::init(): using local memory");
 
164
    
163
165
    access::rw(mem) = mem_local;
164
166
    }
165
167
  else
167
169
    arma_extra_debug_print("Mat::init(): allocating memory");
168
170
    
169
171
    access::rw(mem) = memory::acquire<eT>(n_elem);
170
 
    
171
 
    arma_check_bad_alloc( (mem == 0), "Mat::init(): out of memory" );
172
172
    }
173
173
  }
174
174
 
217
217
      }
218
218
    else
219
219
      {
220
 
      arma_debug_set_error
221
 
        (
222
 
        err_state,
223
 
        err_msg,
224
 
        ( ((t_vec_state == 1) && (in_n_cols != 1)) || ((t_vec_state == 2) && (in_n_rows != 1)) ),
225
 
        "Mat::init(): object is a row or column vector; requested size is not compatible"
226
 
        );
 
220
      if(t_vec_state == 1)
 
221
        {
 
222
        arma_debug_set_error
 
223
          (
 
224
          err_state,
 
225
          err_msg,
 
226
          (in_n_cols != 1),
 
227
          "Mat::init(): requested size is not compatible with column vector layout"
 
228
          );
 
229
        }
 
230
      else
 
231
      if(t_vec_state == 2)
 
232
        {
 
233
        arma_debug_set_error
 
234
          (
 
235
          err_state,
 
236
          err_msg,
 
237
          (in_n_rows != 1),
 
238
          "Mat::init(): requested size is not compatible with row vector layout"
 
239
          );
 
240
        }
227
241
      }
228
242
    }
229
243
  
274
288
    
275
289
    if(new_n_elem <= arma_config::mat_prealloc)
276
290
      {
 
291
      arma_extra_debug_print("Mat::init(): using local memory");
 
292
      
277
293
      access::rw(mem) = mem_local;
278
294
      }
279
295
    else
281
297
      arma_extra_debug_print("Mat::init(): allocating memory");
282
298
      
283
299
      access::rw(mem) = memory::acquire<eT>(new_n_elem);
284
 
      
285
 
      arma_check_bad_alloc( (mem == 0), "Mat::init(): out of memory" );
286
300
      }
287
301
    
288
302
    access::rw(n_rows)    = in_n_rows;
362
376
template<typename eT>
363
377
inline 
364
378
void
365
 
Mat<eT>::init(const std::string& text)
 
379
Mat<eT>::init(const std::string& text_orig)
366
380
  {
367
381
  arma_extra_debug_sigprint();
368
382
  
 
383
  const bool replace_commas = (is_cx<eT>::yes) ? false : ( text_orig.find(',') != std::string::npos );
 
384
  
 
385
  std::string* text_mod = (replace_commas) ? new std::string(text_orig) : NULL;
 
386
  
 
387
  const std::string& text = (replace_commas) ? ( std::replace((*text_mod).begin(), (*text_mod).end(), ',', ' '), (*text_mod) ) : text_orig;
 
388
  
369
389
  //
370
390
  // work out the size
371
391
  
379
399
  std::string::size_type line_start = 0;
380
400
  std::string::size_type   line_end = 0;
381
401
  
 
402
  std::stringstream line_stream;
 
403
  
382
404
  while( line_start < text.length() )
383
405
    {
384
 
    
385
406
    line_end = text.find(';', line_start);
386
407
    
387
408
    if(line_end == std::string::npos)
 
409
      {
388
410
      line_end = text.length()-1;
 
411
      }
389
412
    
390
413
    std::string::size_type line_len = line_end - line_start + 1;
391
 
    std::stringstream line_stream( text.substr(line_start,line_len) );
392
414
    
 
415
    line_stream.clear();
 
416
    line_stream.str( text.substr(line_start,line_len) );
393
417
    
394
418
    uword line_n_cols = 0;
395
419
    while(line_stream >> token)
397
421
      ++line_n_cols;
398
422
      }
399
423
    
400
 
    
401
424
    if(line_n_cols > 0)
402
425
      {
403
426
      if(t_n_cols_found == false)
404
427
        {
405
 
        t_n_cols = line_n_cols;
 
428
        t_n_cols       = line_n_cols;
406
429
        t_n_cols_found = true;
407
430
        }
408
431
      else
 
432
        {
409
433
        arma_check( (line_n_cols != t_n_cols), "Mat::init(): inconsistent number of columns in given string");
 
434
        }
410
435
      
411
436
      ++t_n_rows;
412
437
      }
 
438
      
413
439
    line_start = line_end+1;
414
 
    
415
440
    }
416
 
    
 
441
  
 
442
  
417
443
  Mat<eT>& x = *this;
418
444
  x.set_size(t_n_rows, t_n_cols);
419
445
  
420
446
  line_start = 0;
421
 
  line_end = 0;
 
447
  line_end   = 0;
422
448
  
423
449
  uword urow = 0;
424
450
  
425
451
  while( line_start < text.length() )
426
452
    {
427
 
    
428
453
    line_end = text.find(';', line_start);
429
454
    
430
455
    if(line_end == std::string::npos)
 
456
      {
431
457
      line_end = text.length()-1;
 
458
      }
432
459
    
433
460
    std::string::size_type line_len = line_end - line_start + 1;
434
 
    std::stringstream line_stream( text.substr(line_start,line_len) );
 
461
    
 
462
    line_stream.clear();
 
463
    line_stream.str( text.substr(line_start,line_len) );
435
464
    
436
465
//     uword ucol = 0;
437
466
//     while(line_stream >> token)
451
480
    ++urow;
452
481
    line_start = line_end+1;
453
482
    }
454
 
  
 
483
    
 
484
  if(replace_commas)
 
485
    {
 
486
    delete text_mod;
 
487
    }
455
488
  }
456
489
 
457
490
 
534
567
  
535
568
  template<typename eT>
536
569
  inline
537
 
  Mat<eT>::Mat(Mat<eT>&& in_mat)
538
 
    : n_rows(0)
539
 
    , n_cols(0)
540
 
    , n_elem(0)
541
 
    , vec_state(0)
542
 
    , mem_state(0)
543
 
    , mem()
 
570
  Mat<eT>::Mat(Mat<eT>&& X)
 
571
    : n_rows   (X.n_rows)
 
572
    , n_cols   (X.n_cols)
 
573
    , n_elem   (X.n_elem)
 
574
    , vec_state(0       )
 
575
    , mem_state(0       )
 
576
    , mem      (        )
544
577
    {
545
 
    arma_extra_debug_sigprint_this(this);
546
 
    arma_extra_debug_sigprint(arma_boost::format("this = %x   in_mat = %x") % this % &in_mat);
 
578
    arma_extra_debug_sigprint(arma_boost::format("this = %x   X = %x") % this % &X);
547
579
    
548
 
    (*this).steal_mem(in_mat);
 
580
    if( ((X.mem_state == 0) && (X.n_elem > arma_config::mat_prealloc)) || (X.mem_state == 1) || (X.mem_state == 2) )
 
581
      {
 
582
      access::rw(mem_state) = X.mem_state;
 
583
      access::rw(mem)       = X.mem;
 
584
      
 
585
      access::rw(X.n_rows)    = 0;
 
586
      access::rw(X.n_cols)    = 0;
 
587
      access::rw(X.n_elem)    = 0;
 
588
      access::rw(X.mem_state) = 0;
 
589
      access::rw(X.mem)       = 0;
 
590
      }
 
591
    else
 
592
      {
 
593
      init_cold();
 
594
      
 
595
      arrayops::copy( memptr(), X.mem, X.n_elem );
 
596
      }
549
597
    }
550
598
  
551
599
  
553
601
  template<typename eT>
554
602
  inline
555
603
  const Mat<eT>&
556
 
  Mat<eT>::operator=(Mat<eT>&& in_mat)
 
604
  Mat<eT>::operator=(Mat<eT>&& X)
557
605
    {
558
 
    arma_extra_debug_sigprint(arma_boost::format("this = %x   in_mat = %x") % this % &in_mat);
 
606
    arma_extra_debug_sigprint(arma_boost::format("this = %x   X = %x") % this % &X);
559
607
    
560
 
    (*this).steal_mem(in_mat);
 
608
    (*this).steal_mem(X);
561
609
    
562
610
    return *this;
563
611
    }
764
812
 
765
813
 
766
814
 
767
 
//! EXPERIMENTAL: swap the contents of this matrix, denoted as matrix A, with given matrix B
 
815
//! swap the contents of this matrix, denoted as matrix A, with given matrix B
768
816
template<typename eT>
769
817
inline
770
818
void
773
821
  Mat<eT>& A = (*this);
774
822
  
775
823
  arma_extra_debug_sigprint(arma_boost::format("A = %x   B = %x") % &A % &B);
 
824
 
 
825
  bool layout_ok = false;
776
826
  
777
 
  arma_debug_check( (A.vec_state != B.vec_state), "Mat::swap(): incompatible object types" );
 
827
  if(A.vec_state == B.vec_state)
 
828
    {
 
829
    layout_ok = true;
 
830
    }
 
831
  else
 
832
    {
 
833
    const uhword A_vec_state = A.vec_state;
 
834
    const uhword B_vec_state = B.vec_state;
 
835
    
 
836
    const bool A_absorbs_B = (A_vec_state == 0) || ( (A_vec_state == 1) && (B.n_cols == 1) ) || ( (A_vec_state == 2) && (B.n_rows == 1) );
 
837
    const bool B_absorbs_A = (B_vec_state == 0) || ( (B_vec_state == 1) && (A.n_cols == 1) ) || ( (B_vec_state == 2) && (A.n_rows == 1) );
 
838
    
 
839
    layout_ok = A_absorbs_B && B_absorbs_A;
 
840
    }
778
841
  
779
842
  const uhword A_mem_state = A.mem_state;
780
843
  const uhword B_mem_state = B.mem_state;
781
844
  
782
 
  if( (A_mem_state == 0) && (B_mem_state == 0) )
 
845
  if( (A_mem_state == 0) && (B_mem_state == 0) && layout_ok )
783
846
    {
784
847
    const uword A_n_elem = A.n_elem;
785
848
    const uword B_n_elem = B.n_elem;
832
895
    std::swap( access::rw(A.n_elem), access::rw(B.n_elem) );
833
896
    }
834
897
  else
835
 
  if( (A_mem_state == 3) && (B_mem_state == 3) )
836
 
    {
837
 
    arma_debug_check( ((A.n_rows != B.n_rows) || (A.n_cols != B.n_cols)), "Mat::swap(): incompatible object types" );
838
 
    
839
 
    const uword N = A.n_elem;
840
 
    
841
 
    eT* A_mem = A.memptr();
842
 
    eT* B_mem = B.memptr();
843
 
    
844
 
    for(uword ii=0; ii < N; ++ii)  { std::swap(A_mem[ii], B_mem[ii]); }
845
 
    }
846
 
  else
847
 
    {
848
 
    arma_bad("Mat::swap(): incompatible object types");
 
898
  if( (A_mem_state <= 2) && (B_mem_state <= 2) && (A.n_elem == B.n_elem) && layout_ok )
 
899
    {
 
900
    std::swap( access::rw(A.n_rows), access::rw(B.n_rows) );
 
901
    std::swap( access::rw(A.n_cols), access::rw(B.n_cols) );
 
902
    
 
903
    const uword N = A.n_elem;
 
904
    
 
905
    eT* A_mem = A.memptr();
 
906
    eT* B_mem = B.memptr();
 
907
    
 
908
    for(uword ii=0; ii < N; ++ii)  { std::swap(A_mem[ii], B_mem[ii]); }
 
909
    }
 
910
  else
 
911
  if( (A.n_rows == B.n_rows) && (A.n_cols == B.n_cols) )
 
912
    {
 
913
    const uword N = A.n_elem;
 
914
    
 
915
    eT* A_mem = A.memptr();
 
916
    eT* B_mem = B.memptr();
 
917
    
 
918
    for(uword ii=0; ii < N; ++ii)  { std::swap(A_mem[ii], B_mem[ii]); }
 
919
    }
 
920
  else
 
921
    {
 
922
    // generic swap to handle remaining cases
 
923
    
 
924
    if(A.n_elem <= B.n_elem)
 
925
      {
 
926
      Mat<eT> C = A;
 
927
      
 
928
      A.steal_mem(B);
 
929
      B.steal_mem(C);
 
930
      }
 
931
    else
 
932
      {
 
933
      Mat<eT> C = B;
 
934
      
 
935
      B.steal_mem(A);
 
936
      A.steal_mem(C);
 
937
      }
849
938
    }
850
939
  }
851
940
 
879
968
      }
880
969
    else
881
970
      {
882
 
      if( (t_vec_state == 1) && ( x_n_cols == 1) )
883
 
        {
884
 
        layout_ok = true;
885
 
        }
886
 
      
887
 
      if( (t_vec_state == 2) && ( x_n_rows == 1) )
888
 
        {
889
 
        layout_ok = true;
890
 
        }
 
971
      if( (t_vec_state == 1) && (x_n_cols == 1) )  { layout_ok = true; }
 
972
      if( (t_vec_state == 2) && (x_n_rows == 1) )  { layout_ok = true; }
891
973
      }
892
974
    
893
975
    
894
 
    if( (t_mem_state <= 1) && (x_mem_state <= 1) && (x_n_elem > arma_config::mat_prealloc) && (layout_ok == true) )
 
976
    if( (t_mem_state <= 1) && ( ((x_mem_state == 0) && (x_n_elem > arma_config::mat_prealloc)) || (x_mem_state == 1) ) && layout_ok )
895
977
      {
896
978
      reset();
897
 
      // note: calling reset() also prevents fixed size matrices from changing size or using non-local memory
898
979
      
899
 
      access::rw(n_rows) = x_n_rows;
900
 
      access::rw(n_cols) = x_n_cols;
901
 
      access::rw(n_elem) = x_n_elem;
902
 
      access::rw(mem)    = x.mem;
 
980
      access::rw(n_rows)    = x_n_rows;
 
981
      access::rw(n_cols)    = x_n_cols;
 
982
      access::rw(n_elem)    = x_n_elem;
 
983
      access::rw(mem_state) = x_mem_state;
 
984
      access::rw(mem)       = x.mem;
903
985
      
904
986
      access::rw(x.n_rows)    = 0;
905
987
      access::rw(x.n_cols)    = 0;
2181
2263
  access::rw(n_elem) = p.get_n_elem();
2182
2264
  
2183
2265
  init_cold();
2184
 
  fill(eT(0));
 
2266
  
 
2267
  zeros();
2185
2268
  
2186
2269
  typename SpProxy<T1>::const_iterator_type it     = p.begin();
2187
2270
  typename SpProxy<T1>::const_iterator_type it_end = p.end();
2207
2290
  
2208
2291
  init_warm(p.get_n_rows(), p.get_n_cols());
2209
2292
  
2210
 
  fill(eT(0));
 
2293
  zeros();
2211
2294
  
2212
2295
  typename SpProxy<T1>::const_iterator_type it     = p.begin();
2213
2296
  typename SpProxy<T1>::const_iterator_type it_end = p.end();
2833
2916
 
2834
2917
//! creation of subview (submatrix)
2835
2918
template<typename eT>
 
2919
arma_inline
 
2920
subview<eT>
 
2921
Mat<eT>::submat(const uword in_row1, const uword in_col1, const SizeMat& s)
 
2922
  {
 
2923
  arma_extra_debug_sigprint();
 
2924
  
 
2925
  const uword l_n_rows = n_rows;
 
2926
  const uword l_n_cols = n_cols;
 
2927
  
 
2928
  const uword s_n_rows = s.n_rows;
 
2929
  const uword s_n_cols = s.n_cols;
 
2930
  
 
2931
  arma_debug_check
 
2932
    (
 
2933
    ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)),
 
2934
    "Mat::submat(): indices or size out of bounds"
 
2935
    );
 
2936
  
 
2937
  return subview<eT>(*this, in_row1, in_col1, s_n_rows, s_n_cols);
 
2938
  }
 
2939
 
 
2940
 
 
2941
 
 
2942
//! creation of subview (submatrix)
 
2943
template<typename eT>
 
2944
arma_inline
 
2945
const subview<eT>
 
2946
Mat<eT>::submat(const uword in_row1, const uword in_col1, const SizeMat& s) const
 
2947
  {
 
2948
  arma_extra_debug_sigprint();
 
2949
  
 
2950
  const uword l_n_rows = n_rows;
 
2951
  const uword l_n_cols = n_cols;
 
2952
  
 
2953
  const uword s_n_rows = s.n_rows;
 
2954
  const uword s_n_cols = s.n_cols;
 
2955
  
 
2956
  arma_debug_check
 
2957
    (
 
2958
    ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)),
 
2959
    "Mat::submat(): indices or size out of bounds"
 
2960
    );
 
2961
  
 
2962
  return subview<eT>(*this, in_row1, in_col1, s_n_rows, s_n_cols);
 
2963
  }
 
2964
 
 
2965
 
 
2966
 
 
2967
//! creation of subview (submatrix)
 
2968
template<typename eT>
2836
2969
inline
2837
2970
subview<eT>
2838
2971
Mat<eT>::submat(const span& row_span, const span& col_span)
2928
3061
 
2929
3062
 
2930
3063
template<typename eT>
 
3064
inline
 
3065
subview<eT>
 
3066
Mat<eT>::operator()(const uword in_row1, const uword in_col1, const SizeMat& s)
 
3067
  {
 
3068
  arma_extra_debug_sigprint();
 
3069
  
 
3070
  return (*this).submat(in_row1, in_col1, s);
 
3071
  }
 
3072
 
 
3073
 
 
3074
 
 
3075
template<typename eT>
 
3076
inline
 
3077
const subview<eT>
 
3078
Mat<eT>::operator()(const uword in_row1, const uword in_col1, const SizeMat& s) const
 
3079
  {
 
3080
  arma_extra_debug_sigprint();
 
3081
  
 
3082
  return (*this).submat(in_row1, in_col1, s);
 
3083
  }
 
3084
 
 
3085
 
 
3086
 
 
3087
template<typename eT>
2931
3088
template<typename T1>
2932
3089
arma_inline
2933
3090
subview_elem1<eT,T1>
4932
5089
 
4933
5090
 
4934
5091
 
 
5092
template<typename eT>
 
5093
arma_inline
 
5094
arma_warn_unused
 
5095
bool
 
5096
Mat<eT>::in_range(const uword in_row, const uword in_col, const SizeMat& s) const
 
5097
  {
 
5098
  const uword l_n_rows = n_rows;
 
5099
  const uword l_n_cols = n_cols;
 
5100
  
 
5101
  if( (in_row >= l_n_rows) || (in_col >= l_n_cols) || ((in_row + s.n_rows) > l_n_rows) || ((in_col + s.n_cols) > l_n_cols) )
 
5102
    {
 
5103
    return false;
 
5104
    }
 
5105
  else
 
5106
    {
 
5107
    return true;
 
5108
    }
 
5109
  }
 
5110
 
 
5111
 
 
5112
 
4935
5113
//! returns a pointer to array of eTs for a specified column; no bounds check
4936
5114
template<typename eT>
4937
5115
arma_inline
5387
5565
  {
5388
5566
  arma_extra_debug_sigprint();
5389
5567
  
5390
 
  eop_aux_randu<eT>::fill( memptr(), n_elem );
 
5568
  arma_rng::randu<eT>::fill( memptr(), n_elem );
5391
5569
  
5392
5570
  return *this;
5393
5571
  }
5429
5607
  {
5430
5608
  arma_extra_debug_sigprint();
5431
5609
  
5432
 
  eop_aux_randn<eT>::fill( memptr(), n_elem );
 
5610
  arma_rng::randn<eT>::fill( memptr(), n_elem );
5433
5611
  
5434
5612
  return *this;
5435
5613
  }