1 # ifndef CPPAD_LOCAL_SPARSE_PACK_SETVEC_HPP
2 # define CPPAD_LOCAL_SPARSE_PACK_SETVEC_HPP
3 /* --------------------------------------------------------------------------
4 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell
5 
6 CppAD is distributed under the terms of the
7              Eclipse Public License Version 2.0.
8 
9 This Source Code may also be made available under the following
10 Secondary License when the conditions for such availability set forth
11 in the Eclipse Public License, Version 2.0 are satisfied:
12       GNU General Public License, Version 2.0 or later.
13 ---------------------------------------------------------------------------- */
14 # include <cppad/core/cppad_assert.hpp>
15 # include <cppad/local/pod_vector.hpp>
16 
17 // BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE
18 namespace CppAD { namespace local { namespace sparse {
19 
20 // forward declaration of iterator class
21 class pack_setvec_const_iterator;
22 
23 // ============================================================================
24 class pack_setvec {
25 // ============================================================================
26 /*
27 $begin pack_setvec_member_data$$
28 $spell
29     setvec
30     resize
31 $$
32 
33 $section class pack_setvec: Private Member Data$$
34 
35 $head Pack$$
36 Type used to pack multiple elements of a set (multiple bits) onto one
37 $icode Pack$$ value.
38 
39 $head n_bit_$$
40 Number of bits (elements) per $icode Pack$$ value.
41 
42 $head zero_$$
43 The $icode Pack$$ value with all bits zero.
44 
45 $head one_$$
46 The $icode Pack$$ value with all bits zero, except for the lowest order bit.
47 
48 $head n_set_$$
49 Number of sets that we are representing.
50 
51 $head end_$$
52 The possible elements in each set are $code 0$$, $code 1$$, ...,
53 $code end_-1$$.
54 
55 $head n_pack_$$
56 Number of Pack values used to represent one set in the vector; i.e.,
57 to represent $code end_$$ bits.
58 
59 $head data_$$
60 Data for all of the sets.
61 
62 $head Source Code$$
63 $srccode%hpp% */
64 private:
65     typedef size_t    Pack;
66     const size_t      n_bit_;
67     const Pack        zero_;
68     const Pack        one_;
69     size_t            n_set_;
70     size_t            end_;
71     size_t            n_pack_;
72     pod_vector<Pack>  data_;
73 /* %$$
74 $end
75 -----------------------------------------------------------------------------
76 $begin pack_setvec_vec_memory$$
77 $spell
78     setvec
79 $$
80 
81 $section class pack_setvec: Approximate Memory Used by Vector$$
82 
83 $head Public$$
84 This function is declared public, but is not part of
85 $cref SetVector$$ concept.
86 
87 $head Implementation$$
88 $srccode%hpp% */
89 public:
memory(void) const90     size_t memory(void) const
91     {   return data_.capacity() * sizeof(Pack); }
92 /* %$$
93 $end
94 -------------------------------------------------------------------------------
95 $begin pack_setvec_vec_print$$
96 $spell
97     setvec
98 $$
99 
100 $section class pack_setvec: Print a Vector of Sets$$
101 
102 
103 $head Public$$
104 This function is declared public, but is not part of
105 $cref SetVector$$ concept.
106 
107 $head Prototype$$
108 $srccode%hpp% */
109 public:
110     void print(void) const;
111 /* %$$
112 $end
113 -------------------------------------------------------------------------------
114 $begin pack_setvec_iterators$$
115 $spell
116     setvec
117     Iterators
118     typedef
119     const_iterator
120 $$
121 
122 $section class pack_setvec: Iterators$$
123 
124 $head SetVector Concept$$
125 $cref/const_iterator/SetVector/const_iterator/$$
126 
127 $head typedef$$
128 $srccode%hpp% */
129 public:
130     /// declare a const iterator
131     friend class pack_setvec_const_iterator;
132     typedef pack_setvec_const_iterator const_iterator;
133 /* %$$
134 $end
135 -------------------------------------------------------------------------------
136 $begin pack_setvec_default_ctor$$
137 $spell
138     setvec
139 $$
140 
141 $section class pack_setvec: Default Constructor$$
142 
143 $head SetVector Concept$$
144 $cref/constructor/SetVector/Vector Operations/Constructor/$$
145 
146 $head n_bit_$$
147 This member variable is set to the number of bits in a $icode Pack$$ value.
148 
149 $head one_$$
150 This member variable has only its lowest order bit non-zero;
151 
152 $head data_$$
153 This member is initialized as the empty vector; i.e., size zero..
154 
155 $head Other$$
156 All the other member data are $code size_t$$ values
157 that are initialized as zero.
158 
159 $head Implementation$$
160 $srccode%hpp% */
161 public:
pack_setvec(void)162     pack_setvec(void) :
163     n_bit_( std::numeric_limits<Pack>::digits ),
164     zero_(0), one_(1), n_set_(0), end_(0), n_pack_(0), data_(0)
165     { }
166 /* %$$
167 $end
168 -------------------------------------------------------------------------------
169 $begin pack_setvec_destructor$$
170 $spell
171     setvec
172 $$
173 
174 $section class pack_setvec: Destructor$$
175 
176 $head Implementation$$
177 $srccode%hpp% */
178 public:
~pack_setvec(void)179     ~pack_setvec(void)
180     { }
181 /* %$$
182 $end
183 -------------------------------------------------------------------------------
184 $begin pack_setvec_copy_ctor$$
185 $spell
186     setvec
187     CppAD
188 $$
189 
190 $section class pack_setvec: Copy Constructor$$
191 
192 $head v$$
193 The vector of sets that we are attempting to make a copy of.
194 
195 $head Implementation$$
196 Using the copy constructor is probably due to a $code pack_setvec$$
197 being passed by value instead of by reference.
198 This is a CppAD programing error (not CppAD user error).
199 $srccode%hpp% */
200 public:
pack_setvec(const pack_setvec & v)201     pack_setvec(const pack_setvec& v) :
202     n_bit_( std::numeric_limits<Pack>::digits ), zero_(0), one_(1)
203     {   CPPAD_ASSERT_UNKNOWN(0); }
204 /* %$$
205 $end
206 -------------------------------------------------------------------------------
207 $begin pack_setvec_vec_resize$$
208 $spell
209     setvec
210     resize
211 $$
212 
213 $section class pack_setvec: Vector resize$$
214 
215 $head SetVector Concept$$
216 $cref/vector resize/SetVector/Vector Operations/resize/$$
217 
218 $head Prototype$$
219 $srccode%hpp% */
220 public:
resize(size_t n_set,size_t end)221     void resize(size_t n_set, size_t end)
222 /* %$$
223 $end
224 */
225     {   n_set_          = n_set;
226         end_            = end;
227         if( n_set_ == 0 )
228         {   CPPAD_ASSERT_UNKNOWN( end == 0 );
229             data_.clear();
230             return;
231         }
232         // now start a new vector with empty sets
233         Pack zero(0);
234         //
235         n_pack_         = ( 1 + (end_ - 1) / n_bit_ );
236         size_t i        = n_set_ * n_pack_;
237         //
238         data_.resize(i);
239         while(i--)
240             data_[i] = zero;
241     }
242 /* %$$
243 -------------------------------------------------------------------------------
244 $begin pack_setvec_vec_n_set$$
245 $spell
246     setvec
247 $$
248 
249 $section class pack_setvec: Number of Sets$$
250 
251 $head SetVector Concept$$
252 $cref/n_set/SetVector/Vector Operations/n_set/$$
253 
254 $head Implementation$$
255 $srccode%hpp% */
256 public:
n_set(void) const257     size_t n_set(void) const
258     {   return n_set_;  }
259 /* %$$
260 $end
261 -------------------------------------------------------------------------------
262 $begin pack_setvec_vec_end$$
263 $spell
264     setvec
265 $$
266 
267 $section class pack_setvec: End Value$$
268 
269 $head SetVector Concept$$
270 $cref/end/SetVector/Vector Operations/end/$$
271 
272 $head Implementation$$
273 $srccode%hpp% */
274 public:
end(void) const275     size_t end(void) const
276     {   return end_; }
277 /* %$$
278 $end
279 -------------------------------------------------------------------------------
280 $begin pack_setvec_vec_assignment$$
281 $spell
282     setvec
283 $$
284 
285 $section class pack_setvec: Vector Assignment$$
286 
287 $head SetVector Concept$$
288 $cref/vector assignment/SetVector/Vector Operations/Assignment/$$
289 
290 $head Prototype$$
291 $srccode%hpp% */
292 public:
operator =(const pack_setvec & other)293     void operator=(const pack_setvec& other)
294 /* %$$
295 $end
296 */
297     {   CPPAD_ASSERT_UNKNOWN( n_bit_  == other.n_bit_);
298         CPPAD_ASSERT_UNKNOWN( zero_   == other.zero_);
299         CPPAD_ASSERT_UNKNOWN( one_    == other.one_);
300         n_set_  = other.n_set_;
301         end_    = other.end_;
302         n_pack_ = other.n_pack_;
303         data_   = other.data_;
304     }
305 /*
306 -------------------------------------------------------------------------------
307 $begin pack_setvec_vec_swap$$
308 $spell
309     setvec
310 $$
311 
312 $section class pack_setvec: Vector Swap$$
313 
314 $head SetVector Concept$$
315 $cref/vector swap/SetVector/Vector Operations/swap/$$
316 
317 $head Prototype$$
318 $srccode%hpp% */
319 public:
swap(pack_setvec & other)320     void swap(pack_setvec& other)
321 /* %$$
322 $end
323 */
324     {   // size_t objects
325         CPPAD_ASSERT_UNKNOWN( n_bit_  == other.n_bit_);
326         CPPAD_ASSERT_UNKNOWN( zero_   == other.zero_);
327         CPPAD_ASSERT_UNKNOWN( one_    == other.one_);
328         std::swap(n_set_  , other.n_set_);
329         std::swap(end_    , other.end_);
330         std::swap(n_pack_ , other.n_pack_);
331         //
332         // pod_vectors
333         data_.swap(other.data_);
334     }
335 /*
336 -------------------------------------------------------------------------------
337 $begin pack_setvec_number_elements$$
338 $spell
339     setvec
340 $$
341 
342 $section class pack_setvec: Number of Elements in a Set$$
343 
344 $head SetVector Concept$$
345 $cref/number_elements/SetVector/number_elements/$$
346 
347 $head Prototype$$
348 $srccode%hpp% */
349 public:
number_elements(size_t i) const350     size_t number_elements(size_t i) const
351 /* %$$
352 $end
353 */
354     {   CPPAD_ASSERT_UNKNOWN( i < n_set_ );
355         //
356         // special case where data_[i] is 0 or 1
357         if( end_ == 1 )
358         {   CPPAD_ASSERT_UNKNOWN( n_pack_ == 1 );
359             return size_t( data_[i] );
360         }
361         //
362         // initialize count of non-zero bits in this set
363         size_t count = 0;
364         //
365         // mask corresonding to first bit in Pack
366         Pack mask = one_;
367         //
368         // number of bits in last Packing unit
369         size_t n_last = (end_ - 1) % n_bit_ + 1;
370         //
371         // count bits in last unit
372         Pack unit = data_[(i + 1) * n_pack_ - 1];
373         for(size_t bit = 0; bit < n_last; ++bit)
374         {   CPPAD_ASSERT_UNKNOWN( mask >= one_ );
375             if( mask & unit )
376                 ++count;
377             mask = mask << 1;
378         }
379         if( n_pack_ == 1 )
380             return count;
381         //
382         // count bits in other units
383         for(size_t bit = 0; bit < n_bit_; ++bit)
384         {   CPPAD_ASSERT_UNKNOWN( mask >= one_ );
385             size_t k = n_pack_;
386             while(--k)
387             {   if( data_[i * n_pack_ + k] & mask )
388                     ++count;
389             }
390             mask = mask << 1;
391         }
392         return count;
393     }
394 /*
395 -------------------------------------------------------------------------------
396 $begin pack_setvec_add_element$$
397 $spell
398     setvec
399 $$
400 
401 $section class pack_setvec: Add an Elements to a Set$$
402 
403 $head SetVector Concept$$
404 $cref/add_element/SetVector/add_element/$$
405 
406 $head Prototype$$
407 $srccode%hpp% */
408 public:
add_element(size_t i,size_t element)409     void add_element(size_t i, size_t element)
410 /* %$$
411 $end
412 */
413     {   CPPAD_ASSERT_UNKNOWN( i   < n_set_ );
414         CPPAD_ASSERT_UNKNOWN( element < end_ );
415         if( end_ == 1 )
416             data_[i] |= one_;
417         else
418         {   size_t j  = element / n_bit_;
419             size_t k  = element - j * n_bit_;
420             Pack mask = one_ << k;
421             data_[ i * n_pack_ + j] |= mask;
422         }
423     }
424 /*
425 -------------------------------------------------------------------------------
426 $begin pack_setvec_post_element$$
427 $spell
428     setvec
429 $$
430 
431 $section class pack_setvec: Add an Elements to a Set$$
432 
433 $head SetVector Concept$$
434 $cref/post_element/SetVector/post_element/$$
435 
436 $head Implementation$$
437 $srccode%hpp% */
438 public:
post_element(size_t i,size_t element)439     void post_element(size_t i, size_t element)
440     {   add_element(i, element); }
441 /* %$$
442 $end
443 */
444 /*
445 -------------------------------------------------------------------------------
446 $begin pack_setvec_process_post$$
447 $spell
448     setvec
449 $$
450 
451 $section class pack_setvec: Add Posted Elements to a Set$$
452 
453 $head SetVector Concept$$
454 $cref/process_post/SetVector/process_post/$$
455 
456 $head Implementation$$
457 $srccode%hpp% */
458 public:
process_post(size_t i)459     void process_post(size_t i)
460     {   return; }
461 /* %$$
462 $end
463 -------------------------------------------------------------------------------
464 $begin pack_setvec_is_element$$
465 $spell
466     setvec
467 $$
468 
469 $section class pack_setvec: Is an Element in a Set$$
470 
471 $head SetVector Concept$$
472 $cref/is_element/SetVector/is_element/$$
473 
474 $head Prototype$$
475 $srccode%hpp% */
476 public:
is_element(size_t i,size_t element) const477     bool is_element(size_t i, size_t element) const
478 /* %$$
479 $end
480 */
481     {   CPPAD_ASSERT_UNKNOWN( i   < n_set_ );
482         CPPAD_ASSERT_UNKNOWN( element < end_ );
483         if( end_ == 1 )
484             return data_[i] != zero_;
485         //
486         size_t j  = element / n_bit_;
487         size_t k  = element - j * n_bit_;
488         Pack mask = one_ << k;
489         return (data_[i * n_pack_ + j] & mask) != zero_;
490     }
491 /*
492 -------------------------------------------------------------------------------
493 $begin pack_setvec_clear$$
494 $spell
495     setvec
496 $$
497 
498 $section class pack_setvec: Assign a Set to be Empty$$
499 
500 $head SetVector Concept$$
501 $cref/clear/SetVector/clear/$$
502 
503 $head Prototype$$
504 $srccode%hpp% */
505 public:
clear(size_t target)506     void clear(size_t target)
507 /* %$$
508 $end
509 */
510     {   CPPAD_ASSERT_UNKNOWN( target < n_set_ );
511         size_t t = target * n_pack_;
512 
513         size_t j = n_pack_;
514         while(j--)
515             data_[t++] = zero_;
516     }
517 /*
518 -------------------------------------------------------------------------------
519 $begin pack_setvec_assignment$$
520 $spell
521     setvec
522 $$
523 
524 $section class pack_setvec: Assign a Set To Equal Another Set$$
525 
526 $head SetVector Concept$$
527 $cref/assignment/SetVector/assignment/$$
528 
529 $head Prototype$$
530 $srccode%hpp% */
531 public:
assignment(size_t this_target,size_t other_value,const pack_setvec & other)532     void assignment(
533         size_t               this_target  ,
534         size_t               other_value  ,
535         const pack_setvec&   other        )
536 /* %$$
537 $end
538 */
539     {   CPPAD_ASSERT_UNKNOWN( this_target  <   n_set_        );
540         CPPAD_ASSERT_UNKNOWN( other_value  <   other.n_set_  );
541         CPPAD_ASSERT_UNKNOWN( n_pack_      ==  other.n_pack_ );
542         size_t t = this_target * n_pack_;
543         size_t v = other_value * n_pack_;
544 
545         size_t j = n_pack_;
546         while(j--)
547             data_[t++] = other.data_[v++];
548     }
549 /*
550 -------------------------------------------------------------------------------
551 $begin pack_setvec_binary_union$$
552 $spell
553     setvec
554 $$
555 
556 $section class pack_setvec: Assign a Set To Equal Union of Two Sets$$
557 
558 $head SetVector Concept$$
559 $cref/binary_union/SetVector/binary_union/$$
560 
561 $head Prototype$$
562 $srccode%hpp% */
563 public:
binary_union(size_t this_target,size_t this_left,size_t other_right,const pack_setvec & other)564     void binary_union(
565         size_t                  this_target  ,
566         size_t                  this_left    ,
567         size_t                  other_right  ,
568         const pack_setvec&      other        )
569 /* %$$
570 $end
571 */
572     {   CPPAD_ASSERT_UNKNOWN( this_target < n_set_         );
573         CPPAD_ASSERT_UNKNOWN( this_left   < n_set_         );
574         CPPAD_ASSERT_UNKNOWN( other_right < other.n_set_   );
575         CPPAD_ASSERT_UNKNOWN( n_pack_    ==  other.n_pack_ );
576 
577         size_t t  = this_target * n_pack_;
578         size_t l  = this_left  * n_pack_;
579         size_t r  = other_right * n_pack_;
580 
581         size_t j = n_pack_;
582         while(j--)
583             data_[t++] = ( data_[l++] | other.data_[r++] );
584     }
585 /*
586 -------------------------------------------------------------------------------
587 $begin pack_setvec_binary_intersection$$
588 $spell
589     setvec
590 $$
591 
592 $section class pack_setvec: Assign a Set To Intersection of Two Sets$$
593 
594 $head SetVector Concept$$
595 $cref/binary_intersection/SetVector/binary_intersection/$$
596 
597 $head Prototype$$
598 $srccode%hpp% */
599 public:
binary_intersection(size_t this_target,size_t this_left,size_t other_right,const pack_setvec & other)600     void binary_intersection(
601         size_t                  this_target  ,
602         size_t                  this_left    ,
603         size_t                  other_right  ,
604         const pack_setvec&      other        )
605 /* %$$
606 $end
607 */
608     {   CPPAD_ASSERT_UNKNOWN( this_target < n_set_         );
609         CPPAD_ASSERT_UNKNOWN( this_left   < n_set_         );
610         CPPAD_ASSERT_UNKNOWN( other_right < other.n_set_   );
611         CPPAD_ASSERT_UNKNOWN( n_pack_    ==  other.n_pack_ );
612 
613         size_t t  = this_target * n_pack_;
614         size_t l  = this_left  * n_pack_;
615         size_t r  = other_right * n_pack_;
616 
617         size_t j = n_pack_;
618         while(j--)
619             data_[t++] = ( data_[l++] & other.data_[r++] );
620     }
621 // ==========================================================================
622 }; // END_CLASS_PACK_SETVEC
623 // ==========================================================================
624 
625 
626 // =========================================================================
627 class pack_setvec_const_iterator { // BEGIN_CLASS_PACK_SETVEC_CONST_ITERATOR
628 // =========================================================================
629 
630 /*
631 $begin pack_setvec_const_iterator_member_data$$
632 $spell
633     setvec
634     const_iterator
635 $$
636 
637 $section class pack_setvec_const_iterator private: Member Data$$
638 
639 $head Pack$$
640 This is the same type as
641 $cref/pack_setvec Pack/pack_setvec_member_data/Pack/$$.
642 
643 $head n_bit_$$
644 This is a reference to
645 $cref/pack_setvec n_bit_/pack_setvec_member_data/n_bit_/$$.
646 
647 $head one_$$
648 This is a reference to
649 $cref/pack_setvec one_/pack_setvec_member_data/one_/$$.
650 
651 $head n_pack_$$
652 This is a reference to
653 $cref/pack_setvec n_pack_/pack_setvec_member_data/n_pack_/$$.
654 
655 $head end_$$
656 This is a reference to
657 $cref/pack_setvec end_/pack_setvec_member_data/end_/$$.
658 
659 $head data_$$
660 This is a reference to
661 $cref/pack_setvec data_/pack_setvec_member_data/data_/$$.
662 
663 $head data_index_$$
664 Index in $code data_$$ where the next element is located.
665 
666 $head next_element$$
667 Value of the next element in this set
668 If $code next_element_$$ equals $code end_$$,
669 no next element exists; i.e., past end of the set.
670 
671 $head Source Code$$
672 $srccode%hpp% */
673 private:
674     typedef pack_setvec::Pack Pack;
675     const size_t&             n_bit_;
676     const Pack&               one_;
677     const size_t&             n_pack_;
678     const size_t&             end_;
679     const pod_vector<Pack>&   data_;
680     size_t                    data_index_;
681     size_t                    next_element_;
682 public:
683 /* %$$
684 $end
685 -------------------------------------------------------------------------------
686 $begin pack_setvec_const_iterator_ctor$$
687 $spell
688     setvec
689     const_iterator
690 $$
691 
692 $section class pack_setvec_const_iterator: Constructor$$
693 
694 $head SetVector Concept$$
695 $cref/iterator constructor/SetVector/const_iterator/Constructor/$$
696 
697 $head Prototype$$
698 $srccode%hpp% */
699 public:
pack_setvec_const_iterator(const pack_setvec & pack,size_t set_index)700     pack_setvec_const_iterator (const pack_setvec& pack, size_t set_index)
701 /* %$$
702 $end
703 */
704     :
705     n_bit_         ( pack.n_bit_ )        ,
706     one_           ( pack.one_   )        ,
707     n_pack_        ( pack.n_pack_ )       ,
708     end_           ( pack.end_ )          ,
709     data_          ( pack.data_ )         ,
710     data_index_    ( set_index * n_pack_ )
711     {   CPPAD_ASSERT_UNKNOWN( set_index < pack.n_set_ );
712         CPPAD_ASSERT_UNKNOWN( 0 < end_ );
713         //
714         next_element_ = 0;
715         if( data_[data_index_] & one_ )
716             return;
717         //
718         // element with index zero is not in this set of integers,
719         // advance to first element or end
720         ++(*this);
721     }
722 /*
723 -------------------------------------------------------------------------------
724 $begin pack_setvec_const_iterator_dereference$$
725 $spell
726     setvec
727     const_iterator
728     Dereference
729 $$
730 
731 $section class pack_setvec_const_iterator: Dereference$$
732 
733 $head SetVector Concept$$
734 $cref/iterator deference/SetVector/const_iterator/Dereference/$$
735 
736 $head Implementation$$
737 $srccode%hpp% */
operator *(void) const738     size_t operator*(void) const
739     {   return next_element_; }
740 /* %$$
741 $end
742 -------------------------------------------------------------------------------
743 $begin pack_setvec_const_iterator_increment$$
744 $spell
745     setvec
746     const_iterator
747 $$
748 
749 $section class pack_setvec_const_iterator: Increment$$
750 
751 $head SetVector Concept$$
752 $cref/iterator increment/SetVector/const_iterator/Increment/$$
753 
754 $head Prototype$$
755 $srccode%hpp% */
756 public:
operator ++(void)757     pack_setvec_const_iterator& operator++(void)
758 /* %$$
759 $end
760 */
761     {   CPPAD_ASSERT_UNKNOWN( next_element_ <= end_ );
762         if( next_element_ == end_ )
763             return *this;
764         //
765         ++next_element_;
766         if( next_element_ == end_ )
767             return *this;
768         //
769         // bit index corresponding to next element
770         size_t bit = next_element_ % n_bit_;
771         //
772         // check if we have advanced to the next data index
773         if( bit == 0 )
774             ++data_index_;
775         //
776         // initialize mask
777         size_t mask = one_ << bit;
778         //
779         while( next_element_ < end_ )
780         {   // check if this element is in the set
781             if( data_[data_index_] & mask )
782                 return *this;
783             //
784             // try next larger element
785             ++next_element_;
786             ++bit;
787             mask <<= 1;
788             //
789             // check if we must go to next packed data index
790             CPPAD_ASSERT_UNKNOWN( bit <= n_bit_ );
791             if( bit == n_bit_ )
792             {   // get next packed value
793                 bit   = 0;
794                 mask  = one_;
795                 ++data_index_;
796             }
797         }
798         CPPAD_ASSERT_UNKNOWN( next_element_ == end_ );
799         return *this;
800     }
801 // =========================================================================
802 }; // END_CLASS_PACK_SETVEC_CONST_ITERATOR
803 // =========================================================================
804 
805 // Implemented after pack_setvec_const_iterator so can use it
print(void) const806 inline void pack_setvec::print(void) const
807 {   std::cout << "pack_setvec:\n";
808     for(size_t i = 0; i < n_set(); i++)
809     {   std::cout << "set[" << i << "] = {";
810         const_iterator itr(*this, i);
811         while( *itr != end() )
812         {   std::cout << *itr;
813             if( *(++itr) != end() )
814                 std::cout << ",";
815         }
816         std::cout << "}\n";
817     }
818     return;
819 }
820 
821 // ----------------------------------------------------------------------------
822 /*
823 $begin sparsity_user2internal_pack_setvec$$
824 $spell
825     setvec
826     bool
827 $$
828 
829 $section Copy A Boolean Sparsity Pattern To A pack_setvec Object$$
830 
831 $head SetVector$$
832 is a $cref/simple vector/SimpleVector/$$ type with elements of type
833 $code bool$$ containing the input sparsity pattern.
834 
835 $head  internal$$
836 The input value of this object does not matter.
837 Upon return it contains the same sparsity pattern as $icode user$$
838 (or its transpose).
839 
840 $head user$$
841 is the sparsity pattern we are copying to $icode internal$$.
842 
843 $head  n_set$$
844 is the number of sets in the output sparsity pattern $icode internal$$.
845 
846 $head end$$
847 is the end value for the output sparsity pattern $icode internal$$.
848 
849 $head transpose$$
850 If $icode transpose$$ is false,
851 element $icode j$$ is in the $th i$$ $icode internal$$ set if
852 $codei%
853     %user%[ %i% * %end% + %j% ]
854 %$$
855 Otherwise,
856 element $icode j$$ is in the $th i$$ $icode internal$$ set if
857 $codei%
858     %user%[ %i% * %n_set% + %j% ]
859 %$$
860 
861 $head error_msg$$
862 is the error message to display if
863 $codei%
864     %n_set% * %end% != %user%.size()
865 %$$
866 
867 $head Prototype$$
868 $srccode%hpp% */
869 template<class SetVector>
sparsity_user2internal(pack_setvec & internal,const SetVector & user,size_t n_set,size_t end,bool transpose,const char * error_msg)870 void sparsity_user2internal(
871     pack_setvec&            internal  ,
872     const SetVector&        user      ,
873     size_t                  n_set     ,
874     size_t                  end       ,
875     bool                    transpose ,
876     const char*             error_msg )
877 /* %$$
878 $end
879 */
880 {   CPPAD_ASSERT_KNOWN(size_t( user.size() ) == n_set * end, error_msg );
881 
882     // size of internal sparsity pattern
883     internal.resize(n_set, end);
884 
885     if( transpose )
886     {   // transposed pattern case
887         for(size_t j = 0; j < end; j++)
888         {   for(size_t i = 0; i < n_set; i++)
889             {   // no advantage to using post_element for pack_setvec
890                 if( user[ j * n_set + i ] )
891                     internal.add_element(i, j);
892             }
893         }
894         return;
895     }
896     else
897     {   for(size_t i = 0; i < n_set; i++)
898         {   for(size_t j = 0; j < end; j++)
899             {   // no advantage to using post_element for pack_setvec
900                 if( user[ i * end + j ] )
901                     internal.add_element(i, j);
902             }
903         }
904     }
905     return;
906 }
907 
908 } } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE
909 
910 # endif
911