/usr/include/linbox/util/matrix-stream.h is in liblinbox-dev 1.1.6~rc0-4.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | /* matrix-stream.h
* Take a file or stream of a matrix, return (row, column, value) triples from
* that matrix. Automatically determine matrix format.
*
* NOTE to developers: To add a new format, write a subclass of
* MatrixStreamReader and put it in the formats
* subdirectory. Then you must add this new format to
* the file formats/matrix-stream-readers.h in two
* different places. It should be clear how to do this if
* you look at that file. Once you do this, the new format
* will automatically be used.
*
* by Dan Roche, 1-12-05
*/
#ifndef __MATRIX_STREAM_H
#define __MATRIX_STREAM_H
#include <iostream>
#include <queue>
#include <vector>
namespace LinBox { // namespace in which all LinBox code resides
// Error codes enumeration
enum MatrixStreamError {
GOOD, // There is one format that has not yet encountered any errors
END_OF_MATRIX, // The end of tha matrix has been reached; no more data
END_OF_FILE, // An EOF was encountered unexpectedly in reading the data
BAD_FORMAT, // This indicates that the format is recognized, but the
// file itself is not properly formatted. For instance,
// indices out of bounds.
NO_FORMAT // Indicates that the format of the given file is not
// recognized by any of the readers.
};
template <class Field> class MatrixStream;
/** An abstract base class to represent readers for specific formats. For each
* format that is to be supported, make an extension of this class that
* implements protected methods nextTripleImpl and initImpl.
\ingroup util
*/
template <class Field>
class MatrixStreamReader {
public:
typedef typename Field::Element Element;
private:
/** The std::queue used to save triples that have been read but have not yet been
* requested with a call to nextTriple
*/
std::queue<std::pair<std::pair<size_t,size_t>,Element> > savedTriples;
/** The last error returned by saveNext(), to be returned by nextTriple
* after savedTriples has been emptied.
*/
MatrixStreamError lastError;
/* The protected members and methods are provided to save on implementation
* time for making the readers. */
protected:
/** The stream that provides the data to the reader.
*/
std::istream* sin;
/** A pointer to the MatrixStream that is using this reader. Useful to
* get an instance of the field via ms->getField().
*/
MatrixStream<Field>* ms;
/** The number of rows in the matrix. This will be set by default to 0.
*/
size_t _m;
/** Indicates whether the row dimension is accurate */
bool knowM;
/** Number of columns in the matrix. Similar requirements as _m above. */
size_t _n;
/** Indicates whether the column dimension is accurate */
bool knowN;
/** Indicates that the end of the matrix has been reached; no more calls to
* nextTripleImpl will be made once this value is true. This will
* automatically be set to true if nextTripleImpl returns END_OF_MATRIX.
*/
bool atEnd;
/** Save the triple (m,n,v) onto the savedTriples std::queue. */
void saveTriple(size_t m, size_t n, const Element& v);
/** Read the next triple of row index, column index, value and store it in
* the given references.
* @return A MatrixStreamError indicating the success or failure of the
* operation
*/
virtual MatrixStreamError nextTripleImpl(size_t&,size_t&,Element&) = 0;
/** Read the first line of the matrix from the stream and attempt to
* determine if it is of this reader's type.
* @return A MatrixStreamError indicating the success or failure of the
* operation
*/
virtual MatrixStreamError initImpl(const char* firstLine) = 0;
/** A protected constructor that is called automatically when subclasses
* are instantiated. */
MatrixStreamReader() {
sin = NULL;
ms = NULL;
_m = _n = 0;
knowM = knowN = false;
atEnd = false;
lastError = GOOD;
}
public:
/** Get a unique string describing this format. */
virtual const char* getName() const = 0;
/** Get a (possibly) shortened version of the format name. */
virtual const char* shortName() const
{ return getName(); }
/** Determine if this format is sparse or dense.
* @return true if it is a sparse format, false if it is a dense one
*/
virtual bool isSparse() const = 0;
/** Initialize this MatrixStreamReader. Calls the initImpl method of the
* subclass. */
MatrixStreamError init(const char*,std::istream*,MatrixStream<Field>*);
/** Get the next triple of row index, column index, value and store it into
* the three referenced variables. Uses the nextTripleImpl method of the
* subclass. */
MatrixStreamError nextTriple( size_t&, size_t&, Element& );
/** Get the whole matrix as a dense (row-major) array of elements.
* By default, this implementation just repeatedly calls nextTriple to
* read in the whole matrix. Subclasses of dense formats should override
* this behavior.
* @param array The array to fill with entries. May be resized as needed.
*/
virtual MatrixStreamError getArray( std::vector<Element> &array );
/** Reads the next triple from the subclass nextTripleImpl method and saves
* it to the savedTriples std::queue rather than returning it. The error
* returned is that given from the subclass method. */
MatrixStreamError saveNext();
/** Get the number of rows in this matrix, store it in the given int. */
MatrixStreamError getRows(size_t&);
/** Get the number of columns in this matrix, store it in the given int. */
MatrixStreamError getColumns(size_t&);
/** Virtual destructor. */
virtual ~MatrixStreamReader() {
while( !savedTriples.empty() ) savedTriples.pop();
}
};
template <class Field>
class MatrixStream {
public:
typedef typename Field::Element Element;
private:
/** The underlying reader for this matrix stream. */
MatrixStreamReader<Field>* reader;
/** The first line of text used to init. */
char* firstLine;
/** The maximum number of characters to read for the first line (to send to
* the init functions).
*/
static const int FIRST_LINE_LIMIT = 160;
/** The underlying input stream from which data is being read. */
std::istream& in;
/** The lineNumber is recorded in case the user wants to know at which line
* an error occurs. This will be updated automatically by any of the read
* methods below if they encounter breaks; it is up to the subclasses to
* increment lineNumber if they read any newline characters independently.
*/
int lineNumber;
/** The current state of matrix streaming. */
MatrixStreamError currentError;
/** The line number on which the last error occurred */
int errorLineNumber;
/** True once any read functions have been called. */
bool readAnythingYet;
/** The Field to use in reading elements. */
const Field& f;
/** To ensure no one makes a copy of an instance of this class */
MatrixStream( const MatrixStream<Field>& ) {}
/** Called by the constructors to get things going. */
void init();
/** Adds the given MatrixStreamReader to the readers std::vector. */
void addReader( MatrixStreamReader<Field>* );
public:
/** Constructor from an input stream.
* @param fld The Field used to read Elements from the matrix.
* @param in The input stream from which to read
* @throws MatrixStreamError if an error occurs in reading the
* first line (i.e. on initialization).
*/
MatrixStream( const Field& fld, std::istream& i );
/** Destructor */
~MatrixStream() { delete reader; }
/** Read some white space (if there is any). Using this method is preferable
* to letting the input stream handle whitespace skipping because this
* method will update the line number when breaks are encountered.
* @return true iff there is more data after the whitespace.
*/
bool readWhiteSpace();
/** Read the next triple of row index, column index, value and store it in
* the three referenced elements.
* @return true iff the read succeeded.
*/
bool nextTriple( size_t&, size_t&, Element& );
/** Get the whole matrix as a dense (row-major) array of elements.
* @param array The array to fill with entries. May be resized as needed.
*/
bool getArray( std::vector<Element> &array );
/** Get the number of rows in the matrix and store it in the given size_t.
* @return true iff the operation succeeded.
*/
bool getRows(size_t&);
/** Get the number of columns in the matrix and store it in the given size_t.
* @return true iff the operation succeeded.
*/
bool getColumns(size_t&);
/** Get the number of rows and columns in the matrix and store them in the
* given ints.
* @return true iff the operation succeeded.
*/
bool getDimensions( size_t&, size_t& );
/** Get the current state of the stream. Especially useful if called after
* nextTriple or one of the get operations on failure to get some
* information on what caused the failure.
*/
MatrixStreamError getError() const { return currentError; }
/** Report the error to the error stream and return it. Designed for throw
* operations.
*/
MatrixStreamError reportError(const char*, int) const;
/** If the reader is in the GOOD state, get the line number it is on.
* Otherwise, get the line number on which the last error occurred.
*/
int getLineNumber() const;
/** Get the Field that was passed to the constructor. */
const Field& getField() const { return f; }
/** Get a brief description of the format of the matrix being read. */
const char* getFormat() const { return reader->getName(); }
/** Get a very brief description of the matrix format. */
const char* getShortFormat() const { return reader->shortName(); }
/** Tell if the matrix being read is sparse.
* @return true if the matrix is sparse, false if it is dense.
*/
bool isSparse() const { return reader->isSparse(); }
}; // end of class MatrixStream
} // end of namespace LinBox
#include "matrix-stream.inl"
#endif // MATRIX_STREAM_H
|