cartodata 6.0.0
volumeutil.h
Go to the documentation of this file.
1/* This software and supporting documentation are distributed by
2 * Institut Federatif de Recherche 49
3 * CEA/NeuroSpin, Batiment 145,
4 * 91191 Gif-sur-Yvette cedex
5 * France
6 *
7 * This software is governed by the CeCILL-B license under
8 * French law and abiding by the rules of distribution of free software.
9 * You can use, modify and/or redistribute the software under the
10 * terms of the CeCILL-B license as circulated by CEA, CNRS
11 * and INRIA at the following URL "http://www.cecill.info".
12 *
13 * As a counterpart to the access to the source code and rights to copy,
14 * modify and redistribute granted by the license, users are provided only
15 * with a limited warranty and the software's author, the holder of the
16 * economic rights, and the successive licensors have only limited
17 * liability.
18 *
19 * In this respect, the user's attention is drawn to the risks associated
20 * with loading, using, modifying and/or developing or reproducing the
21 * software by the user in light of its specific status of free software,
22 * that may mean that it is complicated to manipulate, and that also
23 * therefore means that it is reserved for developers and experienced
24 * professionals having in-depth computer knowledge. Users are therefore
25 * encouraged to load and test the software's suitability as regards their
26 * requirements in conditions enabling the security of their systems and/or
27 * data to be ensured and, more generally, to use and operate it in the
28 * same conditions as regards security.
29 *
30 * The fact that you are presently reading this means that you have had
31 * knowledge of the CeCILL-B license and that you accept its terms.
32 */
33
34#ifndef CARTODATA_VOLUME_VOLUMEUTIL_H
35#define CARTODATA_VOLUME_VOLUMEUTIL_H
36
37//--- cartodata --------------------------------------------------------------
40//--- cartobase --------------------------------------------------------------
41#include <cartobase/type/datatypetraits.h>
42#include <cartobase/smart/rcptr.h>
43#include <cartobase/containers/nditerator.h>
44//--- std --------------------------------------------------------------------
45#include <algorithm>
46#include <cstddef>
47#include <exception>
48//----------------------------------------------------------------------------
49
50namespace carto
51{
52
53 //==========================================================================
54 //
55 // DECLARATIONS
56 //
57 //==========================================================================
58
59 namespace volumeutil {
60
61 //========================================================================
62 // Generic operators
63 //========================================================================
67
70 inline bool sameSize( const std::vector<int> & s1,
71 const std::vector<int> & s2 );
73 inline std::vector<int> maxSize( const std::vector<int> & s1,
74 const std::vector<int> & s2 );
76 inline std::vector<int> minSize( const std::vector<int> & s1,
77 const std::vector<int> & s2 );
78
82 template <typename T, typename UnaryFunction>
83 Volume<typename UnaryFunction::result_type>
84 apply( const Volume<T> & vol, UnaryFunction func );
85 template <typename T, typename U, typename BinaryFunction>
86 Volume<typename BinaryFunction::result_type>
87 apply( const Volume<T> & vol1, const Volume<U> & vol2, BinaryFunction func );
88 template <typename T, typename UnaryFunction>
89 rc_ptr<Volume<typename UnaryFunction::result_type> >
90 apply( const rc_ptr<Volume<T> > & vol, UnaryFunction func );
91 template <typename T, typename U, typename BinaryFunction>
92 rc_ptr<Volume<typename BinaryFunction::result_type> >
93 apply( const rc_ptr<Volume<T> > & vol1, const Volume<U> & vol2, BinaryFunction func );
94
98 template <typename T, typename UnaryFunction>
99 Volume<T> & selfApply( Volume<T> & vol, UnaryFunction func );
100 template <typename T, typename U, typename BinaryFunction>
101 Volume<T> & selfApply( Volume<T> & vol1, const Volume<U> & vol2, BinaryFunction func );
102 template <typename T, typename UnaryFunction>
103 rc_ptr<Volume<T> > & selfApply( rc_ptr<Volume<T> > & vol, UnaryFunction func );
104 template <typename T, typename U, typename BinaryFunction>
105 rc_ptr<Volume<T> > & selfApply( rc_ptr<Volume<T> > & vol1, const Volume<U> & vol2, BinaryFunction func );
107
114 template <typename T, typename OUTP, typename UnaryFunction>
115 Volume<OUTP> &
116 applyTowards( const Volume<T> & vol, Volume<OUTP> & dst, UnaryFunction func );
117 template <typename T, typename OUTP, typename UnaryFunction>
118 Volume<OUTP> &
119 applyTowards( const T & cst, Volume<OUTP> & dst, UnaryFunction func );
120 template <typename T, typename U, typename OUTP, typename BinaryFunction>
121 Volume<OUTP> &
122 applyTowards( const Volume<T> & vol1, const Volume<U> & vol2, Volume<OUTP> & dst, BinaryFunction func );
123 template <typename T, typename U, typename OUTP, typename BinaryFunction>
124 Volume<OUTP> &
125 applyTowards( const Volume<T> & vol1, const U & cst2, Volume<OUTP> & dst, BinaryFunction func );
127
141 template <typename OUTP, typename T, typename BinaryFunction>
142 OUTP accumulate( const Volume<T> & vol, BinaryFunction func, OUTP initial );
143 template <typename OUTP, typename T, typename BinaryFunction>
144 OUTP accumulate( const rc_ptr<Volume<T> > & vol, BinaryFunction func, OUTP initial );
146
147 } // namespace volumeutil
148
149 //==========================================================================
150 // Copy functions
151 //==========================================================================
152
156 template <typename T>
157 void transfer( const Volume<T> & src, Volume<T> & dst );
158 template <typename T>
159 void transfer( const rc_ptr<Volume<T> > & src, rc_ptr<Volume<T> > & dst );
160 template <typename OUTP, typename INP>
161 void transfer( const Volume<INP> & src, Volume<OUTP> & dst );
162 template <typename OUTP, typename INP>
163 void transfer( const rc_ptr<Volume<INP> > & src, rc_ptr<Volume<OUTP> > & dst );
165
169 template <typename T>
170 Volume<T> deepcopy( const Volume<T> & src,
171 const std::vector<int> & size = std::vector<int>() );
172 template <typename T>
174 const rc_ptr<Volume<T> > & src,
175 const std::vector<int> & size = std::vector<int>() );
176 template <typename OUTP, typename INP>
177 Volume<OUTP> deepcopy( const Volume<INP> & src,
178 const std::vector<int> & size = std::vector<int>() );
179 template <typename OUTP, typename INP>
181 const rc_ptr<Volume<INP> > & src,
182 const std::vector<int> & size = std::vector<int>() );
184
189 template <typename T>
190 Volume<T> copy( const Volume<T> & src );
191 template <typename T>
192 rc_ptr<Volume<T> > copy( const rc_ptr<Volume<T> > & src );
193 template <typename OUTP, typename INP>
194 Volume<OUTP> copy( const Volume<INP> & src );
195 template <typename OUTP, typename INP>
196 rc_ptr<Volume<OUTP> > copy( const rc_ptr<Volume<INP> > & src );
198
201 template <typename T>
202 Volume<T> copyStructure( const Volume<T> & src );
203 template <typename T>
205 template <typename OUTP, typename INP>
207 template <typename OUTP, typename INP>
210
211 //==========================================================================
212 // Accumulated values: Min/Max/Sum...
213 //==========================================================================
214
219 template <typename T>
220 T min( const Volume<T> & vol );
221 template <typename T>
222 T min( const rc_ptr<Volume<T> > & vol );
224
229 template <typename T>
230 T max( const Volume<T> & vol );
231 template <typename T>
232 T max( const rc_ptr<Volume<T> > & vol );
234
237 template <typename T>
238 typename DataTypeTraits<T>::LongType sum( const Volume<T> & vol );
239 template <typename OUTP, typename T>
240 OUTP sum( const Volume<T> & vol );
241 template <typename T>
242 typename DataTypeTraits<T>::LongType sum( const rc_ptr<Volume<T> > & vol );
243 template <typename OUTP, typename T>
244 OUTP sum( const rc_ptr<Volume<T> > & vol );
246
249 template <typename T>
250 bool all( const Volume<T> & vol );
251 template <typename T>
252 bool all( const rc_ptr<Volume<T> > & vol );
254
257 template <typename T>
258 bool any( const Volume<T> & vol );
259 template <typename T>
260 bool any( const rc_ptr<Volume<T> > & vol );
262
263 //==========================================================================
264 // Special operators
265 //==========================================================================
266
274 template <typename T, typename U>
275 Volume<bool> valuesIn( const Volume<T> & volume, const U & set );
276 template <typename T, typename U>
277 rc_ptr<Volume<bool> > valuesIn( const rc_ptr<Volume<T> > & volume, const U & set );
279
287 template <typename T, typename U>
288 Volume<bool> valuesNotIn( const Volume<T> & volume, const U & set );
289 template <typename T, typename U>
290 rc_ptr<Volume<bool> > valuesNotIn( const rc_ptr<Volume<T> > & volume, const U & set );
292
298 template <typename T, typename U>
299 void conditionalSet( Volume<T> & volume, const Volume<U> & condition, const T & value );
300 template <typename T, typename U>
301 void conditionalSet( rc_ptr<Volume<T> > & volume, const rc_ptr<Volume<U> > & condition, const T & value );
303
308 template <typename T>
309 Volume<T> invertMinMax( const Volume<T> & volume );
310 template <typename T>
311 rc_ptr<Volume<T> > invertMinMax( const rc_ptr<Volume<T> > & volume );
313
315 template <typename T>
316 VolumeRef<T> matrix_product( const Volume<T> & v1, const Volume<T> & v2 );
318 template <typename T>
320 const rc_ptr<Volume<T> > & v2 );
322 template <typename T>
323 VolumeRef<T> transpose( const Volume<T> & v );
328 template <typename T>
329 VolumeRef<T> transpose( const rc_ptr<Volume<T> > & v, bool copy=false );
330
331
333 template <typename T>
334 inline
336 {
337 if( thing->getSizeT() != 1 || thing->getSizeZ() != 1
338 || thing->getSizeY() != 1 )
339 throw std::runtime_error("diag expects a 1D (Nx1x1x1) vector as input");
340
341 int n = thing->getSizeX();
342 // allocate the new thing
343 rc_ptr<Volume<T> > m( new Volume<T>( n, n ) );
344 // do the operations
345 for( int x = 0; x < n; x++ )
346 m->at( x, x ) = thing->at( x );
347
348 return m;
349 }
350
351
352 template <typename T>
353 inline
355 {
356 if( thing->getSizeT() != 1 || thing->getSizeZ() != 1 )
357 throw std::runtime_error(
358 "undiag expects a 2D (NxMx1x1) matrix as input");
359
360 int n = std::min( thing->getSizeX(), thing->getSizeY() );
361 // allocate the new thing
362 rc_ptr<Volume<T> > m( new Volume<T>( n, 1, 1, 1,
363 AllocatorContext::fast() ) );
364 // do the operations
365 for( int x = 0; x < n; x++ )
366 m->at( x, 0 ) = thing->at( x, x );
367
368 return m;
369 }
370
371 //==========================================================================
372 // Borders
373 //==========================================================================
374
383 template <typename T>
384 void setBorders( Volume<T> & volume,
385 const typename Volume<T>::Position4Di & top,
386 const typename Volume<T>::Position4Di & bottom
387 = typename Volume<T>::Position4Di(-1, -1, -1, -1) );
390 template <typename T>
391 void setBorders( rc_ptr<Volume<T> > & volume,
392 const typename Volume<T>::Position4Di & top,
393 const typename Volume<T>::Position4Di & bottom
394 = typename Volume<T>::Position4Di(-1, -1, -1, -1) );
396
404 template <typename T>
405 void setMinBorders( Volume<T> & volume,
406 const typename Volume<T>::Position4Di & top,
407 const typename Volume<T>::Position4Di & bottom
408 = typename Volume<T>::Position4Di(-1, -1, -1, -1) );
411 template <typename T>
412 void setMinBorders( rc_ptr<Volume<T> > & volume,
413 const typename Volume<T>::Position4Di & top,
414 const typename Volume<T>::Position4Di & bottom
415 = typename Volume<T>::Position4Di(-1, -1, -1, -1) );
417
418
419 template<typename T>
420 inline
421 bool isSameVolumeSize( const Volume<T> & v1, const Volume<T> & v2 )
422 {
423 std::vector<int> dim1 = v1.getSize();
424 std::vector<int> dim2 = v2.getSize();
425 std::size_t i, n1 = dim1.size(), n2 = dim2.size(), n = std::min( n1, n2 );
426 for( i=0; i<n; ++i )
427 if( dim1[i] != dim2[i] )
428 return false;
429 for( ; i<n1; ++i )
430 if( dim1[i] != 1 )
431 return false;
432 for( ; i<n2; ++i )
433 if( dim2[i] != 1 )
434 return false;
435
436 return true;
437 }
438
439
440 template<typename T>
441 inline
443 const rc_ptr<Volume<T> > & v2 )
444 {
445 return isSameVolumeSize( *v1, *v2 );
446 }
447
448
449 //==========================================================================
450 //
451 // DEFINITIONS
452 //
453 //==========================================================================
454
455 namespace volumeutil {
456
457 //========================================================================
458 // Generic operators
459 //========================================================================
460
461 bool sameSize( const std::vector<int> & s1, const std::vector<int> & s2 )
462 {
463 std::size_t s0 = s1.size();
464 std::size_t i;
465 if( s2.size() < s0 )
466 s0 = s2.size();
467 for( i=0; i<s0; ++i )
468 if( s1[i] != s2[i] )
469 return false;
470 for( ; i<s1.size(); ++i )
471 if( s1[i] != 1 )
472 return false;
473 for( ; i<s2.size(); ++i )
474 if( s2[i] != 1 )
475 return false;
476 return true;
477 }
478
479
480 std::vector<int> maxSize( const std::vector<int> & s1,
481 const std::vector<int> & s2 )
482 {
483 std::vector<int> dim( std::max( s1.size(), s2.size() ), 1 );
484 std::size_t s0 = s1.size();
485 std::size_t i;
486 if( s2.size() < s0 )
487 s0 = s2.size();
488 for( i=0; i<s0; ++i )
489 dim[i] = std::max( s1[i], s2[i] );
490 for( ; i<s1.size(); ++i )
491 dim[i] = s1[i];
492 for( ; i<s2.size(); ++i )
493 dim[i] = s2[i];
494 return dim;
495 }
496
497
498 std::vector<int> minSize( const std::vector<int> & s1,
499 const std::vector<int> & s2 )
500 {
501 std::vector<int> dim( std::min( s1.size(), s2.size() ), 1 );
502 std::size_t s0 = s1.size();
503 std::size_t i;
504 if( s2.size() < s0 )
505 s0 = s2.size();
506 for( i=0; i<s0; ++i )
507 dim[i] = std::min( s1[i], s2[i] );
508 for( ; i<dim.size(); ++i )
509 dim[i] = 1;
510 return dim;
511 }
512
513
514 //--- Volume [op] other --------------------------------------------------
515
516 template <typename T, typename UnaryFunction>
517 inline
519 apply( const Volume<T> & vol, UnaryFunction func )
520 {
521 typedef typename UnaryFunction::result_type OUTP;
522 Volume<OUTP> output = deepcopy<OUTP,T>(vol);
523 applyTowards( vol, output, func );
524 return output;
525 }
526
527 template <typename T, typename U, typename BinaryFunction>
528 inline
530 apply( const Volume<T> & vol1, const Volume<U> & vol2, BinaryFunction func )
531 {
532 typedef typename BinaryFunction::result_type OUTP;
534 vol1, maxSize( vol1.getSize(), vol2.getSize() ) );
535 applyTowards( vol1, vol2, output, func );
536 return output;
537 }
538
539 //--- VolumeRef [op]= other ----------------------------------------------
540
541 template <typename T, typename UnaryFunction>
542 inline
544 apply( const rc_ptr<Volume<T> > & vol, UnaryFunction func )
545 {
546 typedef typename UnaryFunction::result_type OUTP;
548 applyTowards( *vol, *output, func );
549 return output;
550 }
551
552 template <typename T, typename U, typename BinaryFunction>
553 inline
555 apply( const rc_ptr<Volume<T> > & vol1, const Volume<U> & vol2, BinaryFunction func )
556 {
557 typedef typename BinaryFunction::result_type OUTP;
559 vol1, maxSize( vol1->getSize(), vol2.getSize()) );
560 applyTowards( *vol1, vol2, *output, func );
561 return output;
562 }
563
564 //--- Volume [op]= other -------------------------------------------------
565
566 template <typename T, typename UnaryFunction>
567 inline
568 Volume<T> & selfApply( Volume<T> & vol, UnaryFunction func )
569 {
570 applyTowards( vol, vol, func );
571 return vol;
572 }
573
574 template <typename T, typename U, typename BinaryFunction>
575 inline
576 Volume<T> & selfApply( Volume<T> & vol1, const Volume<U> & vol2, BinaryFunction func )
577 {
578 applyTowards( vol1, vol2, vol1, func );
579 return vol1;
580 }
581
582 //--- VolumeRef [op]= other ----------------------------------------------
583
584 template <typename T, typename UnaryFunction>
585 inline
586 rc_ptr<Volume<T> > & selfApply( rc_ptr<Volume<T> > & vol, UnaryFunction func )
587 {
588 selfApply( *vol, func );
589 return vol;
590 }
591
592 template <typename T, typename U, typename BinaryFunction>
593 inline
594 rc_ptr<Volume<T> > & selfApply( rc_ptr<Volume<T> > & vol1, const Volume<U> & vol2, BinaryFunction func )
595 {
596 selfApply( *vol1, vol2, func );
597 return vol1;
598 }
599
600 //--- Volume [op] other -> Output ---------------------------------------
601 template <typename T, typename OUTP, typename UnaryFunction>
602 inline
605 UnaryFunction func )
606 {
607 std::vector<int> size = minSize( vol.getSize(), dst.getSize() );
608 if( !sameSize( size, vol.getSize() )
609 || !sameSize( size, dst.getSize() ) )
610 {
611 // build views
613 const_cast<carto::Volume<T> *>( &vol ) );
614 std::vector<int> pos( size.size(), 0 );
615 carto::VolumeRef<T> invol( invvol, pos, size );
616 carto::rc_ptr<Volume<OUTP> > outvvol( &dst );
617 carto::VolumeRef<OUTP> outvol( outvvol, pos, size );
618 // applyTowards on views of the same size
619 applyTowards( *invol, *outvol, func );
620 // release views and restore refcount on initial volumes
621 invol.reset( 0 );
622 invvol.release();
623 outvol.reset( 0 );
624 outvvol.release();
625 // FIXME TODO: handle parts outside of the intersection
626 return dst;
627 }
628 carto::const_line_NDIterator<T> it( &vol.at( 0 ), vol.getSize(),
629 vol.getStrides() );
630 carto::line_NDIterator<OUTP> dit( &dst.at( 0 ), dst.getSize(),
631 dst.getStrides() );
632 const T *p, *pp;
633 OUTP *d;
634 for( ; !it.ended(); ++it, ++dit )
635 {
636 p = &*it;
637 d = &*dit;
638 for( pp=p + it.line_length(); p!=pp;
639 it.inc_line_ptr( p ), dit.inc_line_ptr( d ) )
640 *d = func( *p );
641 }
642 return dst;
643 }
644
645 template <typename T, typename OUTP, typename UnaryFunction>
646 inline
648 applyTowards( const T & cst, Volume<OUTP> & dst,
649 UnaryFunction func )
650 {
651 carto::line_NDIterator<OUTP> dit( &dst.at( 0 ), dst.getSize(),
652 dst.getStrides() );
653 OUTP *d, *dd;
654 OUTP value = func( cst );
655 for( ; !dit.ended(); ++dit )
656 {
657 d = &*dit;
658 for( dd=d + dit.line_length(); d!=dd; dit.inc_line_ptr( d ) )
659 *d = value;
660 }
661 return dst;
662 }
663
664 template <typename T, typename U, typename OUTP, typename BinaryFunction>
665 inline
667 applyTowards( const Volume<T> & vol1, const Volume<U> & vol2,
668 Volume<OUTP> & dst, BinaryFunction func )
669 {
670 std::vector<int> sizei = minSize( vol1.getSize(), vol2.getSize() );
671 std::vector<int> size = minSize( sizei, dst.getSize() );
672 if( !sameSize( size, vol1.getSize() )
673 || !sameSize( size, vol2.getSize() )
674 || !sameSize( size, dst.getSize() ) )
675 {
676 // build views
677 carto::rc_ptr<Volume<T> > invvol1(
678 const_cast<carto::Volume<T> *>( &vol1 ) );
679 std::vector<int> pos( size.size(), 0 );
680 carto::VolumeRef<T> invol1( invvol1, pos, size );
681 carto::rc_ptr<Volume<U> > invvol2(
682 const_cast<carto::Volume<U> *>( &vol2 ) );
683 carto::VolumeRef<U> invol2( invvol2, pos, size );
684 carto::rc_ptr<Volume<OUTP> > outvvol( &dst );
685 carto::VolumeRef<OUTP> outvol( outvvol, pos, size );
686 // applyTowards on views of the same size
687 applyTowards( *invol1, *invol2, *outvol, func );
688 // release views and restore refcount on initial volumes
689 invol1.reset( 0 );
690 invvol1.release();
691 invol2.reset( 0 );
692 invvol2.release();
693 outvol.reset( 0 );
694 outvvol.release();
695 // FIXME TODO: handle parts outside of the intersection
696 return dst;
697 }
698
699 carto::const_line_NDIterator<T> it1( &vol1.at( 0 ), vol1.getSize(),
700 vol1.getStrides() );
701 carto::const_line_NDIterator<U> it2( &vol2.at( 0 ), vol2.getSize(),
702 vol2.getStrides() );
703 carto::line_NDIterator<OUTP> dit( &dst.at( 0 ), dst.getSize(),
704 dst.getStrides() );
705 const T *p, *pp;
706 const U *p2;
707 OUTP *d;
708 for( ; !it1.ended(); ++it1, ++it2, ++dit )
709 {
710 p = &*it1;
711 p2 = &*it2;
712 d = &*dit;
713 for( pp=p + it1.line_length(); p!=pp;
714 it1.inc_line_ptr( p ), it2.inc_line_ptr( p2 ),
715 dit.inc_line_ptr( d ) )
716 *d = func( *p, *p2 );
717 }
718 return dst;
719 }
720
721 template <typename T, typename U, typename OUTP, typename BinaryFunction>
722 inline
724 applyTowards( const T & cst1, const Volume<U> & vol2,
725 Volume<OUTP> & dst, BinaryFunction func )
726 {
727 std::vector<int> size = minSize( vol2.getSize(), dst.getSize() );
728 if( !sameSize( size, vol2.getSize() )
729 || !sameSize( size, dst.getSize() ) )
730 {
731 // build views
732 std::vector<int> pos( size.size(), 0 );
733 carto::rc_ptr<Volume<U> > invvol2(
734 const_cast<carto::Volume<U> *>( &vol2 ) );
735 carto::VolumeRef<U> invol2( invvol2, pos, size );
736 carto::rc_ptr<Volume<OUTP> > outvvol( &dst );
737 carto::VolumeRef<OUTP> outvol( outvvol, pos, size );
738 // applyTowards on views of the same size
739 applyTowards( cst1, *invol2, *outvol, func );
740 // release views and restore refcount on initial volumes
741 invol2.reset( 0 );
742 invvol2.release();
743 outvol.reset( 0 );
744 outvvol.release();
745 // FIXME TODO: handle parts outside of the intersection
746 return dst;
747 }
748
749 carto::const_line_NDIterator<U> it2( &vol2.at( 0 ), vol2.getSize(),
750 vol2.getStrides() );
751 carto::line_NDIterator<OUTP> dit( &dst.at( 0 ), dst.getSize(),
752 dst.getStrides() );
753 const U *p2, *pp;
754 OUTP *d;
755 for( ; !it2.ended(); ++it2, ++dit )
756 {
757 p2 = &*it2;
758 d = &*dit;
759 for( pp=p2+ it2.line_length(); p2!=pp;
760 it2.inc_line_ptr( p2 ), dit.inc_line_ptr( d ) )
761 *d = func( cst1, *p2 );
762 }
763 return dst;
764 }
765
766 template <typename T, typename U, typename OUTP, typename BinaryFunction>
767 inline
769 applyTowards( const Volume<T> & vol1, const U & cst2,
770 Volume<OUTP> & dst, BinaryFunction func )
771 {
772 std::vector<int> size = minSize( vol1.getSize(), dst.getSize() );
773 if( !sameSize( size, vol1.getSize() )
774 || !sameSize( size, dst.getSize() ) )
775 {
776 // build views
777 carto::rc_ptr<Volume<T> > invvol1(
778 const_cast<carto::Volume<T> *>( &vol1 ) );
779 std::vector<int> pos( size.size(), 0 );
780 carto::VolumeRef<T> invol1( invvol1, pos, size );
781 carto::rc_ptr<Volume<OUTP> > outvvol( &dst );
782 carto::VolumeRef<OUTP> outvol( outvvol, pos, size );
783 // applyTowards on views of the same size
784 applyTowards( *invol1, cst2, *outvol, func );
785 // release views and restore refcount on initial volumes
786 invol1.reset( 0 );
787 invvol1.release();
788 outvol.reset( 0 );
789 outvvol.release();
790 // FIXME TODO: handle parts outside of the intersection
791 return dst;
792 }
793
794 carto::const_line_NDIterator<T> it1( &vol1.at( 0 ), vol1.getSize(),
795 vol1.getStrides() );
796 carto::line_NDIterator<OUTP> dit( &dst.at( 0 ), dst.getSize(),
797 dst.getStrides() );
798 const T *p, *pp;
799 OUTP *d;
800 for( ; !it1.ended(); ++it1, ++dit )
801 {
802 p = &*it1;
803 d = &*dit;
804 for( pp=p + it1.line_length(); p!=pp;
805 it1.inc_line_ptr( p ), dit.inc_line_ptr( d ) )
806 *d = func( *p, cst2 );
807 }
808 return dst;
809 }
810
811 //--- Volume: accumulate -------------------------------------------------
812
813 template <typename OUTP, typename T, typename BinaryFunction>
814 inline
815 OUTP accumulate( const Volume<T> & vol, BinaryFunction func, OUTP initial )
816 {
817 carto::const_line_NDIterator<T> it( &vol.at( 0 ), vol.getSize(),
818 vol.getStrides() );
819 const T *p, *pp;
820 for( ; !it.ended(); ++it )
821 {
822 p = &*it;
823 for( pp=p + it.line_length(); p!=pp; it.inc_line_ptr( p ) )
824 initial = func( initial, *p );
825 }
826 return initial;
827 }
828
829 //--- VolumeRef: accumulate ----------------------------------------------
830
831 template <typename OUTP, typename T, typename BinaryFunction>
832 inline
833 OUTP accumulate( const rc_ptr<Volume<T> > & vol, BinaryFunction func, OUTP initial )
834 {
835 return accumulate<OUTP, T, BinaryFunction>( *vol, func, initial );
836 }
837
838 } // namespace volumeutil
839
840 //==========================================================================
841 // Copy functions
842 //==========================================================================
843
844 //--- transfer -------------------------------------------------------------
845
846 template <typename T>
847 inline
848 void transfer( const Volume<T> & src, Volume<T> & dst )
849 {
850 transfer<T,T>( src, dst );
851 }
852
853 template <typename T>
854 inline
855 void transfer( const rc_ptr<Volume<T> > & src, rc_ptr<Volume<T> > & dst )
856 {
857 transfer<T,T>( src, dst );
858 }
859
860 template <typename OUTP, typename INP>
861 inline
862 void transfer( const Volume<INP> & src, Volume<OUTP> & dst )
863 {
865 }
866
867 template <typename OUTP, typename INP>
868 inline
869 void transfer( const rc_ptr<Volume<INP> > & src, rc_ptr<Volume<OUTP> > & dst )
870 {
871 transfer( *src, *dst );
872 }
873
874 //--- deepcopy -------------------------------------------------------------
875
876 template <typename T>
877 inline
878 Volume<T> deepcopy( const Volume<T> & src, const std::vector<int> & size )
879 {
880 return deepcopy<T,T>( src, size );
881 }
882
883 template <typename T>
884 inline
886 const std::vector<int> & size )
887 {
888 return deepcopy<T,T>( src, size );
889 }
890
891 template <typename OUTP, typename INP>
892 inline
894 const std::vector<int> & size )
895 {
896 std::vector<int> nsize = size;
897 if( nsize.empty() )
898 nsize = src.getSize();
899 Volume<OUTP> dst( nsize,
900 src.allocatorContext(),
901 src.allocatorContext().isAllocated() );
902 dst.copyHeaderFrom( src.header() );
903 if( src.allocatorContext().isAllocated()
904 && src.allocatorContext().allocatorType()
905 != AllocatorStrategy::Unallocated )
906 transfer( src, dst );
907
908 if( src.refVolume() )
909 {
910 rc_ptr<Volume<INP> > srcparent = src.refVolume();
911 rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
912 srcparent->getSize(),
913 srcparent->allocatorContext(),
914 srcparent->allocatorContext().isAllocated() ) );
915 if( srcparent->allocatorContext().isAllocated()
916 && srcparent->allocatorContext().allocatorType()
917 != AllocatorStrategy::Unallocated )
918 transfer( srcparent, dstparent );
919 dst.setRefVolume( dstparent );
921 }
922
923 rc_ptr<Volume<INP> > srcchild = src.refVolume();
924 rc_ptr<Volume<OUTP> > dstchild = dst.refVolume();
925
926 while( srcchild->refVolume().get() )
927 {
928 rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
929 rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
930 srcparent->getSize(),
931 srcparent->allocatorContext(),
932 srcparent->allocatorContext().isAllocated() ) );
933 dstparent->copyHeaderFrom( srcparent->header() );
934 if( srcparent->allocatorContext().isAllocated()
935 && srcparent->allocatorContext().allocatorType()
936 != AllocatorStrategy::Unallocated )
937 transfer( srcparent, dstparent );
938 dstchild->setRefVolume( dstparent );
939 dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
940 srcchild = srcparent;
941 dstchild = dstparent;
942 }
943
944 return dst;
945 }
946
947 template <typename OUTP, typename INP>
948 inline
950 const std::vector<int> & size )
951 {
952 std::vector<int> nsize = size;
953 if( nsize.empty() )
954 nsize = src->getSize();
956 nsize,
957 src->allocatorContext(),
958 src->allocatorContext().isAllocated() ) );
959 dst->copyHeaderFrom( src->header() );
960 if( src->allocatorContext().isAllocated()
961 && src->allocatorContext().allocatorType()
962 != AllocatorStrategy::Unallocated )
963 transfer( src, dst );
964
965 rc_ptr<Volume<INP> > srcchild = src;
966 rc_ptr<Volume<OUTP> > dstchild = dst;
967
968 while( srcchild->refVolume().get() )
969 {
970 rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
971 rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
972 srcparent->getSize(),
973 srcparent->allocatorContext(),
974 srcparent->allocatorContext().isAllocated() ) );
975 dstparent->copyHeaderFrom( srcparent->header() );
976 if( srcparent->allocatorContext().isAllocated()
977 && srcparent->allocatorContext().allocatorType()
978 != AllocatorStrategy::Unallocated )
979 transfer( srcparent, dstparent );
980 dstchild->setRefVolume( dstparent );
981 dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
982 srcchild = srcparent;
983 dstchild = dstparent;
984 }
985
986 return dst;
987 }
988
989
990 //--- copy -----------------------------------------------------------------
991
992 template <typename T>
993 inline
994 Volume<T> copy( const Volume<T> & src )
995 {
996 return copy<T,T>( src );
997 }
998
999 template <typename T>
1000 inline
1002 {
1003 return copy<T,T>( src );
1004 }
1005
1006 template <typename OUTP, typename INP>
1007 inline
1009 {
1010 Volume<OUTP> dst( src.getSize() );
1011 dst.copyHeaderFrom( src.header() );
1012 transfer( src, dst );
1013 return dst;
1014 }
1015
1016 template <typename OUTP, typename INP>
1017 inline
1019 {
1020 rc_ptr<Volume<OUTP> > dst( new Volume<OUTP>( src->getSize() ) );
1021 dst->copyHeaderFrom( src->header() );
1022 transfer( src, dst );
1023 return dst;
1024 }
1025
1026
1027 //--- copyStructure --------------------------------------------------------
1028
1029 template <typename T>
1030 inline
1032 {
1033 return copyStructure<T,T>( src );
1034 }
1035
1036 template <typename T>
1037 inline
1039 {
1040 return copyStructure<T,T>( src );
1041 }
1042
1043 template <typename OUTP, typename INP>
1044 inline
1046 {
1047 Volume<OUTP> dst( src.getSize(),
1048 src.allocatorContext(),
1049 src.allocatorContext().isAllocated() );
1050 dst.copyHeaderFrom( src.header() );
1051 // if( src.allocatorContext().isAllocated() )
1052 // dst.fill(0);
1053
1054 if( src.refVolume() )
1055 {
1056 rc_ptr<Volume<INP> > srcparent = src.refVolume();
1057 rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
1058 srcparent->getSize(),
1059 srcparent->allocatorContext(),
1060 srcparent->allocatorContext().isAllocated() ) );
1061 // if( srcparent->allocatorContext().isAllocated() )
1062 // dstparent->fill(0);
1063 dst.setRefVolume( dstparent );
1064 dst.setPosInRefVolume( src.posInRefVolume() );
1065
1066 rc_ptr<Volume<INP> > srcchild = src.refVolume();
1067 rc_ptr<Volume<OUTP> > dstchild = dst.refVolume();
1068
1069 while( srcchild->refVolume().get() )
1070 {
1071 rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
1072 rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
1073 srcparent->getSize(),
1074 srcparent->allocatorContext(),
1075 srcparent->allocatorContext().isAllocated() ) );
1076 dstparent->copyHeaderFrom( srcparent->header() );
1077 // if( srcparent->allocatorContext().isAllocated() )
1078 // dstparent->fill(0);
1079 dstchild->setRefVolume( dstparent );
1080 dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
1081 srcchild = srcparent;
1082 dstchild = dstparent;
1083 }
1084
1085 }
1086
1087 return dst;
1088 }
1089
1090 template <typename OUTP, typename INP>
1091 inline
1093 {
1094 if( !src.get() )
1095 return rc_ptr<Volume<OUTP> >( (Volume<OUTP>*)0 );
1096
1098 src->getSize(),
1099 src->allocatorContext(),
1100 src->allocatorContext().isAllocated() ) );
1101 dst->copyHeaderFrom( src->header() );
1102 // if( src->allocatorContext().isAllocated() )
1103 // dst->fill(0);
1104
1105 rc_ptr<Volume<INP> > srcchild = src;
1106 rc_ptr<Volume<OUTP> > dstchild = dst;
1107
1108 while( srcchild->refVolume().get() )
1109 {
1110 rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
1111 rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
1112 srcparent->getSize(),
1113 srcparent->allocatorContext(),
1114 srcparent->allocatorContext().isAllocated() ) );
1115 dstparent->copyHeaderFrom( srcparent->header() );
1116 // if( srcparent->allocatorContext().isAllocated() )
1117 // dstparent->fill(0);
1118 dstchild->setRefVolume( dstparent );
1119 dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
1120 srcchild = srcparent;
1121 dstchild = dstparent;
1122 }
1123
1124 return dst;
1125 }
1126
1127
1128 //==========================================================================
1129 // Min/Max/Sum/Any/All
1130 //==========================================================================
1131
1132 template <typename T>
1133 inline
1134 T min( const Volume<T> & vol )
1135 {
1136 if( vol.getSizeX() == 0 && vol.getSizeY() == 0 &&
1137 vol.getSizeZ() == 0 && vol.getSizeT() == 0 )
1138 throw std::runtime_error("Cannot compute min of an empty volume");
1139 return accumulate( vol, volumeutil::select_min<T>(), vol.at(0, 0, 0, 0) );
1140 }
1141
1142 template <typename T>
1143 inline
1144 T min( const rc_ptr<Volume<T> > & vol )
1145 {
1146 if( !vol.get() || ( vol->getSizeX() == 0 && vol->getSizeY() == 0 &&
1147 vol->getSizeZ() == 0 && vol->getSizeT() == 0 ) )
1148 throw std::runtime_error("Cannot compute min of an empty volume");
1149 return accumulate( vol, volumeutil::select_min<T>(), vol->at(0, 0, 0, 0) );
1150 }
1151
1152 template <typename T>
1153 inline
1154 T max( const Volume<T> & vol )
1155 {
1156 if( vol.getSizeX() == 0 && vol.getSizeY() == 0 &&
1157 vol.getSizeZ() == 0 && vol.getSizeT() == 0 )
1158 throw std::runtime_error("Cannot compute max of an empty volume");
1159 return accumulate( vol, volumeutil::select_max<T>(), vol.at(0, 0, 0, 0) );
1160 }
1161
1162 template <typename T>
1163 inline
1164 T max( const rc_ptr<Volume<T> > & vol )
1165 {
1166 if( !vol.get() || ( vol->getSizeX() == 0 && vol->getSizeY() == 0 &&
1167 vol->getSizeZ() == 0 && vol->getSizeT() == 0 ) )
1168 throw std::runtime_error("Cannot compute max of an empty volume");
1169 return accumulate( vol, volumeutil::select_max<T>(), vol->at(0, 0, 0, 0) );
1170 }
1171
1172 template <typename T>
1173 inline
1175 {
1177 }
1178
1179
1180 template <typename OUTP, typename T>
1181 inline
1182 OUTP sum( const Volume<T> & vol )
1183 {
1184 return accumulate( vol, volumeutil::plus<OUTP,T>(), static_cast<OUTP>(0) );
1185 }
1186
1187 template <typename T>
1188 inline
1190 {
1192 }
1193
1194 template <typename OUTP, typename T>
1195 inline
1196 OUTP sum( const rc_ptr<Volume<T> > & vol )
1197 {
1198 if( !vol.get() )
1199 return static_cast<OUTP>(0);
1200 return accumulate( vol, volumeutil::plus<OUTP,T>(), static_cast<OUTP>(0) );
1201 }
1202
1203 template <typename T>
1204 inline
1205 bool all( const Volume<T> & vol )
1206 {
1208 }
1209
1210 template <typename T>
1211 inline
1212 bool all( const rc_ptr<Volume<T> > & vol )
1213 {
1215 }
1216
1217 template <typename T>
1218 inline
1219 bool any( const Volume<T> & vol )
1220 {
1222 }
1223
1224 template <typename T>
1225 inline
1226 bool any( const rc_ptr<Volume<T> > & vol )
1227 {
1229 }
1230
1231 //==========================================================================
1232 // Special operators
1233 //==========================================================================
1234
1235 namespace internal {
1236 template <typename T, typename U>
1237 struct inSet: public std::binary_function<T, U, bool>
1238 {
1239 bool operator() ( const T & x, const U & y )
1240 {
1241 for( typename U::const_iterator k = y.begin(); k != y.end(); ++k )
1242 if( x == *k )
1243 return true;
1244 return false;
1245 }
1246 };
1247 } // namespace internal
1248
1249 template <typename T, typename U>
1250 inline
1251 Volume<bool> valuesIn( const Volume<T> & volume, const U & set )
1252 {
1253 Volume<bool> output = copyStructure<bool, T>( volume );
1254 volumeutil::applyTowards( volume, output, std::bind2nd( internal::inSet<T,U>(), set ) );
1255 return output;
1256 }
1257
1258 template <typename T, typename U>
1259 inline
1260 rc_ptr<Volume<bool> > valuesIn( const rc_ptr<Volume<T> > & volume, const U & set )
1261 {
1262 rc_ptr<Volume<bool> > output = copyStructure<bool, T>( volume );
1263 volumeutil::applyTowards( *volume, *output, std::bind2nd( internal::inSet<T,U>(), set ) );
1264 return output;
1265 }
1266
1267 namespace internal {
1268 template <typename T, typename U>
1269 struct notInSet: public std::binary_function<T, U, bool>
1270 {
1271 bool operator() ( const T & x, const U & y )
1272 {
1273 for( typename U::const_iterator k = y.begin(); k != y.end(); ++k )
1274 if( x == *k )
1275 return false;
1276 return true;
1277 }
1278 };
1279 } // namespace internal
1280
1281 template <typename T, typename U>
1282 inline
1283 Volume<bool> valuesNotIn( const Volume<T> & volume, const U & set )
1284 {
1285 Volume<bool> output = copyStructure<bool, T>( volume );
1286 volumeutil::applyTowards( volume, output, std::bind2nd( internal::notInSet<T,U>(), set ) );
1287 return output;
1288 }
1289
1290 template <typename T, typename U>
1291 inline
1292 rc_ptr<Volume<bool> > valuesNotIn( const rc_ptr<Volume<T> > & volume, const U & set )
1293 {
1294 rc_ptr<Volume<bool> > output = copyStructure<bool, T>( volume );
1295 volumeutil::applyTowards( *volume, *output, std::bind2nd( internal::notInSet<T,U>(), set ) );
1296 return output;
1297 }
1298
1299 namespace internal {
1300 template <typename T, typename U>
1301 struct changeIf: public std::binary_function<T, U, T>
1302 {
1303 changeIf( const T & value ): _value(value) {}
1304 bool operator() ( const T & x, const U & y )
1305 {
1306 return y ? _value : x;
1307 }
1308 private:
1309 T _value;
1310 };
1311 } // namespace internal
1312
1313 template <typename T, typename U>
1314 inline
1315 void conditionalSet( Volume<T> & volume, const Volume<U> & condition, const T & value )
1316 {
1317 volumeutil::selfApply( volume, condition, internal::changeIf<T,U>(value) );
1318 }
1319
1320 template <typename T, typename U>
1321 inline
1322 void conditionalSet( rc_ptr<Volume<T> > & volume, const rc_ptr<Volume<U> > & condition, const T & value )
1323 {
1324 volumeutil::selfApply( volume, *condition, internal::changeIf<T,U>(value) );
1325 }
1326
1327 namespace internal {
1328 template <typename T>
1329 struct invMinMax: public std::unary_function<T, T>
1330 {
1331 invMinMax( const T & min, const T & max ):
1332 _min(min),
1333 _max(max)
1334 {}
1335
1336 T operator() ( const T & x )
1337 {
1338 return max - x + min;
1339 }
1340 private:
1341 T _min;
1342 T _max;
1343 };
1344 } // namespace internal
1345
1346 template <typename T>
1347 inline
1349 {
1350 T min = min( volume );
1351 T max = max( volume );
1353 }
1354
1355 template <typename T>
1356 inline
1358 {
1359 T min = min( volume );
1360 T max = max( volume );
1362 }
1363
1364 //==========================================================================
1365 // Borders
1366 //==========================================================================
1367
1368 template <typename T>
1369 inline
1370 void setBorders( Volume<T> & volume,
1371 const typename Volume<T>::Position4Di & top,
1372 const typename Volume<T>::Position4Di & bottom )
1373 {
1374 const typename Volume<T>::Position4Di & bot =
1375 ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
1376 top : bottom );
1377 std::vector<int> b = volume.getBorders();
1378 if( b[0] != top[0] || b[1] != bot[0] ||
1379 b[2] != top[1] || b[3] != bot[1] ||
1380 b[4] != top[2] || b[5] != bot[2] ||
1381 b[6] != top[3] || b[7] != bot[3] )
1382 {
1383 rc_ptr<Volume<T> > parent( new Volume<T>(
1384 volume.getSizeX() + top[0] + bot[0],
1385 volume.getSizeY() + top[1] + bot[1],
1386 volume.getSizeZ() + top[2] + bot[2],
1387 volume.getSizeT() + top[3] + bot[3] ) );
1388 parent->copyHeaderFrom( volume.header() );
1389 typename Volume<T>::Position4Di size( volume.getSizeX(),
1390 volume.getSizeY(),
1391 volume.getSizeZ(),
1392 volume.getSizeT() );
1393 Volume<T> view( parent, top, size );
1394 transfer( volume, view );
1395 volume.reallocate( volume.getSizeX(), volume.getSizeY(),
1396 volume.getSizeZ(), volume.getSizeT(),
1397 true, volume.allocatorContext(), false );
1398 volume.setRefVolume( parent );
1399 volume.setPosInRefVolume( top );
1400 }
1401 }
1402
1403 template <typename T>
1404 inline
1405 void setBorders( rc_ptr<Volume<T> > & volume,
1406 const typename Volume<T>::Position4Di & top,
1407 const typename Volume<T>::Position4Di & bottom )
1408 {
1409 const typename Volume<T>::Position4Di & bot =
1410 ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
1411 top : bottom );
1412 std::vector<int> b = volume->getBorders();
1413 if( b[0] != top[0] || b[1] != bot[0] ||
1414 b[2] != top[1] || b[3] != bot[1] ||
1415 b[4] != top[2] || b[5] != bot[2] ||
1416 b[6] != top[3] || b[7] != bot[3] )
1417 {
1418 rc_ptr<Volume<T> > parent( new Volume<T>(
1419 volume->getSizeX() + top[0] + bot[0],
1420 volume->getSizeY() + top[1] + bot[1],
1421 volume->getSizeZ() + top[2] + bot[2],
1422 volume->getSizeT() + top[3] + bot[3] ) );
1423 parent->copyHeaderFrom( volume->header() );
1424 typename Volume<T>::Position4Di size( volume->getSizeX(),
1425 volume->getSizeY(),
1426 volume->getSizeZ(),
1427 volume->getSizeT() );
1428 rc_ptr<Volume<T> > view( new Volume<T>( parent, top, size ) );
1429 transfer( volume, view );
1430 volume->reallocate( volume->getSizeX(), volume->getSizeY(),
1431 volume->getSizeZ(), volume->getSizeT(),
1432 true, volume->allocatorContext(), false );
1433 volume->setRefVolume( parent );
1434 volume->setPosInRefVolume( top );
1435 }
1436 }
1437
1438 template <typename T>
1439 inline
1440 void setMinBorders( Volume<T> & volume,
1441 const typename Volume<T>::Position4Di & top,
1442 const typename Volume<T>::Position4Di & bottom )
1443 {
1444 const typename Volume<T>::Position4Di & bot =
1445 ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
1446 top : bottom );
1447 std::vector<int> b = volume.getBorders();
1448 if( b[0] < top[0] || b[1] < bot[0] ||
1449 b[2] < top[1] || b[3] < bot[1] ||
1450 b[4] < top[2] || b[5] < bot[2] ||
1451 b[6] < top[3] || b[7] < bot[3] )
1452 {
1453 rc_ptr<Volume<T> > parent( new Volume<T>(
1454 volume.getSizeX() + top[0] + bot[0],
1455 volume.getSizeY() + top[1] + bot[1],
1456 volume.getSizeZ() + top[2] + bot[2],
1457 volume.getSizeT() + top[3] + bot[3] ) );
1458 parent->copyHeaderFrom( volume.header() );
1459 typename Volume<T>::Position4Di size( volume.getSizeX(),
1460 volume.getSizeY(),
1461 volume.getSizeZ(),
1462 volume.getSizeT() );
1463 Volume<T> view( parent, top, size );
1464 transfer( volume, view );
1465 volume.reallocate( volume.getSizeX(), volume.getSizeY(),
1466 volume.getSizeZ(), volume.getSizeT(),
1467 true, volume.allocatorContext(), false );
1468 volume.setRefVolume( parent );
1469 volume.setPosInRefVolume( top );
1470 }
1471 }
1472
1473 template <typename T>
1474 inline
1476 const typename Volume<T>::Position4Di & top,
1477 const typename Volume<T>::Position4Di & bottom )
1478 {
1479 const typename Volume<T>::Position4Di & bot =
1480 ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
1481 top : bottom );
1482 std::vector<int> b = volume->getBorders();
1483 if( b[0] < top[0] || b[1] < bot[0] ||
1484 b[2] < top[1] || b[3] < bot[1] ||
1485 b[4] < top[2] || b[5] < bot[2] ||
1486 b[6] < top[3] || b[7] < bot[3] )
1487 {
1488 rc_ptr<Volume<T> > parent( new Volume<T>(
1489 volume->getSizeX() + top[0] + bot[0],
1490 volume->getSizeY() + top[1] + bot[1],
1491 volume->getSizeZ() + top[2] + bot[2],
1492 volume->getSizeT() + top[3] + bot[3] ) );
1493 parent->copyHeaderFrom( volume->header() );
1494 typename Volume<T>::Position4Di size( volume->getSizeX(),
1495 volume->getSizeY(),
1496 volume->getSizeZ(),
1497 volume->getSizeT() );
1498 rc_ptr<Volume<T> > view( new Volume<T>( parent, top, size ) );
1499 transfer( volume, view );
1500 volume->reallocate( volume->getSizeX(), volume->getSizeY(),
1501 volume->getSizeZ(), volume->getSizeT(),
1502 true, volume->allocatorContext(), false );
1503 volume->setRefVolume( parent );
1504 volume->setPosInRefVolume( top );
1505 }
1506 }
1507
1508 //==========================================================================
1509 //
1510 // OLD CLASSES / METHODS
1511 //
1512 //==========================================================================
1513 template <typename T> class VolumeRef;
1514
1515
1521 template <typename T, class BinaryFunction>
1523 {
1524 public:
1525 inline UnaryFromConstantBinaryFunctor( const T & x, BinaryFunction func )
1526 : value( x ), f( func ) {}
1527 inline T operator () ( const T & y ) const
1528 { return f( y, value ); }
1530 BinaryFunction f;
1531 };
1532
1533
1538 template <typename T, class BinaryFunction>
1540 {
1541 public:
1542 inline UnaryFromConstantBinaryFunctor2( const T & x, BinaryFunction func )
1543 : value( x ), f( func ) {}
1544 inline T operator () ( const T & y ) const
1545 { return f( value, y ); }
1547 BinaryFunction f;
1548 };
1549
1553 template <typename T, typename U>
1555 {
1556 public:
1557 inline Scaler( U x ) : scale( x ) {}
1558 inline T operator () ( const T & x ) const
1559 { return (T) ( x * scale ); }
1561 };
1562
1563 template<> inline cfloat
1565 {
1566 return x * (float) scale;
1567 }
1568
1569 template<> inline cfloat
1571 {
1572 return x * (float) scale;
1573 }
1574
1575 template<> inline cdouble
1577 {
1578 return x * (double) scale;
1579 }
1580
1581 template<> inline cdouble
1583 {
1584 return x * (double) scale;
1585 }
1586
1591 template <typename T, typename U>
1593 {
1594 public:
1595 inline Divider( U x ) : divisor( x ) {}
1596 inline T operator () ( const T & x ) const
1597 { return (T) ( x / divisor ); }
1599 };
1600
1601 template<> inline cfloat
1603 {
1604 return x * (float) ( 1. / divisor );
1605 }
1606
1607 template<> inline cfloat
1609 {
1610 return x * (float) ( 1. / (double) divisor );
1611 }
1612
1613 template<> inline cdouble
1615 {
1616 return x * ( 1. / divisor );
1617 }
1618
1619 template<> inline cdouble
1621 {
1622 return x * (double) ( 1. / divisor );
1623 }
1624
1625 template<> inline cdouble
1627 {
1628 return x * (double) ( 1. / divisor );
1629 }
1630
1631 template <typename T, bool Scalar>
1633 };
1634
1636 template <typename T>
1637 class VolumeUtilBase<T, true> {
1638 public :
1641 static T min( const Volume<T> & o );
1642
1645 static T max( const Volume<T> & o );
1646 };
1647
1649 template <typename T>
1650 class VolumeUtilBase<T, false> {
1651 };
1652
1654 template <typename T>
1655 class VolumeUtil: public carto::VolumeUtilBase<T, carto::DataTypeTraits<T>::is_scalar>
1656 {
1657 public:
1659 template <class UnaryFunction> static
1660 VolumeRef<T> apply( UnaryFunction f, const VolumeRef<T> & o );
1662// template <class BinaryFunction> static
1663// VolumeRef<T> apply( BinaryFunction f, const VolumeRef<T> & o1,
1664// const VolumeRef<T> & o2 );
1667 template <class UnaryFunction> static
1668 void selfApply( UnaryFunction f, VolumeRef<T> & o );
1671 template <class BinaryFunction> static
1672 void selfApply( BinaryFunction f, VolumeRef<T> & o1,
1673 const VolumeRef<T> & o2 );
1684 template <class BinaryFunction> static
1685 T accumulate( BinaryFunction f, const VolumeRef<T> & o2, T initial )
1686 { return accumulate( f, *o2, initial ); }
1687 template <class BinaryFunction> static
1688 T accumulate( BinaryFunction f, const Volume<T> & o2, T initial );
1689 };
1690
1691
1692 template <typename T>
1693 inline
1694 void sort( Volume<T>& thing, bool ascending = true )
1695 {
1696 int i, j, n = thing.getSizeX();
1697 T tmp;
1698
1699 if( ascending )
1700 {
1701 for( j=1; j<n; ++j )
1702 {
1703 tmp = thing.at( j );
1704 i = j - 1;
1705 while( i >= 0L && thing.at( i ) > tmp )
1706 {
1707 thing.at( i + 1 ) = thing.at( i );
1708 i--;
1709 }
1710 thing.at( i + 1 ) = tmp;
1711 }
1712 }
1713 else
1714 {
1715 for( j=1; j<n; ++j )
1716 {
1717 tmp = thing.at( j );
1718 i = j - 1;
1719 while( i >= 0L && thing.at( i ) < tmp )
1720 {
1721 thing.at( i + 1 ) = thing.at( i );
1722 i--;
1723 }
1724 thing.at( i + 1 ) = tmp;
1725 }
1726 }
1727 }
1728
1729
1730 template <typename T>
1731 inline
1732 void sort( rc_ptr<Volume<T> >& thing, bool ascending = true )
1733 {
1734 sort( *thing, ascending );
1735 }
1736
1737
1738} // namespace carto
1739
1740#endif // CARTODATA_VOLUME_VOLUMEUTIL_H
1741
T operator()(const T &x) const
const PropertySet & header() const
T operator()(const T &x) const
UnaryFromConstantBinaryFunctor2(const T &x, BinaryFunction func)
UnaryFromConstantBinaryFunctor(const T &x, BinaryFunction func)
int getSizeY() const
virtual void copyHeaderFrom(const PropertySet &other, bool stopOnError=true)
copy properties from other to this, avoiding forbidden properties like size.
int getSizeX() const
Definition volumeproxy.h:91
std::vector< int > getSize() const
get the 4 dimensions in a vector
int getSizeZ() const
int getSizeT() const
Convenient handle for a Volume - this is normally the entry point for all volumes handling.
Definition volumeref.h:60
Volume utilities classes.
static T accumulate(BinaryFunction f, const VolumeRef< T > &o2, T initial)
Apply a binary function to each voxel of the volume, with a "current" value as second argument.
static void selfApply(UnaryFunction f, VolumeRef< T > &o)
applies a binary function to each voxel of a pair of volumes
static VolumeRef< T > apply(UnaryFunction f, const VolumeRef< T > &o)
applies a unary function to each voxel of a volume
N-D Volume main class.
Definition volumebase.h:120
const AllocatorContext & allocatorContext() const
returns volume's AllocatorContext
void setPosInRefVolume(const Position4Di &pos)
Set position in parent volume.
const Position & posInRefVolume() const
Get position in parent volume.
void setRefVolume(const rc_ptr< Volume< T > > &refvol)
Set parent volume.
rc_ptr< Volume< T > > refVolume() const
Get parent volume.
std::vector< int > getBorders() const
Get borders for the volume.
std::vector< long > getStrides() const
Get strides for the volume.
const T & at(long x, long y=0, long z=0, long t=0) const
virtual void reallocate(int sizeX=1, int sizeY=1, int sizeZ=1, int sizeT=1, bool keepcontents=false, const AllocatorContext &allocatorContext=AllocatorContext(), bool allocate=true, const std::vector< long > *strides=0)
allows resizing and changing allocator
std::ptrdiff_t line_length() const
void inc_line_ptr(const T *&p) const
std::ptrdiff_t line_length() const
void inc_line_ptr(T *&p) const
void reset(T *p=NULL)
T * get() const
T * release()
Volume< OUTP > & applyTowards(const Volume< T > &vol, Volume< OUTP > &dst, UnaryFunction func)
Apply a function to all the elements of a volume (already allocated output version)
Definition volumeutil.h:604
OUTP accumulate(const Volume< T > &vol, BinaryFunction func, OUTP initial)
Accumulation over a volume.
Definition volumeutil.h:815
std::vector< int > minSize(const std::vector< int > &s1, const std::vector< int > &s2)
return the smallest dimensions between s1 and s2
Definition volumeutil.h:498
Volume< T > & selfApply(Volume< T > &vol, UnaryFunction func)
Apply a function to all the elements of a volume (in place version)
Definition volumeutil.h:568
std::vector< int > maxSize(const std::vector< int > &s1, const std::vector< int > &s2)
return the largest dimensions between s1 and s2
Definition volumeutil.h:480
Volume< typename UnaryFunction::result_type > apply(const Volume< T > &vol, UnaryFunction func)
Apply a function to all the elements of a volume (create output version)
Definition volumeutil.h:519
bool sameSize(const std::vector< int > &s1, const std::vector< int > &s2)
Used by the actual Volume and VolumeRef operators It allows to keep the loops in one place and to spe...
Definition volumeutil.h:461
bool any(const Volume< T > &vol)
Returns true if at least one value compares to true.
Volume< bool > valuesIn(const Volume< T > &volume, const U &set)
Find values contained in a set.
Volume< T > invertMinMax(const Volume< T > &volume)
Invert a volume between its min and max values.
bool isSameVolumeSize(const Volume< T > &v1, const Volume< T > &v2)
Definition volumeutil.h:421
rc_ptr< Volume< T > > undiag(const rc_ptr< Volume< T > > &thing)
Definition volumeutil.h:354
Volume< T > deepcopy(const Volume< T > &src, const std::vector< int > &size=std::vector< int >())
Performs a copy of the data (not only a reference copy) The whole view hierarchy is fully duplicated.
Definition volumeutil.h:878
void conditionalSet(Volume< T > &volume, const Volume< U > &condition, const T &value)
Conditionally fill a volume.
void transfer(const Volume< T > &src, Volume< T > &dst)
Transfer data from an allocated volume to another Allocated sizes must be equal (same number of voxel...
Definition volumeutil.h:848
Volume< T > copyStructure(const Volume< T > &src)
Performs a copy of the view structure without transfering the data.
Volume< T > copy(const Volume< T > &src)
Performs a copy of the data (not only a reference copy) Only the data inside the view is copied.
Definition volumeutil.h:994
T min(const Volume< T > &vol)
Returns the minimum value of the volume.
T max(const Volume< T > &vol)
Returns the maximum value of the volume.
DataTypeTraits< T >::LongType sum(const Volume< T > &vol)
Returns the sum of the volume values.
void sort(Volume< T > &thing, bool ascending=true)
VolumeRef< T > matrix_product(const Volume< T > &v1, const Volume< T > &v2)
matrix product
VolumeRef< T > transpose(const Volume< T > &v)
transpose
bool all(const Volume< T > &vol)
Returns true if all values compare to true.
void setBorders(Volume< T > &volume, const typename Volume< T >::Position4Di &top, const typename Volume< T >::Position4Di &bottom=typename Volume< T >::Position4Di(-1, -1, -1, -1))
Set border width.
void setMinBorders(Volume< T > &volume, const typename Volume< T >::Position4Di &top, const typename Volume< T >::Position4Di &bottom=typename Volume< T >::Position4Di(-1, -1, -1, -1))
Set border width.
Volume< bool > valuesNotIn(const Volume< T > &volume, const U &set)
Find values not contained in a set.
rc_ptr< Volume< T > > diag(const rc_ptr< Volume< T > > &thing)
Build a diagonal matrix from a line (1D) vector.
Definition volumeutil.h:335
bool operator()(const T &x, const U &y)
changeIf(const T &value)
bool operator()(const T &x, const U &y)
invMinMax(const T &min, const T &max)
bool operator()(const T &x, const U &y)
std::complex< double > cdouble
std::complex< float > cfloat