feisty meow concerns codebase 2.140
matrix.h
Go to the documentation of this file.
1#ifndef MATRIX_CLASS
2#define MATRIX_CLASS
3
4/*****************************************************************************\
5* *
6* Name : matrix *
7* Author : Chris Koeritz *
8* *
9*******************************************************************************
10* Copyright (c) 1993-$now By Author. This program is free software; you can *
11* redistribute it and/or modify it under the terms of the GNU General Public *
12* License as published by the Free Software Foundation; either version 2 of *
13* the License or (at your option) any later version. This is online at: *
14* http://www.fsf.org/copyleft/gpl.html *
15* Please send any updates to: fred@gruntose.com *
16\*****************************************************************************/
17
18#include <basis/array.h>
19#include <basis/astring.h>
20#include <basis/functions.h>
21#include <basis/guards.h>
22
23namespace structures {
24
26
30template <class contents>
31class matrix : protected basis::array<contents>
32{
33public:
34 matrix(int rows = 0, int cols = 0, contents *data = NULL_POINTER);
36 matrix(const matrix &to_copy);
37
39
40 int rows() const { return _rows; }
41 int columns() const { return _cols; }
42
43 matrix &operator = (const matrix &to_copy);
44
45 contents &get(int row, int column);
46 const contents &get(int row, int column) const;
48
49 bool put(int row, int column, const contents &to_put);
51
52 contents *operator[] (int row);
54
59 const contents *operator[] (int row) const;
61
62 matrix submatrix(int row, int column, int rows, int columns) const;
64
66 void submatrix(matrix &sub, int row, int column, int rows, int cols) const;
68
71 void transpose(matrix &resultant) const;
73
78
79 bool insert_row(int before_row);
81
83 bool insert_column(int before_column);
85
86 void reset(int rows = 0, int columns = 0);
88
89 void redimension(int new_rows, int new_columns);
91
94 bool zap_row(int row_to_zap);
95 bool zap_column(int column_to_zap);
97
100private:
101 int _rows;
102 int _cols;
103
104 int compute_index(int row, int column) const;
106};
107
109
111class int_matrix : public matrix<int>
112{
113public:
114 int_matrix(int rows = 0, int cols = 0, int *data = NULL_POINTER)
115 : matrix<int>(rows, cols, data) {}
116 int_matrix(const matrix<int> &to_copy) : matrix<int>(to_copy) {}
117};
118
120class string_matrix : public matrix<basis::astring>
121{
122public:
123 string_matrix(int rows = 0, int cols = 0, basis::astring *data = NULL_POINTER)
124 : matrix<basis::astring>(rows, cols, data) {}
125 string_matrix(const matrix<basis::astring> &to_copy) : matrix<basis::astring>(to_copy) {}
126};
127
129class double_matrix : public matrix<double>
130{
131public:
132 double_matrix(int rows = 0, int cols = 0, double *data = NULL_POINTER)
133 : matrix<double>(rows, cols, data) {}
134 double_matrix(const matrix<double> &to_copy) : matrix<double>(to_copy) {}
135};
136
138
139// implementation for longer methods...
140
141//hmmm: the operations for zapping use extra memory. they could easily
142// be done as in-place copies.
143
144#undef static_class_name
145#define static_class_name() "matrix"
146 // used in bounds_halt macro.
147
148template <class contents>
149matrix<contents>::matrix(int r, int c, contents *dat)
150: basis::array<contents>(r*c, dat), _rows(r), _cols(c) {}
151
152template <class contents>
154: basis::array<contents>(0), _rows(0), _cols(0)
155{ *this = to_copy; }
156
157template <class contents>
159{
160 if (&to_copy == this) return *this;
162 _rows = to_copy._rows;
163 _cols = to_copy._cols;
164 return *this;
165}
166
167template <class contents>
169{ return &basis::array<contents>::operator [] (compute_index(r, 0)); }
170
171template <class contents>
172const contents *matrix<contents>::operator[] (int r) const
173{ return &basis::array<contents>::operator [] (compute_index(r, 0)); }
174
175template <class contents>
176const contents &matrix<contents>::get(int r, int c) const
177{ return basis::array<contents>::get(compute_index(r, c)); }
178
179template <class contents>
180contents &matrix<contents>::get(int row, int column)
181{ return basis::array<contents>::operator [] (compute_index(row, column)); }
182
183template <class contents>
184int matrix<contents>::compute_index(int row, int column) const
185{ return column + row * _cols; }
186
187template <class contents>
188void matrix<contents>::reset(int rows_in, int columns_in)
189{
190 if ( (_rows == rows_in) && (_cols == columns_in) ) {
191 // reuse space, but reset the objects to their initial state.
192 for (int i = 0; i < basis::array<contents>::length(); i++)
193 basis::array<contents>::operator [](i) = contents();
194 return;
195 }
196
197 _rows = 0;
198 _cols = 0;
200
201 this->insert(0, rows_in * columns_in);
202 _rows = rows_in;
203 _cols = columns_in;
204}
205
206template <class contents>
207void matrix<contents>::redimension(int new_rows, int new_columns)
208{
209 if ( (_rows == new_rows) && (_cols == new_columns) ) return;
210 matrix<contents> new_this(new_rows, new_columns);
211 for (int r = 0; r < basis::minimum(new_rows, rows()); r++)
212 for (int c = 0; c < basis::minimum(new_columns, columns()); c++)
213 new_this[r][c] = (*this)[r][c];
214 *this = new_this;
215}
216
217template <class contents>
218bool matrix<contents>::put(int row, int column, const contents &to_put)
219{
220 if ( (row >= rows()) || (column >= columns()) )
221 return false;
222 (operator [](row))[column] = to_put;
223 return true;
224}
225
226template <class contents>
227matrix<contents> matrix<contents>::submatrix(int row, int column, int rows_in,
228 int columns_in) const
229{
230 matrix<contents> to_return;
231 submatrix(to_return, row, column, rows_in, columns_in);
232 return to_return;
233}
234
235template <class contents>
236void matrix<contents>::submatrix(matrix<contents> &sub, int row, int column,
237 int rows_in, int columns_in) const
238{
239 sub.reset();
240 if ( (row >= rows()) || (row + rows_in >= rows()) ) return;
241 if ( (column >= columns()) || (column + columns_in >= columns()) ) return;
242 sub.reset(rows_in, columns_in);
243 for (int r = row; r < row + rows_in; r++)
244 for (int c = column; c < column + columns_in; c++)
245 sub[r - row][c - column] = (*this)[r][c];
246}
247
248template <class contents>
250{
251 matrix<contents> to_return;
252 transpose(to_return);
253 return to_return;
254}
255
256template <class contents>
258{
259 resultant.reset(columns(), rows());
260 for (int i = 0; i < rows(); i++)
261 for (int j = 0; j < columns(); j++)
262 resultant[j][i] = (*this)[i][j];
263}
264
265template <class contents>
267{
268 basis::array<contents> to_return;
269 if (row >= rows()) return to_return;
270 to_return.reset(columns());
271 for (int i = 0; i < columns(); i++)
272 to_return[i] = get(row, i);
273 return to_return;
274}
275
276template <class contents>
278{
279 basis::array<contents> to_return;
280 if (column >= columns()) return to_return;
281 to_return.reset(rows());
282 for (int i = 0; i < rows(); i++)
283 to_return[i] = get(i, column);
284 return to_return;
285}
286
287template <class contents>
288bool matrix<contents>::zap_row(int row_to_zap)
289{
290 FUNCDEF("zap_row");
291 bounds_halt(row_to_zap, 0, rows() - 1, false);
292 const int start = compute_index(row_to_zap, 0);
293 // this is only safe because the indices are stored in row-major order (which
294 // i hope means the right thing). in any case, the order is like so:
295 // 1 2 3 4
296 // 5 6 7 8
297 // thus we can whack a whole row contiguously.
298 basis::array<contents>::zap(start, start + columns() - 1);
299 _rows--;
300 return true;
301}
302
303template <class contents>
304bool matrix<contents>::zap_column(int column_to_zap)
305{
306 FUNCDEF("zap_column");
307 bounds_halt(column_to_zap, 0, columns() - 1, false);
308 // this starts at the end, which keeps the indexes meaningful. otherwise
309 // the destruction interferes with finding the elements.
310 for (int r = rows(); r >= 0; r--) {
311 const int loc = compute_index(r, column_to_zap);
313 }
314 _cols--;
315 return true;
316}
317
318template <class contents>
320{
321 FUNCDEF("insert_row");
322 bounds_halt(position, 0, rows(), false);
323 // see comment in zap_row for reasoning about the below.
324 basis::array<contents>::insert(compute_index(position, 0), columns());
325 _rows++;
326 // clear out those spaces.
327 for (int c = 0; c < columns(); c++)
328 put(position, c, contents());
329 return true;
330}
331
332template <class contents>
334{
335 FUNCDEF("insert_column");
336 bounds_halt(position, 0, columns(), false);
337 // similarly to zap_column, we must iterate in reverse.
338 for (int r = rows(); r >= 0; r--)
339 basis::array<contents>::insert(compute_index(r, position), 1);
340 _cols++;
341 // clear out those spaces.
342 for (int r = 0; r < rows(); r++)
343 put(r, position, contents());
344 return true;
345}
346
347#undef static_class_name
348
349} //namespace.
350
351#endif
352
Represents a sequential, ordered, contiguous collection of objects.
Definition array.h:54
outcome insert(int index, int new_indices)
Adds "new_indices" new positions for objects into the array at "index".
Definition array.h:803
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
Definition array.h:349
const contents & operator[](int index) const
Synonym for get that provides the expected array indexing syntax.
Definition array.h:137
const contents & get(int index) const
Accesses individual objects stored in "this" at the "index" position.
Definition array.h:372
outcome zap(int start, int end)
Deletes from "this" the objects inclusively between "start" and "end".
Definition array.h:769
array & operator=(const array< contents > &copy_from)
Copies the array in "copy_from" into this.
Definition array.h:353
Provides a dynamically resizable ASCII character string.
Definition astring.h:35
A matrix of double floating point numbers.
Definition matrix.h:130
double_matrix(int rows=0, int cols=0, double *data=NULL_POINTER)
Definition matrix.h:132
double_matrix(const matrix< double > &to_copy)
Definition matrix.h:134
A matrix of integers.
Definition matrix.h:112
int_matrix(const matrix< int > &to_copy)
Definition matrix.h:116
int_matrix(int rows=0, int cols=0, int *data=NULL_POINTER)
Definition matrix.h:114
Represents a two-dimensional array of objects.
Definition matrix.h:32
bool zap_column(int column_to_zap)
removes a row or column from the matrix.
Definition matrix.h:304
contents & get(int row, int column)
Definition matrix.h:180
matrix(int rows=0, int cols=0, contents *data=NULL_POINTER)
the "data" array must have at least "rows" * "cols" contents in it.
Definition matrix.h:149
void submatrix(matrix &sub, int row, int column, int rows, int cols) const
like submatrix() above, but stores into the "sub" parameter.
Definition matrix.h:236
void transpose(matrix &resultant) const
stores the transpose of this matrix in "resultant".
Definition matrix.h:257
bool insert_row(int before_row)
inserts a row before the "before_" parameter.
Definition matrix.h:319
matrix submatrix(int row, int column, int rows, int columns) const
returns a submatrix of this one starting at "row" and "column".
Definition matrix.h:227
bool insert_column(int before_column)
inserts a column before the "before_" parameter.
Definition matrix.h:333
bool put(int row, int column, const contents &to_put)
stores "to_put" into the matrix at "row" and "column".
Definition matrix.h:218
int columns() const
Definition matrix.h:41
void reset(int rows=0, int columns=0)
empties the matrix and changes its size.
Definition matrix.h:188
matrix & operator=(const matrix &to_copy)
Definition matrix.h:158
int rows() const
Definition matrix.h:40
basis::array< contents > get_row(int row)
return the vector at the "row", or an empty array if "row" is invalid.
Definition matrix.h:266
bool zap_row(int row_to_zap)
Definition matrix.h:288
contents * operator[](int row)
dangerous: indexes by "row" into the underlying contents.
Definition matrix.h:168
matrix transpose() const
provides the transposed form of this matrix.
Definition matrix.h:249
basis::array< contents > get_column(int column)
return the vector at the "column", or an empty array if it's invalid.
Definition matrix.h:277
const contents & get(int row, int column) const
retrieves the contents from the specified "row" and "column".
Definition matrix.h:176
void redimension(int new_rows, int new_columns)
changes the size to contain "new_rows" by "new_columns" elements.
Definition matrix.h:207
matrix(const matrix &to_copy)
Definition matrix.h:153
A matrix of strings.
Definition matrix.h:121
string_matrix(int rows=0, int cols=0, basis::astring *data=NULL_POINTER)
Definition matrix.h:123
string_matrix(const matrix< basis::astring > &to_copy)
Definition matrix.h:125
#define NULL_POINTER
The value representing a pointer to nothing.
Definition definitions.h:32
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition enhance_cpp.h:54
#define bounds_halt(value, low, high, to_return)
Verifies that "value" is between "low" and "high", inclusive.
Definition guards.h:60
The guards collection helps in testing preconditions and reporting errors.
Definition array.h:30
type minimum(type a, type b)
maximum returns the greater of two values.
Definition functions.h:29
A dynamic container class that holds any kind of object via pointers.
Definition amorph.h:55