Rheolef  7.1
an efficient C++ finite element environment
pair_set.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_PAIR_SET_H
2 #define _RHEOLEF_PAIR_SET_H
3 //
4 // This file is part of Rheolef.
5 //
6 // Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
7 //
8 // Rheolef is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // Rheolef is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with Rheolef; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 //
22 // =========================================================================
23 // same as index_set, but with a pair<size_t,T> instead of a size_t
24 // wrapper around map<size_t,T> with goodies such as union as a+b
25 //
26 // motivation: this class is useful for disarray<pair_set,M>
27 // to send/receive variable-sized lists via MPI correctly
28 // disarray<pair_set,M> is used by the asr class
29 // send & receive of such lists are used to assembly a global matrix locally
30 // when computing the csr*csr product
31 //
32 // author: Pierre.Saramito@imag.fr
33 //
34 // date: 19 mai 2012
35 //
36 #include "rheolef/distributed.h"
37 #include "rheolef/pretty_name.h"
38 #include "rheolef/container_traits.h"
39 #ifdef _RHEOLEF_HAVE_MPI
40 #include "rheolef/mpi_pair_datatype.h"
41 #endif // _RHEOLEF_HAVE_MPI
42 
43 #include <boost/serialization/map.hpp>
44 #include <boost/serialization/base_object.hpp>
45 
46 namespace rheolef {
47 
48 /*Class:
49 NAME: pair_set - a set of (index,value) pair (@PACKAGE@-@VERSION@)
50 SYNOPSIS:
51  A class for: l = @{(0,3.3),...(7,8.2)@} i.e. a wrapper for STL @code{map<size_t,T>} with
52  some assignment operators, such as l1 += l2.
53  This class is suitable for use with the @code{disarray<T>} class,
54  as @code{disarray<pair_set>} (@pxref{disarray class}).
55 TODO:
56  template <T,A> with A=std::allocator or heap_allocator
57  difficulty: get heap_allocator<T> or std::allocator<T> and then requires
58  heap_allocator<pair<size_t,T>> or std::allocator<>pair<size_t,T>>
59  for std::map
60 
61 AUTHOR: Pierre.Saramito@imag.fr
62 DATE: date: 19 may 2012
63 End:
64 */
65 //<verbatim:
66 template<class T, class A = std::allocator<std::pair<std::size_t,T> > >
67 class pair_set: public std::map<std::size_t, T, std::less<std::size_t> > {
68  // TODO: use A extra-arg for std::map for heap_allocator
69 public:
70 
71 // typedefs:
72 
73  typedef std::size_t size_type;
74  typedef std::pair<size_type,T> pair_type;
75  typedef std::pair<const size_type,T> const_pair_type;
77  typedef std::map<size_type, T, std::less<size_type> > // TODO: use allocator_type for heap_allocator
79 #ifdef TODO
80  typedef typename base::allocator_type allocator_type;
81 #endif // TODO
82  typedef A allocator_type;
83  typedef typename base::iterator iterator;
84  typedef typename base::const_iterator const_iterator;
85 
86 // allocators:
87 
88  pair_set (const A& alloc = A());
89  pair_set (const pair_set<T,A>& x, const A& alloc = A());
91  void clear ();
92 
93 // basic algebra: semantic of a sparse vector
94 
95  pair_set<T,A>& operator+= (const pair_type& x); // c := a union {x}
96  template<class B>
97  pair_set<T,A>& operator+= (const pair_set<T,B>& b); // c := a union b
98 
99 // boost mpi:
100 
101  template <class Archive>
102  void serialize (Archive& ar, const unsigned int version);
103 };
104 // io:
105 template <class T, class A>
106 std::istream& operator>> (std::istream& is, pair_set<T,A>& a);
107 template <class T, class A>
108 std::ostream& operator<< (std::ostream& os, const pair_set<T,A>& b);
109 //>verbatim:
110 
111 // operator += for disarray::assembly
112 template <class T>
113 struct pair_set_add_op : std::binary_function<T,T,T> {
114  T& operator()(T& x, const T& y) const { return x += y; }
115  T& operator()(T& x, const typename T::pair_type& y) const { return x += y; }
116  T& operator()(T& x, const typename T::const_pair_type& y) const { return x += y; }
117 };
118 // for boost mpi and disarray<pair_set>:
119 template <class T, class A>
120 struct default_set_op<pair_set<T,A> > {
122 };
123 template <class T, class A>
124 struct is_container<pair_set<T,A> > : std::true_type {
125  typedef std::true_type type;
126 };
127 #ifdef _RHEOLEF_HAVE_MPI
128 // convert boost::mpl::false_ and true_ to std::false_type and true_type...
129 template <class T, class A>
131  : std::conditional<
132  boost::mpi::is_mpi_datatype<T>::value
133  ,std::true_type
134  ,std::false_type
135  >::type
136 {
137  typedef
138  typename std::conditional<
139  boost::mpi::is_mpi_datatype<T>::value
140  ,std::true_type
141  ,std::false_type>
142  ::type
144 };
145 #endif // _RHEOLEF_HAVE_MPI
146 // -------------------------------------------------------------------
147 // inlined
148 // -------------------------------------------------------------------
149 template <class T, class A>
150 inline
151 pair_set<T,A>::pair_set (const A& alloc)
152  : base (std::less<size_type>()) // TODO: use alloc extra-arg for base=std::map for heap_allocator
153 {
154 }
155 template <class T, class A>
156 inline
157 void
159 {
160  base::clear();
161 }
162 template <class T, class A>
163 inline
166 {
167  iterator p = base::find(x.first);
168  if (p == base::end()) {
169  // insert a new element
170  base::insert (x);
171  } else {
172  // increment an existing element
173  (*p).second += x.second;
174  }
175  return *this;
176 }
177 template <class T, class A>
178 template <class Archive>
179 void
180 pair_set<T,A>::serialize (Archive& ar, const unsigned int version)
181 {
182  ar & boost::serialization::base_object<base>(*this);
183 }
184 // -------------------------------------------------------------------
185 // not inlined
186 // -------------------------------------------------------------------
187 template <class T, class A>
188 pair_set<T,A>::pair_set (const pair_set& a, const A& alloc)
189  : base(std::less<size_type>()) // TODO: use a.get_allocator() extra-arg for base=std::map for heap_allocator
190 {
191  for (const_iterator iter = a.base::begin(), last = a.base::end(); iter != last; iter++) {
192  base::insert (*iter);
193  }
194 }
195 template <class T, class A>
196 pair_set<T,A>&
198 {
199  base::clear();
200  for (const_iterator iter = a.base::begin(), last = a.base::end(); iter != last; iter++) {
201  base::insert (*iter);
202  }
203  return *this;
204 }
205 template <class T, class A>
206 template <class B>
209 {
210  for (typename pair_set<T,B>::const_iterator iter = b.begin(), last = b.end(); iter != last; iter++) {
211  operator+= (*iter);
212  }
213  return *this;
214 }
215 template <class T, class A>
216 std::istream&
217 operator>> (std::istream& is, pair_set<T,A>& a)
218 {
219  typedef typename pair_set<T,A>::size_type size_type;
220  typedef typename pair_set<T,A>::pair_type pair_type;
221  size_type n;
222  is >> n;
223  a.clear();
224  for (size_type i = 0; i < n; i++) {
225  pair_type xi;
226  is >> xi.first >> xi.second;
227  a.insert (xi);
228  }
229  return is;
230 }
231 template <class T, class A>
232 std::ostream&
233 operator<< (std::ostream& os, const pair_set<T,A>& a)
234 {
235  typedef typename pair_set<T,A>::size_type size_type;
237  os << a.size() << "\t";
238  for (const_iterator iter = a.begin(), last = a.end(); iter != last; iter++) {
239  os << " " << (*iter).first << " " << (*iter).second;
240  }
241  return os;
242 }
243 
244 } // namespace rheolef
245 #endif // _RHEOLEF_PAIR_SET_H
rheolef::pair_set::value_type
pair_type value_type
Definition: pair_set.h:76
rheolef::pair_set_add_op::operator()
T & operator()(T &x, const T &y) const
Definition: pair_set.h:114
rheolef::pair_set::iterator
base::iterator iterator
Definition: pair_set.h:83
rheolef::operator+=
std::enable_if< details::is_rheolef_arithmetic< U >::value,ad3_basic< T > & >::type operator+=(ad3_basic< T > &a, const U &b)
Definition: ad3.h:286
rheolef::pair_set_add_op
Definition: pair_set.h:113
rheolef::pair_set::clear
void clear()
Definition: pair_set.h:158
rheolef-config.version
version
Definition: rheolef-config.in:126
rheolef::pair_set::pair_type
std::pair< size_type, T > pair_type
Definition: pair_set.h:74
rheolef::size_type
size_t size_type
Definition: basis_get.cc:76
rheolef::pair_set::base
std::map< size_type, T, std::less< size_type > > base
Definition: pair_set.h:78
p
Definition: sphere.icc:25
rheolef::pair_set::allocator_type
base::allocator_type allocator_type
Definition: pair_set.h:80
rheolef::pair_set::pair_set
pair_set(const A &alloc=A())
Definition: pair_set.h:151
rheolef::pair_set
Definition: pair_set.h:67
rheolef::pair_set_add_op::operator()
T & operator()(T &x, const typename T::const_pair_type &y) const
Definition: pair_set.h:116
a
Definition: diffusion_isotropic.h:25
rheolef::default_set_op< pair_set< T, A > >::type
pair_set_add_op< pair_set< T, A > > type
Definition: pair_set.h:121
rheolef::is_container_of_mpi_datatype< pair_set< T, A > >::type
std::conditional< boost::mpi::is_mpi_datatype< T >::value,std::true_type,std::false_type >::type type
Definition: pair_set.h:143
rheolef::pair_set::const_pair_type
std::pair< const size_type, T > const_pair_type
Definition: pair_set.h:75
rheolef::operator>>
std::istream & operator>>(std::istream &is, const catchmark &m)
Definition: catchmark.h:88
rheolef
This file is part of Rheolef.
Definition: compiler_eigen.h:37
rheolef::default_set_op
Definition: container_traits.h:36
rheolef::pair_set::const_iterator
base::const_iterator const_iterator
Definition: pair_set.h:84
mkgeo_ball.b
b
Definition: mkgeo_ball.sh:152
rheolef::pair_set::allocator_type
A allocator_type
Definition: pair_set.h:82
rheolef::const_iterator
Definition: field_expr_recursive.h:552
mkgeo_ball.n
n
Definition: mkgeo_ball.sh:150
rheolef::pair_set_add_op::operator()
T & operator()(T &x, const typename T::pair_type &y) const
Definition: pair_set.h:115
size_type
field::size_type size_type
Definition: branch.cc:425
rheolef::is_container_of_mpi_datatype
Definition: container_traits.h:45
rheolef::pair_set::operator=
pair_set< T, A > & operator=(const pair_set< T, A > &x)
Definition: pair_set.h:197
rheolef::pair_set::operator+=
pair_set< T, A > & operator+=(const pair_type &x)
Definition: pair_set.h:165
rheolef::pair_set::serialize
void serialize(Archive &ar, const unsigned int version)
Definition: pair_set.h:180
rheolef::pair_set::size_type
std::size_t size_type
Definition: pair_set.h:73
rheolef::operator<<
std::ostream & operator<<(std::ostream &os, const catchmark &m)
Definition: catchmark.h:99
rheolef::is_container
Definition: container_traits.h:40
rheolef::std
Definition: vec_expr_v2.h:391
rheolef::is_container< pair_set< T, A > >::type
std::true_type type
Definition: pair_set.h:125
T
Expr1::float_type T
Definition: field_expr.h:218