TiledArray  0.7.0
variable_list.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2013 Virginia Tech
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #ifndef TILEDARRAY_EXPRESSIONS_VARIABLE_LIST_H__INCLUDED
21 #define TILEDARRAY_EXPRESSIONS_VARIABLE_LIST_H__INCLUDED
22 
23 #include <TiledArray/permutation.h>
24 #include <string>
25 #include <algorithm>
26 #include <iosfwd>
27 
28 namespace TiledArray {
29  namespace expressions {
30 
31  class VariableList;
32  VariableList operator *(const ::TiledArray::Permutation&, const VariableList&);
33  void swap(VariableList&, VariableList&);
34 
35 
36  namespace detail {
38 
63  template<typename InIter1, typename InIter2>
64  void find_common(InIter1 first1, const InIter1 last1, InIter2 first2, const InIter2 last2,
65  std::pair<InIter1, InIter1>& common1, std::pair<InIter2, InIter2>& common2)
66  {
67  common1.first = last1;
68  common1.second = last1;
69  common2.first = last2;
70  common2.second = last2;
71 
72  // find the first common element in the in the two ranges
73  for(; first1 != last1; ++first1) {
74  common2.first = std::find(first2, last2, *first1);
75  if(common2.first != last2)
76  break;
77  }
78  common1.first = first1;
79  first2 = common2.first;
80 
81  // find the last common element in the two ranges
82  while((first1 != last1) && (first2 != last2)) {
83  if(*first1 != *first2)
84  break;
85  ++first1;
86  ++first2;
87  }
88  common1.second = first1;
89  common2.second = first2;
90  }
91 
92  template <typename VarLeft, typename VarRight>
93  inline Permutation var_perm(const VarLeft& l, const VarRight& r) {
94  TA_ASSERT(l.size() == r.size());
95  std::vector<size_t> a(l.size());
96  typename VarRight::const_iterator rit = r.begin();
97  for(auto it = a.begin(); it != a.end(); ++it) {
98  typename VarLeft::const_iterator lit = std::find(l.begin(), l.end(), *rit++);
99  TA_ASSERT(lit != l.end());
100  *it = std::distance(l.begin(), lit);
101  }
102  return Permutation(std::move(a));
103  }
104  } // namespace detail
105 
107 
111  class VariableList {
112  public:
113  typedef std::vector<std::string>::const_iterator const_iterator;
114 
116  VariableList() : vars_() { }
117 
119  explicit VariableList(const std::string& vars) {
120  if(vars.size() != 0)
121  init_(vars);
122  }
123 
124  template<typename InIter>
125  VariableList(InIter first, InIter last) {
127  "VariableList constructor requires an input iterator");
128  TA_ASSERT( unique_(first, last) );
129 
130  for(; first != last; ++first)
131  vars_.push_back(trim_spaces_(first->begin(), first->end()));
132 
133  }
134 
135  VariableList(const VariableList& other) : vars_(other.vars_) { }
136 
138  vars_ = other.vars_;
139 
140  return *this;
141  }
142 
143  VariableList& operator =(const std::string& vars) {
144  init_(vars);
145  return *this;
146  }
147 
149  TA_ASSERT(p.dim() == dim());
150  vars_ *= p;
151  return *this;
152  }
153 
155  const_iterator begin() const { return vars_.begin(); }
156 
158  const_iterator end() const { return vars_.end(); }
159 
161  const std::string& at(const std::size_t n) const { return vars_.at(n); }
162 
164  const std::string& operator [](const std::size_t n) const { return vars_[n]; }
165 
167  unsigned int dim() const { return vars_.size(); }
168 
170  unsigned int size() const { return vars_.size(); }
171 
172  const std::vector<std::string>& data() const { return vars_; }
173 
174  std::string string() const {
175  std::string result;
176  std::vector<std::string>::const_iterator it = vars_.begin();
177  if(it == vars_.end())
178  return result;
179 
180  for(result = *it++; it != vars_.end(); ++it) {
181  result += "," + *it;
182  }
183 
184  return result;
185  }
186 
187  void swap(VariableList& other) {
188  std::swap(vars_, other.vars_);
189  }
190 
192 
198  template <typename V>
199  Permutation permutation(const V& other) const {
200  return detail::var_perm(*this, other);
201  }
202 
204 
207  bool is_permutation(const VariableList& other) const {
208  if(vars_.size() != other.vars_.size())
209  return false;
210 
211  for(const_iterator it = begin(); it != end(); ++it) {
212  const_iterator other_it = other.begin();
213  for(; other_it != other.end(); ++other_it)
214  if(*it == *other_it)
215  break;
216  if(other_it == other.end())
217  return false;
218  }
219 
220  return true;
221  }
222 
223  private:
224 
227  void init_(const std::string& vars) {
228  std::string::const_iterator start = vars.begin();
229  std::string::const_iterator finish = vars.begin();
230  for(; finish != vars.end(); ++finish) {
231  if(*finish == ',') {
232  vars_.push_back(trim_spaces_(start, finish));
233  start = finish + 1;
234  }
235  }
236  vars_.push_back(trim_spaces_(start, finish));
237 
238  TA_ASSERT( (unique_(vars_.begin(), vars_.end())));
239  }
240 
243  static std::string trim_spaces_(std::string::const_iterator first, std::string::const_iterator last) {
244  TA_ASSERT(first != last);
245  std::string result = "";
246  for(;first != last; ++first) {
247  TA_ASSERT( valid_char_(*first));
248  if(*first != ' ' && *first != '\0')
249  result.append(1, *first);
250  }
251 
252  TA_ASSERT(result.length() != 0);
253 
254  return result;
255  }
256 
258  template<typename InIter>
259  bool unique_(InIter first, InIter last) const {
260  for(; first != last; ++first) {
261  InIter it2 = first;
262  for(++it2; it2 != last; ++it2)
263  if(first->compare(*it2) == 0)
264  return false;
265  }
266 
267  return true;
268  }
269 
270  static bool valid_char_(char c) {
271  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
272  (c >= '0' && c <= '9') || (c == ' ') || (c == ',') || (c == '\0') ||
273  (c == '\'') || (c == '_');
274  }
275 
276  friend void swap(VariableList&, VariableList&);
277 
278  std::vector<std::string> vars_;
279 
280  friend VariableList operator*(const ::TiledArray::Permutation&, const VariableList&);
281 
282  }; // class VariableList
283 
285  inline void swap(VariableList& v0, VariableList& v1) {
286  std::swap(v0.vars_, v1.vars_);
287  }
288 
289  inline bool operator ==(const VariableList& v0, const VariableList& v1) {
290  return (v0.dim() == v1.dim()) && std::equal(v0.begin(), v0.end(), v1.begin());
291  }
292 
293  inline bool operator !=(const VariableList& v0, const VariableList& v1) {
294  return ! operator ==(v0, v1);
295  }
296 
297  inline VariableList operator*(const ::TiledArray::Permutation& p, const VariableList& v) {
298  TA_ASSERT(p.dim() == v.dim());
299  VariableList result;
300  result.vars_ = p * v.vars_;
301 
302  return result;
303  }
304 
306  inline std::ostream& operator <<(std::ostream& out, const VariableList& v) {
307  out << "(";
308  std::size_t d;
309  std::size_t n = v.dim() - 1;
310  for(d = 0; d < n; ++d) {
311  out << v[d] << ", ";
312  }
313  out << v[d];
314  out << ")";
315  return out;
316  }
317 
318  } // namespace expressions
319 
320 } // namespace TiledArray
321 
322 #endif // TILEDARRAY_EXPRESSIONS_VARIABLE_LIST_H__INCLUDED
void swap(VariableList &, VariableList &)
Exchange the content of the two variable lists.
ExprTraceTarget operator<<(std::ostream &os, const TsrExpr< A, Alias > &tsr)
Expression trace factory function.
Definition: expr_trace.h:131
VariableList(const std::string &vars)
constructs a variable lists
void find_common(InIter1 first1, const InIter1 last1, InIter2 first2, const InIter2 last2, std::pair< InIter1, InIter1 > &common1, std::pair< InIter2, InIter2 > &common2)
Finds the range of common elements for two sets of iterators.
Definition: variable_list.h:64
Permutation permutation(const V &other) const
Generate permutation relationship for variable lists.
VariableList(InIter first, InIter last)
VariableList & operator*=(const Permutation &p)
bool operator!=(const VariableList &v0, const VariableList &v1)
std::enable_if< TiledArray::detail::is_numeric< Scalar >::value, ScalAddExpr< Left, Right, Scalar > >::type operator*(const AddExpr< Left, Right > &expr, const Scalar &factor)
Scaled-addition expression factor.
Definition: add_expr.h:198
const std::string & operator[](const std::size_t n) const
Returns the n-th string in the variable list.
const std::vector< std::string > & data() const
unsigned int dim() const
Returns the number of strings in the variable list.
index_type dim() const
Domain size accessor.
Definition: permutation.h:206
Variable list manages a list variable strings.
#define TA_ASSERT(a)
Definition: error.h:107
std::vector< std::string >::const_iterator const_iterator
Permutation var_perm(const VarLeft &l, const VarRight &r)
Definition: variable_list.h:93
friend VariableList operator*(const ::TiledArray::Permutation &, const VariableList &)
bool is_permutation(const VariableList &other) const
Check that this variable list is a permutation of other.
Permutation of a sequence of objects indexed by base-0 indices.
Definition: permutation.h:119
const_iterator end() const
Returns an iterator to the end of the variable list.
void swap(VariableList &other)
VariableList(const VariableList &other)
const std::string & at(const std::size_t n) const
Returns the n-th string in the variable list.
VariableList()
Constructs an empty variable list.
bool operator==(const VariableList &v0, const VariableList &v1)
const_iterator begin() const
Returns an iterator to the first variable.
VariableList & operator=(const VariableList &other)
unsigned int size() const
Returns the number of strings in the variable list.