rheolef  6.3
form_concat.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_FORM_CONCAT_H
2 #define _RHEOLEF_FORM_CONCAT_H
3 #include "rheolef/form.h"
4 #include "rheolef/csr_concat.h"
5 
6 namespace rheolef {
7 
8 // A = {a, b}; // matrix & vector
9 template <class T, class M>
12  form_concat_value (const T& x) : s(x), v(), m(), variant(scalar) {}
13  form_concat_value (const form_basic<T,M>& x) : s(), v(), m(x), variant(form) {}
14 // io/debug:
15  friend std::ostream& operator<< (std::ostream& o, const form_concat_value<T,M>& x) {
16  if (x.variant == scalar) return o << "s";
17  else if (x.variant == field) return o << "f";
18  else if (x.variant == field_transpose) return o << "ft";
19  else return o << "m";
20  }
21 public:
22  T s;
26 };
27 template <class T, class M>
31  typedef typename std::list<value_type>::const_iterator const_iterator;
32  form_concat_line () : _l() {}
33 
34 #ifdef _RHEOLEF_HAVE_STD_INITIALIZER_LIST
35  form_concat_line (const std::initializer_list<value_type>& il) : _l() {
36 #ifdef _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
37  typedef typename std::initializer_list<value_type>::const_iterator const_iterator;
38 #else // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
39  typedef const value_type* const_iterator;
40 #endif // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
41  for(const_iterator iter = il.begin(); iter != il.end(); ++iter) {
42  _l.push_back(*iter);
43  }
44  }
45 #endif // _RHEOLEF_HAVE_STD_INITIALIZER_LIST
46 
47  const_iterator begin() const { return _l.begin(); }
48  const_iterator end() const { return _l.end(); }
49 
50  friend std::ostream& operator<< (std::ostream& o, const form_concat_line<T,M>& x) {
51  std::cout << "{";
52  for(typename std::list<value_type>::const_iterator iter = x._l.begin(); iter != x._l.end(); ++iter) {
53  std::cout << *iter << " ";
54  }
55  return std::cout << "}";
56  }
57 
58  void build_form_pass0 (std::vector<std::pair<bool,space_basic<T,M> > >& l_Xh, space_basic<T,M>& Yh, size_t i_comp = 0) const;
59  static void build_first_space (const std::vector<std::pair<bool,space_basic<T,M> > >& l_Xh, space_basic<T,M>& Xh);
62  form_basic<T,M> build_form () const;
63 
64 protected:
65  std::list<value_type> _l;
66 };
67 template <class T, class M>
68 void
69 form_concat_line<T,M>::build_form_pass0 (std::vector<std::pair<bool,space_basic<T,M> > >& l_Xh, space_basic<T,M>& Yh, size_t i_comp) const
70 {
71  size_t j_comp = 0;
72  bool have_Yh = false;
73  typename std::vector<std::pair<bool,space_basic<T,M> > >::iterator xh_iter = l_Xh.begin();
74  for (typename std::list<value_type>::const_iterator iter = _l.begin(); iter != _l.end(); ++iter, xh_iter++, j_comp++) {
75  const value_type& x = *iter;
76  switch (x.variant) {
78  check_macro (x.s == 0, "unsupported non-nul scalar `"<<x.s<<"' in form concatenation"
79  << " at ("<<i_comp<<","<<j_comp<<")");
80  break;
81  }
83  if (!(*xh_iter).first) {
84  (*xh_iter).first = true;
85  (*xh_iter).second = x.m.get_first_space();
86  } else {
87  check_macro (x.m.get_first_space() == (*xh_iter).second, "form initializer: invalid second space `"
88  << x.m.get_first_space().stamp() << "': expect `" << (*xh_iter).second.stamp() << "'"
89  << " at ("<<i_comp<<","<<j_comp<<")");
90  }
91  if (!have_Yh) {
92  have_Yh = true;
93  Yh = x.m.get_second_space();
94  } else {
95  check_macro (x.m.get_second_space() == Yh, "form initializer: invalid second space `"
96  << x.m.get_second_space().stamp() << "': expect `" << Yh.stamp() << "'"
97  << " at ("<<i_comp<<","<<j_comp<<")");
98  }
99  break;
100  }
101  default: error_macro ("non-form or scalar concatenation not yet supported"
102  << " at ("<<i_comp<<","<<j_comp<<")");
103  }
104  }
105  check_macro (have_Yh, "form concatenation: "<<i_comp<<"th row space remains undefined");
106 }
107 template <class T, class M>
108 void
110 {
111  space_mult_list<T,M> sml_X;
112  size_t j_comp = 0;
113  for (typename std::vector<std::pair<bool,space_basic<T,M> > >::const_iterator
114  xh_iter = l_Xh.begin(),
115  xh_last = l_Xh.end(); xh_iter != xh_last; xh_iter++, j_comp++) {
116  check_macro ((*xh_iter).first, "form concatenation: "<<j_comp<<"th column space remains undefined");
117  sml_X *= (*xh_iter).second;
118  }
119  Xh = space_basic<T,M>(sml_X);
120 }
121 template <class T, class M>
122 void
124 {
125  std::vector<std::pair<bool,space_basic<T,M> > > l_Xh (_l.size(), std::pair<bool,space_basic<T,M> >(false, space_basic<T,M>()));
126  build_form_pass0 (l_Xh, Yh);
127  build_first_space (l_Xh, Xh);
128 }
129 template <class T, class M>
132 {
133  form_basic<T,M> a (Xh, Yh);
134  csr_concat_line<T,M> uu, ub, bu, bb;
135  for(typename std::list<value_type>::const_iterator iter = _l.begin(); iter != _l.end(); ++iter) {
136  const value_type& x = *iter;
137  switch (x.variant) {
139  uu.push_back (x.m.uu());
140  ub.push_back (x.m.ub());
141  bu.push_back (x.m.bu());
142  bb.push_back (x.m.bb());
143  break;
144  }
145  default: error_macro ("non-form concatenation not yet supported");
146  }
147  }
148  a.set_uu() = uu.build_csr();
149  a.set_ub() = ub.build_csr();
150  a.set_bu() = bu.build_csr();
151  a.set_bb() = bb.build_csr();
152  return a;
153 }
154 template <class T, class M>
157 {
158  space_basic<T,M> Xh, Yh;
159  build_form_pass1 (Xh, Yh);
160  return build_form_pass2 (Xh, Yh);
161 }
162 #ifdef _RHEOLEF_HAVE_STD_INITIALIZER_LIST
163 template <class T, class M>
164 inline
165 form_basic<T,M>::form_basic (const std::initializer_list<form_concat_value<T,M> >& init_list)
166 {
167  form_concat_line<T,M> cc (init_list);
169 }
170 #endif // _RHEOLEF_HAVE_STD_INITIALIZER_LIST
171 template <class T, class M>
172 struct form_concat {
176  form_concat () : _l() {}
177 
178 #ifdef _RHEOLEF_HAVE_STD_INITIALIZER_LIST
179  form_concat (const std::initializer_list<line_type>& il) : _l() {
180 #ifdef _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
181  typedef typename std::initializer_list<line_type>::const_iterator const_iterator;
182 #else // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
183  typedef const line_type* const_iterator;
184 #endif // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
185  for(const_iterator iter = il.begin(); iter != il.end(); ++iter) {
186  _l.push_back(*iter);
187  }
188  }
189 #endif // _RHEOLEF_HAVE_STD_INITIALIZER_LIST
190 
191  friend std::ostream& operator<< (std::ostream& o, const form_concat<T,M>& x) {
192  std::cout << "{";
193  for(typename std::list<line_type>::const_iterator iter = x._l.begin(); iter != x._l.end(); ++iter) {
194  std::cout << *iter << " ";
195  }
196  return std::cout << "}";
197  }
198  form_basic<T,M> build_form () const;
199 
200 protected:
201  std::list<line_type> _l;
202 };
203 template <class T, class M>
206 {
207  size_t i_comp = 0;
208  space_mult_list<T,M> sml_Y;
209  std::vector<std::pair<bool,space_basic<T,M> > > l_Xh (_l.size(), std::pair<bool,space_basic<T,M> >(false, space_basic<T,M>()));
210  for (typename std::list<line_type>::const_iterator iter = _l.begin(); iter != _l.end(); ++iter, i_comp++) {
211  const line_type& line = *iter;
212  space_basic<T,M> Yih;
213  line.build_form_pass0 (l_Xh, Yih, i_comp);
214  sml_Y *= Yih;
215  }
216  space_basic<T,M> Xh;
218  space_basic<T,M> Yh (sml_Y);
219  csr_concat<T,M> uu, ub, bu, bb;
220  for (typename std::list<line_type>::const_iterator iter = _l.begin(); iter != _l.end(); ++iter) {
221  const line_type& line = *iter;
222  csr_concat_line<T,M> uu_i, ub_i, bu_i, bb_i;
223  for (typename std::list<value_type>::const_iterator jter = line.begin(); jter != line.end(); ++jter) {
224  const value_type& x = *jter;
225  switch (x.variant) {
227  check_macro (x.s == 0, "unsupported non-nul scalar `"<<x.s<<"' in form concatenation");
228  // zero: no values to insert in the sparse structure => nothing more to do
229  uu_i.push_back (x.s);
230  ub_i.push_back (x.s);
231  bu_i.push_back (x.s);
232  bb_i.push_back (x.s);
233  break;
234  }
236  uu_i.push_back (x.m.uu());
237  ub_i.push_back (x.m.ub());
238  bu_i.push_back (x.m.bu());
239  bb_i.push_back (x.m.bb());
240  break;
241  }
242  default: error_macro ("non-form or scalar concatenation not yet supported");
243  }
244  }
245  uu.push_back (uu_i);
246  ub.push_back (ub_i);
247  bu.push_back (bu_i);
248  bb.push_back (bb_i);
249  }
250  form_basic<T,M> a(Xh, Yh);
251  a.set_uu() = uu.build_csr();
252  a.set_ub() = ub.build_csr();
253  a.set_bu() = bu.build_csr();
254  a.set_bb() = bb.build_csr();
255  return a;
256 }
257 
258 #ifdef _RHEOLEF_HAVE_STD_INITIALIZER_LIST
259 template <class T, class M>
260 inline
261 form_basic<T,M>::form_basic (const std::initializer_list<form_concat_line<T,M> >& init_list)
262 {
263  form_concat<T,M> cc (init_list);
265 }
266 #endif // _RHEOLEF_HAVE_STD_INITIALIZER_LIST
267 
268 } // namespace rheolef
269 #endif // _RHEOLEF_FORM_CONCAT_H
270