BALL  1.4.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
diagonalIterator.h
Go to the documentation of this file.
1 #ifndef BALL_LINALG_DIAGONALITERATOR_H
2 #define BALL_LINALG_DIAGONALITERATOR_H
3 
4 #ifndef BALL_LINALG_MATRIX_IH
5 # include <BALL/MATHS/LINALG/matrix.ih>
6 #endif
7 
8 #ifndef BALL_LINALG_VECTOR_IH
9 # include <BALL/MATHS/vector.ih>
10 #endif
11 
12 #ifndef BALL_CONCEPT_RANDOMACCESSITERATOR_H
14 #endif
15 
16 namespace BALL {
17 
18  // forward declaration
19  template <class valuetype, class mtraits>
20  class Matrix;
21 
22 
23  template <class valuetype, class mtraits=StandardTraits>
25  {
28  typedef valuetype ValueType;
29 
32  typedef valuetype* PointerType;
33 
36  typedef int IteratorPosition;
37 
40  typedef int Distance;
41 
44  typedef int Index;
45 
46  friend class Matrix<valuetype, mtraits>;
47  public:
48 
50  {
51  }
52 
54  : bound_(0),
55  position_(0),
56  vector_(0)
57  {
58  }
59 
61  : bound_(const_cast<Matrix<valuetype, mtraits>*>(&matrix)),
62  position_(0),
63  vector_(bound_->m_)
64  {
65  }
66 
68  : bound_(traits.bound_),
69  position_(traits.position_),
70  vector_(bound_->m_)
71  {
72  }
73 
75  {
76  bound_ = traits.bound_;
77  position_ = traits.position_;
78  vector_ = traits.vector_;
79 
80  return *this;
81  }
82 
84  {
85  return bound_;
86  }
87 
89  {
90  return bound_;
91  }
92 
93  bool isSingular() const
94  {
95  return (bound_ == 0);
96  }
97 
99  {
100  return position_;
101  }
102 
104  {
105  return position_;
106  }
107 
108  bool operator == (const DiagonalIteratorTraits& traits) const
109  {
110  return (position_ == traits.position_);
111  }
112 
113  bool operator != (const DiagonalIteratorTraits& traits) const
114  {
115  return (position_ != traits.position_);
116  }
117 
118  bool operator < (const DiagonalIteratorTraits& traits) const
119  {
120  if (bound_->row_major_)
121  {
122  return (((position_ / bound_->m_) > (traits.position_ / traits.bound_->m_)) &&
123  ((position_ % bound_->m_) < (traits.position_ % traits.bound_->m_)));
124  }
125  else
126  {
127  return (((position_ % bound_->n_) > (traits.position_ % traits.bound_->n_)) &&
128  ((position_ / bound_->n_) < (traits.position_ / traits.bound_->n_)));
129  }
130  }
131 
133  {
134  return (Distance)(position_ - traits.position_);
135  }
136 
137  bool isValid() const
138  {
139  return ((bound_ != 0) && (position_ >= 0) && (position_ < (int)bound_->data_.size()));
140  }
141 
142  void invalidate()
143  {
144  bound_ = 0;
145  position_ = -1;
146  }
147 
148  void toBegin()
149  {
150  if (bound_->row_major_)
151  {
152  position_ = bound_->data_.size() - bound_->m_;
153  }
154  else
155  {
156  position_ = (bound_->n_ - 1);
157  }
158  }
159 
160  bool isBegin() const
161  {
162  if (bound_->row_major_)
163  {
164  return (position_ == (int)(bound_->data_.size() - bound_->m_));
165  }
166  else
167  {
168  return (position_ == (int)(bound_->n_ - 1));
169  }
170  }
171 
172  void toEnd()
173  {
174  if (bound_->row_major_)
175  {
176  position_ = bound_->m_;
177  }
178  else
179  {
180  position_ = bound_->data_.size();
181  }
182  }
183 
184  bool isEnd() const
185  {
186  if (bound_->row_major_)
187  {
188  return (position_ == (int)bound_->m_);
189  }
190  else
191  {
192  return (position_ == (int)bound_->data_.size());
193  }
194  }
195 
197  {
198 
199  if (bound_->row_major_)
200  {
201  // calculate the size of the current diagonalvector
202  uint vector_size = std::min(bound_->n_-(position_ / bound_->m_), bound_->m_-(position_ % bound_->m_));
203  vector_.resize(vector_size);
204  uint i = 0;
205  for (uint j = 0; j < vector_size; j++)
206  {
207  vector_[j]=(*bound_)[position_+i];
208  i+=bound_->m_+1;
209  }
210  }
211  else
212  {
213  // calculate the size of the current diagonalvector
214  uint vector_size = std::min(bound_->n_-(position_ % bound_->n_), bound_->m_-(position_ / bound_->n_));
215  vector_.resize(vector_size);
216  uint j = 0;
217  for (uint i = 0; position_+i < bound_->data_.size(); i+=bound_->n_)
218  {
219  vector_[j++]=(*bound_)[position_+i];
220  i++;
221  }
222  }
223 
224  return vector_;
225  }
226 
227  const Vector<valuetype>& getData() const
228  {
229  if (bound_->row_major_)
230  {
231 
232  // calculate the size of the current diagonalvector
233  uint vector_size = std::min(bound_->n_-(position_ / bound_->m_), bound_->m_-(position_ % bound_->m_));
234  vector_.resize(vector_size);
235  uint i = 0;
236  for (uint j = 0; j < vector_size; j++)
237  {
238  vector_[j]=(*bound_)[position_+i];
239  i+=bound_->m_+1;
240  }
241  }
242  else
243  {
244  // calculate the size of the current diagonalvector
245  uint vector_size = std::min(bound_->n_-(position_ % bound_->n_), bound_->m_-(position_ / bound_->n_));
246  vector_.resize(vector_size);
247  uint j = 0;
248  for (uint i = 0; position_+i < bound_->data_.size(); i+=bound_->n_)
249  {
250  vector_[j++]=(*bound_)[position_+i];
251  i++;
252  }
253  }
254 
255  return vector_;
256 
257  }
258 
259  void forward()
260  {
261  int i,j;
262  if (bound_->row_major_)
263  {
264  i = position_ / bound_->m_;
265  j = position_ % bound_->m_;
266  }
267  else
268  {
269  i = position_ % bound_->n_;
270  j = position_ / bound_->n_;
271  }
272 
273  if (i != 0)
274  {
275  i--;
276  } else
277  {
278  j++;
279  }
280  if (bound_->row_major_)
281  {
282  position_ = j + bound_->m_*i;
283  }
284  else
285  {
286  position_ = i + bound_->n_*j;
287  }
288  }
289 
290  friend std::ostream& operator << (std::ostream& s, const DiagonalIteratorTraits& traits)
291  {
292  return (s << traits.position_ << ' ');
293  }
294 
295  void dump(std::ostream& s) const
296  {
297  s << position_ << std::endl;
298  }
299 
300  void toRBegin()
301  {
302  if (bound_->row_major_)
303  {
304  position_ = (bound_->m_ - 1);
305  }
306  else
307  {
308  position_ = bound_->data_.size() - bound_->n_;
309  }
310  }
311 
312  bool isRBegin() const
313  {
314  if (bound_->row_major_)
315  {
316  return (position_ == (int)(bound_->m_ - 1));
317  }
318  else
319  {
320  return (position_ == (int)(bound_->data_.size() - bound_->n_));
321  }
322  }
323 
324  void toREnd()
325  {
326  if (bound_->row_major_)
327  {
328  position_ = bound_->data_.size();
329  }
330  else
331  {
332  position_ = bound_->n_;
333  }
334  }
335 
336  bool isREnd() const
337  {
338  if (bound_->row_major_)
339  {
340  return (position_ == (int)bound_->data_.size());
341  }
342  else
343  {
344  return (position_ == (int)bound_->n_);
345  }
346  }
347 
348  void backward()
349  {
350 
351  int i,j;
352  if (bound_->row_major_)
353  {
354  if (position_ == (int)bound_->m_)
355  {
356  position_--;
357  return;
358  }
359  i = position_ / bound_->m_;
360  j = position_ % bound_->m_;
361  }
362  else
363  {
364  i = position_ % bound_->n_;
365  j = position_ / bound_->n_;
366  }
367  if (j != 0)
368  {
369  j--;
370  } else
371  {
372  i++;
373  }
374  if (bound_->row_major_)
375  {
376  position_ = j + bound_->m_*i;
377  }
378  else
379  {
380  position_ = i + bound_->n_*j;
381  }
382 
383  }
384 
385  void backward(Distance distance)
386  {
387  int i,j;
388  if (bound_->row_major_)
389  {
390  if (position_ == (int)bound_->m_)
391  {
392  position_--;
393  distance--;
394  }
395  i = position_ / bound_->m_;
396  j = position_ % bound_->m_;
397  }
398  else
399  {
400  i = position_ % bound_->n_;
401  j = position_ / bound_->n_;
402  }
403 
404  if (j-distance >= 0)
405  {
406  j-=distance;
407  } else
408  {
409  j = 0;
410  i += (distance - j);
411  }
412  if (bound_->row_major_)
413  {
414  position_ = j + bound_->m_*i;
415  }
416  else
417  {
418  position_ = i + bound_->n_*j;
419  }
420  }
421 
422  void forward(Distance distance)
423  {
424 
425  int i,j;
426  if (bound_->row_major_)
427  {
428  i = position_ / bound_->m_;
429  j = position_ % bound_->m_;
430  }
431  else
432  {
433  i = position_ % bound_->n_;
434  j = position_ / bound_->n_;
435  }
436 
437  if (i-distance >= 0)
438  {
439  i-=distance;
440  } else
441  {
442  i = 0;
443  j += (distance - i);
444  }
445  if (bound_->row_major_)
446  {
447  position_ = j + bound_->m_*i;
448  }
449  else
450  {
451  position_ = i + bound_->n_*j;
452  }
453  }
454 
456  {
457  int i = bound_->n_ - 1;
458  int j = 0;
459  int position;
460 
461  if (i-index >= 0)
462  {
463  i-=index;
464  } else
465  {
466  i = 0;
467  j += (index - i);
468  }
469  if (bound_->row_major_)
470  {
471  position = j + bound_->m_*i;
472  }
473  else
474  {
475  position = i + bound_->n_*j;
476  }
477  if (bound_->row_major_)
478  {
479  // calculate the size of the current diagonalvector
480  uint vector_size = std::min(bound_->n_-(position / bound_->m_), bound_->m_-(position % bound_->m_));
481  vector_.resize(vector_size);
482  uint i = 0;
483  for (uint j = 0; j < vector_size; j++)
484  {
485  vector_[j]=(*bound_)[position+i];
486  i+=bound_->m_+1;
487  }
488  }
489  else
490  {
491  // calculate the size of the current diagonalvector
492  uint vector_size = std::min(bound_->n_-(position % bound_->n_), bound_->m_-(position / bound_->n_));
493  vector_.resize(vector_size);
494  uint j = 0;
495  for (uint i = 0; i < bound_->data_.size(); i+=bound_->n_)
496  {
497  vector_[j++]=(*bound_)[position+i];
498  i++;
499  }
500  }
501 
502  return vector_;
503  }
504 
505  const Vector<valuetype>& getData(Index index) const
506  {
507  int i = bound_->n_ - 1;
508  int j = 0;
509  int position;
510 
511  if (i-index >= 0)
512  {
513  i-=index;
514  } else
515  {
516  i = 0;
517  j += (index - i);
518  }
519  if (bound_->row_major_)
520  {
521  position = j + bound_->m_*i;
522  }
523  else
524  {
525  position = i + bound_->n_*j;
526  }
527  if (bound_->row_major_)
528  {
529  // calculate the size of the current diagonalvector
530  uint vector_size = std::min(bound_->n_-(position / bound_->m_), bound_->m_-(position % bound_->m_));
531  vector_.resize(vector_size);
532  uint i = 0;
533  for (uint j = 0; j < vector_size; j++)
534  {
535  vector_[j]=(*bound_)[position+i];
536  i+=bound_->m_+1;
537  }
538  }
539  else
540  {
541  // calculate the size of the current diagonalvector
542  uint vector_size = std::min(bound_->n_-(position % bound_->n_), bound_->m_-(position / bound_->n_));
543  vector_.resize(vector_size);
544  uint j = 0;
545  for (uint i = 0; i < bound_->data_.size(); i+=bound_->n_)
546  {
547  vector_[j++]=(*bound_)[position+i];
548  i++;
549  }
550  }
551  return vector_;
552  }
553 
554 
555  protected:
556 
560  };
561 
562 
563 } // namespace BALL
564 
565 #endif