casacore
Loading...
Searching...
No Matches
Matrix.h
Go to the documentation of this file.
1// # Matrix.h: A 2-D Specialization of the Array Class
2// # Copyright (C) 1993,1994,1995,1996,1999,2000,2001,2003
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef CASA_MATRIX_2_H
27#define CASA_MATRIX_2_H
28
29// # Includes
30#include "Array.h"
31
32namespace casacore { // #Begin casa namespace
33
34// <summary> A 2-D Specialization of the Array class </summary>
35// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
36// </reviewed>
37//
38// Matrix objects are two-dimensional specializations (e.g., more convenient
39// and efficient indexing) of the general Array class. You might also want
40// to look at the Array documentation to see inherited functionality. A
41// tutorial on using the array classes in general is available in the
42// "AIPS++ Programming Manual".
43//
44// Generally the member functions of Array are also available in
45// Matrix versions which take a pair of integers where the array
46// needs an IPosition. Since the Matrix
47// is two-dimensional, the IPositions are overkill, although you may
48// use those versions if you want to.
49// <srcblock>
50// Matrix<int> mi(100,100); // Shape is 100x100
51// mi.resize(50,50); // Shape now 50x50
52// </srcblock>
53//
54// Slices may be taken with the Slice class. To take a slice, one "indexes"
55// with one Slice(start, length, inc) for each axis,
56// where end and inc are optional.
57// Additionally, there are row(), column() and diagonal()
58// member functions which return Vector's which refer to the storage back
59// in the Matrix:
60// <srcblock>
61// Matrix<float> mf(100, 100);
62// mf.diagonal() = 1;
63// </srcblock>
64//
65// Correct indexing order of a matrix is:
66// <srcblock>
67// Matrix<int> mi(n1,n2) // [nrow, ncolumn]
68// for (size_t j=0; j<mi.ncolumn(); j++) {
69// for (size_t i=0; i<mi.nrow(); i++) {
70// mi(i,j) = i*j;
71// }
72// }
73// </srcblock>
74//
75//
76// Element-by-element arithmetic and logical operations are available (in
77// aips/ArrayMath.h and aips/ArrayLogical.h). Other Matrix operations (e.g.
78// LU decomposition) are available, and more appear periodically.
79//
80// As with the Arrays, if the preprocessor symbol AIPS_DEBUG is
81// defined at compile time invariants will be checked on entry to most
82// member functions. Additionally, if AIPS_ARRAY_INDEX_CHECK is defined
83// index operations will be bounds-checked. Neither of these should
84// be defined for production code.
85
86template <typename T>
87class Matrix : public Array<T> {
88 public:
89 // A Matrix of length zero in each dimension; zero origin.
91
92 // A Matrix with "l1" rows and "l2" columns.
93 // Fill it with the initial value.
94 Matrix(size_t l1, size_t l2, const T &initialValue = T());
95
96 // An uninitialized Matrix with "l1" rows and "l2" columns.
97 Matrix(size_t l1, size_t l2, typename Array<T>::uninitializedType);
98
99 // A matrix of shape with shape "len".
100 // Fill it with the initial value.
101 Matrix(const IPosition &len, const T &initialValue = T());
102
103 // An uninitialized matrix of shape with shape "len".
105
106 // The copy/move constructor uses reference semantics.
107 Matrix(const Matrix<T> &source);
108 Matrix(Matrix<T> &&source);
109
110 // Construct a Matrix by reference from "source". "source must have
111 // ndim() of 2 or less.
112 Matrix(const Array<T> &source);
113 Matrix(Array<T> &&source);
114
115 // Create an Matrix of a given shape from a pointer.
117 // Create an Matrix of a given shape from a pointer. Because the pointer
118 // is const, a copy is always made.
119 Matrix(const IPosition &shape, const T *storage);
120
121 // Create an identity matrix of side length n. (Could not do this as a constructor
122 // because of ambiguities with other constructors).
123 static Matrix<T> identity(size_t n);
124
125 // Resize to the given shape
126 // <group>
127 using Array<T>::resize;
128 void resize(size_t nx, size_t ny, bool copyValues = false);
129 // </group>
130
131 Matrix<T> &operator=(const Matrix<T> &source) { return assign_conforming(source); }
132 Matrix<T> &operator=(Matrix<T> &&source) { return assign_conforming(std::move(source)); }
133 Matrix<T> &operator=(const Array<T> &source) { return assign_conforming(source); }
134 Matrix<T> &operator=(Array<T> &&source) { return assign_conforming(std::move(source)); }
135
136 // Copy the values from other to this Matrix. If this matrix has zero
137 // elements then it will resize to be the same shape as other; otherwise
138 // other must conform to this.
139 // Note that the assign function can be used to assign a
140 // non-conforming matrix.
141 // <group>
144 return *this;
145 }
147 Array<T>::assign_conforming(std::move(source));
148 return *this;
149 }
150
152 // TODO Should be supported by the Array class,
153 // see Cube::operator=(const Array&)
154
155 if (source.ndim() == 2) {
157 } else {
158 // This might work if a.ndim == 1 or 2
159 (*this) = Matrix<T>(source);
160 }
161 return *this;
162 }
163
165 if (source.ndim() == 2) {
166 Array<T>::assign_conforming(std::move(source));
167 } else {
168 (*this) = Matrix<T>(std::move(source));
169 }
170 return *this;
171 }
172 // </group>
173
174 // Copy val into every element of this Matrix; i.e. behaves as if
175 // val were a constant conformant matrix.
176 Array<T> &operator=(const T &val) { return Array<T>::operator=(val); }
177
178 // Copy to this those values in marray whose corresponding elements
179 // in marray's mask are true.
184
185 // Single-pixel addressing. If AIPS_ARRAY_INDEX_CHECK is defined,
186 // bounds checking is performed.
187 // <group>
188 T &operator()(const IPosition &i) { return Array<T>::operator()(i); }
189 const T &operator()(const IPosition &i) const { return Array<T>::operator()(i); }
190 T &operator()(size_t i1, size_t i2) {
191 return this->contiguous_p ? this->begin_p[i1 + i2 * yinc()]
192 : this->begin_p[i1 * xinc() + i2 * yinc()];
193 }
194
195 const T &operator()(size_t i1, size_t i2) const {
196 return this->contiguous_p ? this->begin_p[i1 + i2 * yinc()]
197 : this->begin_p[i1 * xinc() + i2 * yinc()];
198 }
199 // </group>
200
201 // The array is masked by the input LogicalArray.
202 // This mask must conform to the array.
203 // <group>
204
205 // Return a MaskedArray.
207
208 // Return a MaskedArray.
210
211 // </group>
212
213 // The array is masked by the input MaskedLogicalArray.
214 // The mask is effectively the AND of the internal LogicalArray
215 // and the internal mask of the MaskedLogicalArray.
216 // The MaskedLogicalArray must conform to the array.
217 // <group>
218
219 // Return a MaskedArray.
223
224 // Return a MaskedArray.
226
227 // </group>
228
229 // Returns a reference to the i'th row.
230 // <group>
231 Vector<T> row(size_t i);
232 const Vector<T> row(size_t i) const;
233 // </group>
234
235 // Returns a reference to the j'th column
236 // <group>
237 Vector<T> column(size_t j);
238 const Vector<T> column(size_t j) const;
239 // </group>
240
241 // Returns a diagonal from the Matrix. The Matrix must be square.
242 // n==0 is the main diagonal. n>0 is above the main diagonal, n<0
243 // is below it.
244 // <group>
245 Vector<T> diagonal(long long n = 0);
246 const Vector<T> diagonal(long long n = 0) const;
247 // </group>
248
249 // Take a slice of this matrix. Slices are always indexed starting
250 // at zero. This uses reference semantics, i.e. changing a value
251 // in the slice changes the original.
252 // <srcblock>
253 // Matrix<double> vd(100,100);
254 // //...
255 // vd(Slice(0,10),Slice(10,10)) = -1.0; // 10x10 sub-matrix set to -1.0
256 // </srcblock>
257 // <group>
258 Matrix<T> operator()(const Slice &sliceX, const Slice &sliceY);
259 const Matrix<T> operator()(const Slice &sliceX, const Slice &sliceY) const;
260 // </group>
261
262 // Slice using IPositions. Required to be defined, otherwise the base
263 // class versions are hidden.
264 // <group>
265 Array<T> operator()(const IPosition &blc, const IPosition &trc, const IPosition &incr) {
266 return Array<T>::operator()(blc, trc, incr);
267 }
268 const Array<T> operator()(const IPosition &blc, const IPosition &trc,
269 const IPosition &incr) const {
270 return Array<T>::operator()(blc, trc, incr);
271 }
272 Array<T> operator()(const IPosition &blc, const IPosition &trc) {
273 return Array<T>::operator()(blc, trc);
274 }
275 const Array<T> operator()(const IPosition &blc, const IPosition &trc) const {
276 return Array<T>::operator()(blc, trc);
277 }
278 Array<T> operator()(const Slicer &slicer) { return Array<T>::operator()(slicer); }
279 const Array<T> operator()(const Slicer &slicer) const { return Array<T>::operator()(slicer); }
280 // </group>
281
282 // The length of each axis of the Matrix.
283 const IPosition &shape() const { return this->length_p; }
284 void shape(int &s1, int &s2) const {
285 s1 = this->length_p(0);
286 s2 = this->length_p(1);
287 }
288
289 // The number of rows in the Matrix, i.e. the length of the first axis.
290 size_t nrow() const { return this->length_p(0); }
291
292 // The number of columns in the Matrix, i.e. the length of the 2nd axis.
293 size_t ncolumn() const { return this->length_p(1); }
294
295 // Checks that the Matrix is consistent (invariants check out).
296 virtual bool ok() const override;
297
298 protected:
299 virtual void preTakeStorage(const IPosition &shape) override;
300 // Remove the degenerate axes from other and store result in this matrix.
301 // An exception is thrown if removing degenerate axes does not result
302 // in a matrix.
303 virtual void doNonDegenerate(const Array<T> &other, const IPosition &ignoreAxes) override;
304
305 virtual size_t fixedDimensionality() const override { return 2; }
306
307 private:
308 // Cached constants to improve indexing.
309 // size_t xinc_p, yinc_p;
310
311 size_t xinc() const { return this->inc_p(0); }
312 size_t yinc() const { return this->inc_p(1) * this->originalLength_p(0); }
313};
314
315// # Declare extern templates for often used types.
316extern template class Matrix<bool>;
317extern template class Matrix<float>;
318extern template class Matrix<double>;
319
320} // namespace casacore
321
322#include "Matrix.tcc"
323
324#endif
size_t ndim() const
The dimensionality of this array.
Definition ArrayBase.h:94
bool contiguous_p
Are the data contiguous?
Definition ArrayBase.h:253
IPosition originalLength_p
Definition ArrayBase.h:256
IPosition length_p
Used to hold the shape, increment into the underlying storage and originalLength of the array.
Definition ArrayBase.h:256
Array< T > & operator=(const Array< T > &other)
TODO we should change the semantics.
Definition Array.h:292
LogicalArrayElem * begin_p
Definition Array.h:920
T & operator()(const IPosition &)
Access a single element of the array.
Array< T > & assign_conforming(const Array< T > &other)
Copy the values in other to this.
Definition Array.h:279
Array()
Result has dimensionality of zero, and nelements is zero.
MaskedArray< T > operator()(const MaskedLogicalArray &mask)
Return a MaskedArray.
Definition Matrix.h:225
size_t nrow() const
The number of rows in the Matrix, i.e.
Definition Matrix.h:290
Matrix< T > operator()(const Slice &sliceX, const Slice &sliceY)
Take a slice of this matrix.
const Vector< T > column(size_t j) const
const Array< T > operator()(const IPosition &blc, const IPosition &trc) const
Definition Matrix.h:275
Matrix(const Array< T > &source)
Construct a Matrix by reference from "source".
const T & operator()(const IPosition &i) const
Definition Matrix.h:189
Vector< T > diagonal(long long n=0)
Returns a diagonal from the Matrix.
MaskedArray< T > operator()(const LogicalArray &mask) const
The array is masked by the input LogicalArray.
Definition Matrix.h:206
size_t ncolumn() const
The number of columns in the Matrix, i.e.
Definition Matrix.h:293
Array< T > operator()(const IPosition &blc, const IPosition &trc, const IPosition &incr)
Slice using IPositions.
Definition Matrix.h:265
Matrix(Matrix< T > &&source)
const Vector< T > diagonal(long long n=0) const
Matrix< T > & operator=(const Matrix< T > &source)
Definition Matrix.h:131
const Vector< T > row(size_t i) const
Matrix< T > & assign_conforming(Array< T > &&source)
Definition Matrix.h:164
Matrix()
A Matrix of length zero in each dimension; zero origin.
Matrix< T > & operator=(const Array< T > &source)
Definition Matrix.h:133
Array< T > operator()(const Slicer &slicer)
Definition Matrix.h:278
Matrix< T > & operator=(Matrix< T > &&source)
Definition Matrix.h:132
Vector< T > row(size_t i)
Returns a reference to the i'th row.
Matrix(const IPosition &len, typename Array< T >::uninitializedType)
An uninitialized matrix of shape with shape "len".
void shape(int &s1, int &s2) const
Definition Matrix.h:284
Matrix(const IPosition &shape, const T *storage)
Create an Matrix of a given shape from a pointer.
T & operator()(const IPosition &i)
Single-pixel addressing.
Definition Matrix.h:188
const Array< T > operator()(const IPosition &blc, const IPosition &trc, const IPosition &incr) const
Definition Matrix.h:268
Matrix< T > & operator=(Array< T > &&source)
Definition Matrix.h:134
Matrix(size_t l1, size_t l2, typename Array< T >::uninitializedType)
An uninitialized Matrix with "l1" rows and "l2" columns.
size_t xinc() const
Cached constants to improve indexing.
Definition Matrix.h:311
void resize(size_t nx, size_t ny, bool copyValues=false)
Matrix(const IPosition &len, const T &initialValue=T())
A matrix of shape with shape "len".
Vector< T > column(size_t j)
Returns a reference to the j'th column.
Array< T > & operator=(const T &val)
Copy val into every element of this Matrix; i.e.
Definition Matrix.h:176
T & operator()(size_t i1, size_t i2)
Definition Matrix.h:190
const Array< T > operator()(const Slicer &slicer) const
Definition Matrix.h:279
Matrix(Array< T > &&source)
virtual void preTakeStorage(const IPosition &shape) override
pre/post processing hook of takeStorage() for subclasses.
static Matrix< T > identity(size_t n)
Create an identity matrix of side length n.
virtual bool ok() const override
Checks that the Matrix is consistent (invariants check out).
MaskedArray< T > operator()(const LogicalArray &mask)
Return a MaskedArray.
Definition Matrix.h:209
Matrix< T > & assign_conforming(const MaskedArray< T > &marray)
Copy to this those values in marray whose corresponding elements in marray's mask are true.
Definition Matrix.h:180
Array< T > operator()(const IPosition &blc, const IPosition &trc)
Definition Matrix.h:272
const IPosition & shape() const
Definition Matrix.h:283
MaskedArray< T > operator()(const MaskedLogicalArray &mask) const
The array is masked by the input MaskedLogicalArray.
Definition Matrix.h:220
Matrix< T > & assign_conforming(const Array< T > &source)
Definition Matrix.h:151
Matrix(const Matrix< T > &source)
The copy/move constructor uses reference semantics.
virtual void doNonDegenerate(const Array< T > &other, const IPosition &ignoreAxes) override
Remove the degenerate axes from other and store result in this matrix.
Matrix< T > & assign_conforming(Matrix< T > &&source)
Definition Matrix.h:146
Matrix< T > & assign_conforming(const Matrix< T > &source)
Copy the values from other to this Matrix.
Definition Matrix.h:142
Matrix(size_t l1, size_t l2, const T &initialValue=T())
A Matrix with "l1" rows and "l2" columns.
Matrix(const IPosition &shape, T *storage, StorageInitPolicy policy=COPY)
Create an Matrix of a given shape from a pointer.
size_t yinc() const
Definition Matrix.h:312
const T & operator()(size_t i1, size_t i2) const
Definition Matrix.h:195
virtual size_t fixedDimensionality() const override
Subclasses can return their dimensionality.
Definition Matrix.h:305
const Matrix< T > operator()(const Slice &sliceX, const Slice &sliceY) const
StorageInitPolicy
Definition ArrayBase.h:48
@ COPY
COPY is used when an internal copy of the storage is to be made.
Definition ArrayBase.h:51
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
T * storage()
If you really, really, need a "raw" pointer to the beginning of the storage area this will give it to...
Definition Block.h:559
LatticeExprNode mask(const LatticeExprNode &expr)
This function returns the mask of the given expression.
Array< LogicalArrayElem > LogicalArray
Definition ArrayFwd.h:17
MaskedArray< LogicalArrayElem > MaskedLogicalArray
Definition ArrayFwd.h:20
TableExprNode marray(const TableExprNode &array, const TableExprNode &mask)
Form a masked array.
Definition ExprNode.h:1567
This is a tag for the constructor that may be used to construct an uninitialized Array.
Definition Array.h:180