ARTS  1.0.222
matpackII.h
Go to the documentation of this file.
1 /* Copyright (C) 2001 Stefan Buehler <sbuehler@uni-bremen.de>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
18 #include <vector>
19 
20 /*
21  Notes:
22 
23  There are two different ways to index:
24  S.rw(3,4) = 1; // Read and write
25  cout << S.ro(3,4); // Read only
26 
27  This distinction is necessary, because rw() creates elements if they
28  don't already exist.
29 
30  */
31 
32 
41 class SparseView {
42 public:
43  // Member functions:
44  Index nrows() const;
45  Index ncols() const;
46  Index nnz() const;
47 
48  // Index Operators:
49  Numeric& rw(Index r, Index c);
50  Numeric ro(Index r, Index c) const;
51 
52  // Friends:
53  friend std::ostream& operator<<(std::ostream& os, const SparseView& v);
54 
55 protected:
56  // Constructors:
57  SparseView();
58  SparseView(std::vector<Numeric> *data,
59  std::vector<Index> *rowind,
60  std::vector<Index> *colptr,
61  const Range& rr,
62  const Range& cr );
63 
64  // Data members:
66  std::vector<Numeric> *mdata;
68  std::vector<Index> *mrowind;
70  std::vector<Index> *mcolptr;
73 };
74 
80 class Sparse : public SparseView {
81 public:
82  // Constructors:
83  Sparse();
84  Sparse(Index r, Index c);
85  Sparse(const Sparse& m);
86 
87  // Destructor:
88  ~Sparse();
89 };
90 
91 
92 // Functions for SparseView:
93 // -------------------------------
94 
96 inline Index SparseView::nrows() const
97 {
98  return mrr.mextent;
99 }
100 
102 inline Index SparseView::ncols() const
103 {
104  return mcr.mextent;
105 }
106 
108 inline Index SparseView::nnz() const
109 {
110  return *(mcolptr->end()-1);
111 }
112 
121 {
122  // Check if indices are valid:
123  assert( 0<=r );
124  assert( 0<=c );
125  assert( r<mrr.mextent );
126  assert( c<mcr.mextent );
127 
128  // Convert to true indices. We use r and c, which are local
129  // variables because we used call be value.
130  r = mrr.mstart + r*mrr.mstride;
131  c = mcr.mstart + c*mcr.mstride;
132 
133  // Get index of first data element of this column:
134  Index i = (*mcolptr)[c];
135 
136  // Get index of first data element of next column. (This always works,
137  // because mcolptr has one extra element pointing behind the last
138  // column.)
139  const Index end = (*mcolptr)[c+1];
140 
141  // See if we find an element with the right row index in this
142  // range. We assume that the elements are sorted by ascending row
143  // index. We use the index i as the loop counter, which we have
144  // initialized above.
145  for ( ; i<end; ++i )
146  {
147  Index rowi = (*mrowind)[i];
148  if ( r < rowi )
149  break;
150  if ( r == rowi )
151  return (*mdata)[i];
152  }
153 
154  // If we are here, then the requested data element does not yet
155  // exist.
156 
157  // We have to adjust the array of column pointers. The values
158  // in all columns above the current one have to be increased by 1.
159  for ( std::vector<Index>::iterator j = mcolptr->begin() + c + 1;
160  j < mcolptr->end();
161  ++j )
162  ++(*j);
163 
164  // We have to insert the new element in *mrowind and *mdata just one
165  // position before the index i. We can use std::insert to achieve
166  // this. Because they return an iterator to the newly inserted
167  // element, we can return directly from the second call.
168  mrowind->insert( mrowind->begin()+i, r );
169  return *( mdata->insert( mdata->begin()+i, 0 ) );
170 }
171 
173 inline Numeric SparseView::ro(Index r, Index c) const
174 {
175  // Check if indices are valid:
176  assert( 0<=r );
177  assert( 0<=c );
178  assert( r<mrr.mextent );
179  assert( c<mcr.mextent );
180 
181  // Convert to true indices:
182  r = mrr.mstart + r*mrr.mstride;
183  c = mcr.mstart + c*mcr.mstride;
184 
185  // Get index of first data element of this column:
186  Index begin = (*mcolptr)[c];
187 
188  // Get index of first data element of next column. (This always works,
189  // because mcolptr has one extra element pointing behind the last
190  // column.)
191  const Index end = (*mcolptr)[c+1];
192 
193  // See if we find an element with the right row index in this
194  // range. We assume that the elements are sorted by ascending row
195  // index.
196  for ( Index i=begin; i<end; ++i )
197  {
198  Index rowi = (*mrowind)[i];
199  if ( r < rowi )
200  return 0;
201  if ( r == rowi )
202  return (*mdata)[i];
203  }
204  return 0;
205 }
206 
210  mdata(NULL),
211  mrowind(NULL),
212  mcolptr(NULL),
213  mrr(0,0),
214  mcr(0,0)
215 {
216  // Nothing to do here
217 }
218 
222 inline SparseView::SparseView(std::vector<Numeric> *data,
223  std::vector<Index> *rowind,
224  std::vector<Index> *colptr,
225  const Range& rr,
226  const Range& cr ) :
227  mdata(data),
228  mrowind(rowind),
229  mcolptr(colptr),
230  mrr(rr),
231  mcr(cr)
232 {
233  // Nothing to do here.
234 }
235 
236 
237 
238 // Functions for Sparse:
239 // ---------------------------
240 
242 inline Sparse::Sparse()
243 {
244  // Nothing to do here
245 }
246 
260 inline Sparse::Sparse(Index r, Index c) :
261  SparseView( new std::vector<Numeric>,
262  new std::vector<Index>,
263  new std::vector<Index>(c+1,0),
264  Range(0,r),
265  Range(0,c) )
266 {
267  // Nothing to do here.
268 }
269 
272 inline Sparse::Sparse(const Sparse& m) :
273  SparseView( new std::vector<Numeric>(*m.mdata),
274  new std::vector<Index>(*m.mrowind),
275  new std::vector<Index>(*m.mcolptr),
276  m.mrr,
277  m.mcr )
278 {
279  // Nothing to do here.
280 }
281 
282 
286 {
287  delete mdata;
288  delete mrowind;
289  delete mcolptr;
290 }
291 
292 // Output operator for SparseView:
293 
294 inline std::ostream& operator<<(std::ostream& os, const SparseView& v)
295 {
296  for (size_t c=0; c<v.mcolptr->size()-1; ++c)
297  {
298  // Get index of first data element of this column:
299  Index begin = (*v.mcolptr)[c];
300 
301  // Get index of first data element of next column. (This always works,
302  // because mcolptr has one extra element pointing behind the last
303  // column.)
304  const Index end = (*v.mcolptr)[c+1];
305 
306  // Loop through the elements in this column:
307  for ( Index i=begin; i<end; ++i )
308  {
309  Index r = (*v.mrowind)[i];
310 
311  // Now we know the true row r and column c. Convert to aparent r
312  // and c using the Ranges mrr and mcr,
313 
314  Index ra = (r-v.mrr.mstart)/v.mrr.mstride;
315  Index ca = (c-v.mcr.mstart)/v.mcr.mstride;
316 
317  // Are the aparent row ra and column ca inside the active range?
318  if ( 0 <= ra &&
319  ra < v.mrr.mextent &&
320  0 <= ca &&
321  ca < v.mcr.mextent )
322  {
323  // Yes, they are! Let's output this element.
324  os << setw(3) << ra << " "
325  << setw(3) << ca << " "
326  << setw(3) << (*v.mdata)[i] << "\n";
327  }
328  }
329  }
330 
331  return os;
332 }
SparseView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackII.h:96
SparseView::ro
Numeric ro(Index r, Index c) const
Plain const index operator.
Definition: matpackII.h:173
SparseView::mnr
Index mnr
Number of rows.
Definition: matpackII.h:72
SparseView::mcolptr
std::vector< Index > * mcolptr
Pointers to first data element for each column.
Definition: matpackII.h:70
Sparse
The Sparse class.
Definition: matpackII.h:80
SparseView::mdata
std::vector< Numeric > * mdata
The actual data values.
Definition: matpackII.h:66
Sparse::Sparse
Sparse()
Default constructor.
Definition: matpackII.h:242
SparseView::operator<<
friend std::ostream & operator<<(std::ostream &os, const SparseView &v)
Definition: matpackII.h:294
SparseView::rw
Numeric & rw(Index r, Index c)
Plain index operator.
Definition: matpackII.h:120
SparseView
The implementation of a sparse matrix.
Definition: matpackII.h:41
operator<<
std::ostream & operator<<(std::ostream &os, const SparseView &v)
Definition: matpackII.h:294
SparseView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackII.h:102
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: arts.h:147
SparseView::mrowind
std::vector< Index > * mrowind
Row indices.
Definition: matpackII.h:68
SparseView::SparseView
SparseView()
Default constructor.
Definition: matpackII.h:209
SparseView::nnz
Index nnz() const
Returns the number of nonzero elements.
Definition: matpackII.h:108
Range
The range class.
Definition: matpackI.h:139
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: arts.h:153
Sparse::~Sparse
~Sparse()
Destructor for Sparse.
Definition: matpackII.h:285