comparison liboctave/Array.cc @ 11507:c3ad80f4ce36

Array.h, Array.cc: more constructor fixes
author John W. Eaton <jwe@octave.org>
date Thu, 13 Jan 2011 06:01:08 -0500
parents 0090bb47d0b5
children fd0a3ac60b0e
comparison
equal deleted inserted replaced
11506:964b7fd379f1 11507:c3ad80f4ce36
46 // One dimensional array class. Handles the reference counting for 46 // One dimensional array class. Handles the reference counting for
47 // all the derived classes. 47 // all the derived classes.
48 48
49 template <class T> 49 template <class T>
50 Array<T>::Array (const Array<T>& a, const dim_vector& dv) 50 Array<T>::Array (const Array<T>& a, const dim_vector& dv)
51 : rep (a.rep), dimensions (dv), 51 : dimensions (dv), rep (a.rep),
52 slice_data (a.slice_data), slice_len (a.slice_len) 52 slice_data (a.slice_data), slice_len (a.slice_len)
53 { 53 {
54 if (dimensions.safe_numel () != a.numel ()) 54 if (dimensions.safe_numel () != a.numel ())
55 { 55 {
56 std::string dimensions_str = a.dimensions.str (); 56 std::string dimensions_str = a.dimensions.str ();
67 dimensions.chop_trailing_singletons (); 67 dimensions.chop_trailing_singletons ();
68 } 68 }
69 69
70 template <class T> 70 template <class T>
71 Array<T>::Array (const Array<T>& a, octave_idx_type nr, octave_idx_type nc) 71 Array<T>::Array (const Array<T>& a, octave_idx_type nr, octave_idx_type nc)
72 : rep (a.rep), dimensions (nr, nc), 72 : dimensions (nr, nc), rep (a.rep),
73 slice_data (a.slice_data), slice_len (a.slice_len) 73 slice_data (a.slice_data), slice_len (a.slice_len)
74 { 74 {
75 if (dimensions.safe_numel () != a.numel ()) 75 if (dimensions.safe_numel () != a.numel ())
76 { 76 {
77 std::string dimensions_str = a.dimensions.str (); 77 std::string dimensions_str = a.dimensions.str ();
315 } 315 }
316 316
317 // Helper class for multi-d dimension permuting (generalized transpose). 317 // Helper class for multi-d dimension permuting (generalized transpose).
318 class rec_permute_helper 318 class rec_permute_helper
319 { 319 {
320 octave_idx_type *dim, *stride; 320 // STRIDE occupies the last half of the space allocated for dim to
321 // avoid a double allocation.
322
323 int n;
324 int top;
325 octave_idx_type *dim;
326 octave_idx_type *stride;
321 bool use_blk; 327 bool use_blk;
322 int top;
323 328
324 public: 329 public:
325 rec_permute_helper (const dim_vector& dv, const Array<octave_idx_type>& perm) 330 rec_permute_helper (const dim_vector& dv, const Array<octave_idx_type>& perm)
326 { 331
327 int n = dv.length (); 332 : n (dv.length ()), top (0), dim (new octave_idx_type [2*n]),
333 stride (dim + n), use_blk (false)
334 {
328 assert (n == perm.length ()); 335 assert (n == perm.length ());
329
330 dim = new octave_idx_type [2*n];
331 // A hack to avoid double allocation
332 stride = dim + n;
333 336
334 // Get cumulative dimensions. 337 // Get cumulative dimensions.
335 OCTAVE_LOCAL_BUFFER (octave_idx_type, cdim, n+1); 338 OCTAVE_LOCAL_BUFFER (octave_idx_type, cdim, n+1);
336 cdim[0] = 1; 339 cdim[0] = 1;
337 for (int i = 1; i < n+1; i++) cdim[i] = cdim[i-1] * dv(i-1); 340 for (int i = 1; i < n+1; i++) cdim[i] = cdim[i-1] * dv(i-1);
343 dim[k] = dv(kk); 346 dim[k] = dv(kk);
344 stride[k] = cdim[kk]; 347 stride[k] = cdim[kk];
345 } 348 }
346 349
347 // Reduce contiguous runs. 350 // Reduce contiguous runs.
348 top = 0;
349 for (int k = 1; k < n; k++) 351 for (int k = 1; k < n; k++)
350 { 352 {
351 if (stride[k] == stride[top]*dim[top]) 353 if (stride[k] == stride[top]*dim[top])
352 dim[top] *= dim[k]; 354 dim[top] *= dim[k];
353 else 355 else
520 } 522 }
521 523
522 return retval; 524 return retval;
523 } 525 }
524 526
525 // Helper class for multi-d index reduction and recursive indexing/indexed assignment. 527 // Helper class for multi-d index reduction and recursive
526 // Rationale: we could avoid recursion using a state machine instead. However, using 528 // indexing/indexed assignment. Rationale: we could avoid recursion
527 // recursion is much more amenable to possible parallelization in the future. 529 // using a state machine instead. However, using recursion is much
530 // more amenable to possible parallelization in the future.
528 // Also, the recursion solution is cleaner and more understandable. 531 // Also, the recursion solution is cleaner and more understandable.
532
529 class rec_index_helper 533 class rec_index_helper
530 { 534 {
531 octave_idx_type *dim, *cdim; 535 // CDIM occupies the last half of the space allocated for dim to
536 // avoid a double allocation.
537
538 int n;
539 int top;
540 octave_idx_type *dim;
541 octave_idx_type *cdim;
532 idx_vector *idx; 542 idx_vector *idx;
533 int top;
534 543
535 public: 544 public:
536 rec_index_helper (const dim_vector& dv, const Array<idx_vector>& ia) 545 rec_index_helper (const dim_vector& dv, const Array<idx_vector>& ia)
537 { 546 : n (ia.length ()), top (0), dim (new octave_idx_type [2*n]),
538 int n = ia.length (); 547 cdim (dim + n), idx (new idx_vector [n])
548 {
539 assert (n > 0 && (dv.length () == std::max (n, 2))); 549 assert (n > 0 && (dv.length () == std::max (n, 2)));
540
541 dim = new octave_idx_type [2*n];
542 // A hack to avoid double allocation
543 cdim = dim + n;
544 idx = new idx_vector [n];
545 top = 0;
546 550
547 dim[0] = dv(0); 551 dim[0] = dv(0);
548 cdim[0] = 1; 552 cdim[0] = 1;
549 idx[0] = ia(0); 553 idx[0] = ia(0);
550 554
577 { 581 {
578 if (lev == 0) 582 if (lev == 0)
579 dest += idx[0].index (src, dim[0], dest); 583 dest += idx[0].index (src, dim[0], dest);
580 else 584 else
581 { 585 {
582 octave_idx_type n = idx[lev].length (dim[lev]), d = cdim[lev]; 586 octave_idx_type nn = idx[lev].length (dim[lev]), d = cdim[lev];
583 for (octave_idx_type i = 0; i < n; i++) 587 for (octave_idx_type i = 0; i < nn; i++)
584 dest = do_index (src + d*idx[lev].xelem (i), dest, lev-1); 588 dest = do_index (src + d*idx[lev].xelem (i), dest, lev-1);
585 } 589 }
586 590
587 return dest; 591 return dest;
588 } 592 }
593 { 597 {
594 if (lev == 0) 598 if (lev == 0)
595 src += idx[0].assign (src, dim[0], dest); 599 src += idx[0].assign (src, dim[0], dest);
596 else 600 else
597 { 601 {
598 octave_idx_type n = idx[lev].length (dim[lev]), d = cdim[lev]; 602 octave_idx_type nn = idx[lev].length (dim[lev]), d = cdim[lev];
599 for (octave_idx_type i = 0; i < n; i++) 603 for (octave_idx_type i = 0; i < nn; i++)
600 src = do_assign (src, dest + d*idx[lev].xelem (i), lev-1); 604 src = do_assign (src, dest + d*idx[lev].xelem (i), lev-1);
601 } 605 }
602 606
603 return src; 607 return src;
604 } 608 }
609 { 613 {
610 if (lev == 0) 614 if (lev == 0)
611 idx[0].fill (val, dim[0], dest); 615 idx[0].fill (val, dim[0], dest);
612 else 616 else
613 { 617 {
614 octave_idx_type n = idx[lev].length (dim[lev]), d = cdim[lev]; 618 octave_idx_type nn = idx[lev].length (dim[lev]), d = cdim[lev];
615 for (octave_idx_type i = 0; i < n; i++) 619 for (octave_idx_type i = 0; i < nn; i++)
616 do_fill (val, dest + d*idx[lev].xelem (i), lev-1); 620 do_fill (val, dest + d*idx[lev].xelem (i), lev-1);
617 } 621 }
618 } 622 }
619 623
620 public: 624 public:
638 // Helper class for multi-d recursive resizing 642 // Helper class for multi-d recursive resizing
639 // This handles resize () in an efficient manner, touching memory only 643 // This handles resize () in an efficient manner, touching memory only
640 // once (apart from reinitialization) 644 // once (apart from reinitialization)
641 class rec_resize_helper 645 class rec_resize_helper
642 { 646 {
643 octave_idx_type *cext, *sext, *dext; 647 octave_idx_type *cext;
648 octave_idx_type *sext;
649 octave_idx_type *dext;
644 int n; 650 int n;
645 651
646 public: 652 public:
647 rec_resize_helper (const dim_vector& ndv, const dim_vector& odv) 653 rec_resize_helper (const dim_vector& ndv, const dim_vector& odv)
654 : cext (0), sext (0), dext (0), n (0)
648 { 655 {
649 int l = ndv.length (); 656 int l = ndv.length ();
650 assert (odv.length () == l); 657 assert (odv.length () == l);
651 octave_idx_type ld = 1; 658 octave_idx_type ld = 1;
652 int i = 0; 659 int i = 0;