Mercurial > hg > octave-nkf
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; |