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