casacore
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: aips2-request@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 //# $Id$
27 
28 #ifndef CASA_MATRIX_2_H
29 #define CASA_MATRIX_2_H
30 
31 //# Includes
32 #include "Array.h"
33 
34 namespace casacore { //#Begin casa namespace
35 
36 // <summary> A 2-D Specialization of the Array class </summary>
37 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
38 // </reviewed>
39 //
40 // Matrix objects are two-dimensional specializations (e.g., more convenient
41 // and efficient indexing) of the general Array class. You might also want
42 // to look at the Array documentation to see inherited functionality. A
43 // tutorial on using the array classes in general is available in the
44 // "AIPS++ Programming Manual".
45 //
46 // Generally the member functions of Array are also available in
47 // Matrix versions which take a pair of integers where the array
48 // needs an IPosition. Since the Matrix
49 // is two-dimensional, the IPositions are overkill, although you may
50 // use those versions if you want to.
51 // <srcblock>
52 // Matrix<int> mi(100,100); // Shape is 100x100
53 // mi.resize(50,50); // Shape now 50x50
54 // </srcblock>
55 //
56 // Slices may be taken with the Slice class. To take a slice, one "indexes"
57 // with one Slice(start, length, inc) for each axis,
58 // where end and inc are optional.
59 // Additionally, there are row(), column() and diagonal()
60 // member functions which return Vector's which refer to the storage back
61 // in the Matrix:
62 // <srcblock>
63 // Matrix<float> mf(100, 100);
64 // mf.diagonal() = 1;
65 // </srcblock>
66 //
67 // Correct indexing order of a matrix is:
68 // <srcblock>
69 // Matrix<int> mi(n1,n2) // [nrow, ncolumn]
70 // for (size_t j=0; j<mi.ncolumn(); j++) {
71 // for (size_t i=0; i<mi.nrow(); i++) {
72 // mi(i,j) = i*j;
73 // }
74 // }
75 // </srcblock>
76 //
77 //
78 // Element-by-element arithmetic and logical operations are available (in
79 // aips/ArrayMath.h and aips/ArrayLogical.h). Other Matrix operations (e.g.
80 // LU decomposition) are available, and more appear periodically.
81 //
82 // As with the Arrays, if the preprocessor symbol AIPS_DEBUG is
83 // defined at compile time invariants will be checked on entry to most
84 // member functions. Additionally, if AIPS_ARRAY_INDEX_CHECK is defined
85 // index operations will be bounds-checked. Neither of these should
86 // be defined for production code.
87 
88 template<typename T, typename Alloc> class Matrix : public Array<T, Alloc>
89 {
90 public:
91  // A Matrix of length zero in each dimension; zero origin.
92  Matrix(const Alloc& allocator = Alloc());
93 
94  // A Matrix with "l1" rows and "l2" columns.
95  // Fill it with the initial value.
96  Matrix(size_t l1, size_t l2, const T &initialValue = T(), const Alloc& allocator = Alloc());
97 
98  // An uninitialized Matrix with "l1" rows and "l2" columns.
99  Matrix(size_t l1, size_t l2, typename Array<T, Alloc>::uninitializedType, const Alloc& allocator = Alloc());
100 
101  // A matrix of shape with shape "len".
102  // Fill it with the initial value.
103  Matrix(const IPosition &len, const T &initialValue = T(), const Alloc& allocator = Alloc());
104 
105  // An uninitialized matrix of shape with shape "len".
106  Matrix(const IPosition &len, typename Array<T, Alloc>::uninitializedType, const Alloc& allocator = Alloc());
107 
108  // The copy/move constructor uses reference semantics.
109  Matrix(const Matrix<T, Alloc>& source);
111 
112  // Construct a Matrix by reference from "source". "source must have
113  // ndim() of 2 or less.
114  Matrix(const Array<T, Alloc>& source);
116 
117  // Create an Matrix of a given shape from a pointer.
118  Matrix(const IPosition &shape, T *storage, StorageInitPolicy policy = COPY, const Alloc& allocator = Alloc());
119  // Create an Matrix of a given shape from a pointer. Because the pointer
120  // is const, a copy is always made.
121  Matrix(const IPosition &shape, const T *storage);
122 
123  // Create an identity matrix of side length n. (Could not do this as a constructor
124  // because of ambiguities with other constructors).
125  static Matrix<T, Alloc> identity (size_t n);
126 
127  // Resize to the given shape
128  // <group>
130  void resize(size_t nx, size_t ny, bool copyValues=false);
131  // </group>
132 
134  { return assign_conforming(source); }
136  { return assign_conforming(std::move(source)); }
138  { return assign_conforming(source); }
140  { return assign_conforming(std::move(source)); }
141 
142  // Copy the values from other to this Matrix. If this matrix has zero
143  // elements then it will resize to be the same shape as other; otherwise
144  // other must conform to this.
145  // Note that the assign function can be used to assign a
146  // non-conforming matrix.
147  // <group>
149  { Array<T, Alloc>::assign_conforming(source); return *this; }
151  { Array<T, Alloc>::assign_conforming(std::move(source)); return *this; }
152 
154  {
155  // TODO Should be supported by the Array class,
156  // see Cube::operator=(const Array&)
157 
158  if (source.ndim() == 2) {
160  } else {
161  // This might work if a.ndim == 1 or 2
162  (*this) = Matrix<T, Alloc>(source);
163  }
164  return *this;
165  }
166 
168  {
169  if (source.ndim() == 2) {
170  Array<T, Alloc>::assign_conforming(std::move(source));
171  } else {
172  (*this) = Matrix<T, Alloc>(std::move(source));
173  }
174  return *this;
175  }
176  // </group>
177 
178  // Copy val into every element of this Matrix; i.e. behaves as if
179  // val were a constant conformant matrix.
180  Array<T, Alloc>& operator=(const T &val)
181  { return Array<T, Alloc>::operator=(val); }
182 
183  // Copy to this those values in marray whose corresponding elements
184  // in marray's mask are true.
186  { Array<T, Alloc>::assign_conforming(marray); return *this; }
187 
188  // Single-pixel addressing. If AIPS_ARRAY_INDEX_CHECK is defined,
189  // bounds checking is performed.
190  // <group>
191  T &operator()(const IPosition &i)
192  { return Array<T, Alloc>::operator()(i); }
193  const T &operator()(const IPosition &i) const
194  { return Array<T, Alloc>::operator()(i); }
195  T &operator()(size_t i1, size_t i2)
196  {
197  return this->contiguous_p ? this->begin_p[i1 + i2*yinc()] :
198  this->begin_p[i1*xinc() + i2*yinc()];
199  }
200 
201  const T &operator()(size_t i1, size_t i2) const
202  {
203  return this->contiguous_p ? this->begin_p[i1 + i2*yinc()] :
204  this->begin_p[i1*xinc() + i2*yinc()];
205  }
206  // </group>
207 
208 
209  // The array is masked by the input LogicalArray.
210  // This mask must conform to the array.
211  // <group>
212 
213  // Return a MaskedArray.
216 
217  // Return a MaskedArray.
220 
221  // </group>
222 
223 
224  // The array is masked by the input MaskedLogicalArray.
225  // The mask is effectively the AND of the internal LogicalArray
226  // and the internal mask of the MaskedLogicalArray.
227  // The MaskedLogicalArray must conform to the array.
228  // <group>
229 
230  // Return a MaskedArray.
233 
234  // Return a MaskedArray.
237 
238  // </group>
239 
240 
241  // Returns a reference to the i'th row.
242  // <group>
244  const Vector<T, Alloc> row(size_t i) const;
245  // </group>
246 
247  // Returns a reference to the j'th column
248  // <group>
250  const Vector<T, Alloc> column(size_t j) const;
251  // </group>
252 
253  // Returns a diagonal from the Matrix. The Matrix must be square.
254  // n==0 is the main diagonal. n>0 is above the main diagonal, n<0
255  // is below it.
256  // <group>
257  Vector<T, Alloc> diagonal(long long n=0);
258  const Vector<T, Alloc> diagonal(long long n=0) const;
259  // </group>
260 
261  // Take a slice of this matrix. Slices are always indexed starting
262  // at zero. This uses reference semantics, i.e. changing a value
263  // in the slice changes the original.
264  // <srcblock>
265  // Matrix<double> vd(100,100);
266  // //...
267  // vd(Slice(0,10),Slice(10,10)) = -1.0; // 10x10 sub-matrix set to -1.0
268  // </srcblock>
269  // <group>
270  Matrix<T, Alloc> operator()(const Slice &sliceX, const Slice &sliceY);
271  const Matrix<T, Alloc> operator()(const Slice &sliceX, const Slice &sliceY) const;
272  // </group>
273 
274  // Slice using IPositions. Required to be defined, otherwise the base
275  // class versions are hidden.
276  // <group>
278  const IPosition &incr)
279  { return Array<T, Alloc>::operator()(blc,trc,incr); }
280  const Array<T, Alloc> operator()(const IPosition &blc, const IPosition &trc,
281  const IPosition &incr) const
282  { return Array<T, Alloc>::operator()(blc,trc,incr); }
284  { return Array<T, Alloc>::operator()(blc,trc); }
285  const Array<T, Alloc> operator()(const IPosition &blc, const IPosition &trc) const
286  { return Array<T, Alloc>::operator()(blc,trc); }
288  { return Array<T, Alloc>::operator()(slicer); }
289  const Array<T, Alloc> operator()(const Slicer& slicer) const
290  { return Array<T, Alloc>::operator()(slicer); }
291  // </group>
292 
293  // The length of each axis of the Matrix.
294  const IPosition &shape() const
295  { return this->length_p; }
296  void shape(int &s1, int &s2) const
297  { s1 = this->length_p(0); s2=this->length_p(1); }
298 
299  // The number of rows in the Matrix, i.e. the length of the first axis.
300  size_t nrow() const
301  { return this->length_p(0); }
302 
303  // The number of columns in the Matrix, i.e. the length of the 2nd axis.
304  size_t ncolumn() const
305  { return this->length_p(1); }
306 
307  // Checks that the Matrix is consistent (invariants check out).
308  virtual bool ok() const override;
309 
310 protected:
311  virtual void preTakeStorage(const IPosition &shape) override;
312  // Remove the degenerate axes from other and store result in this matrix.
313  // An exception is thrown if removing degenerate axes does not result
314  // in a matrix.
315  virtual void doNonDegenerate(const Array<T, Alloc> &other,
316  const IPosition &ignoreAxes) override;
317 
318  virtual size_t fixedDimensionality() const override { return 2; }
319 
320 private:
321  // Cached constants to improve indexing.
322  // size_t xinc_p, yinc_p;
323 
324  size_t xinc() const { return this->inc_p(0); }
325  size_t yinc() const { return this->inc_p(1)*this->originalLength_p(0); }
326 };
327 
328 //# Declare extern templates for often used types.
329  extern template class Matrix<bool>;
330  extern template class Matrix<float>;
331  extern template class Matrix<double>;
332 
333 } //#End casa namespace
334 
335 #include "Matrix.tcc"
336 
337 #endif
size_t ndim() const
The dimensionality of this array.
Definition: ArrayBase.h:98
bool contiguous_p
Are the data contiguous?
Definition: ArrayBase.h:273
IPosition originalLength_p
Definition: ArrayBase.h:276
IPosition length_p
Used to hold the shape, increment into the underlying storage and originalLength of the array.
Definition: ArrayBase.h:276
T & operator()(const IPosition &)
Access a single element of the array.
T * begin_p
This pointer is adjusted to point to the first element of the array.
Definition: Array.h:986
Alloc & allocator()
Retrieve the allocator associated with this array.
Definition: Array.h:234
Array< T, Alloc > & operator=(const Array< T, Alloc > &other)
TODO we should change the semantics.
Definition: Array.h:300
Array< T, Alloc > & assign_conforming(const Array< T, Alloc > &other)
Copy the values in other to this.
Definition: Array.h:285
Matrix< T, Alloc > & assign_conforming(Matrix< T, Alloc > &&source)
Definition: Matrix.h:150
const Vector< T, Alloc > row(size_t i) const
Matrix< T, Alloc > & operator=(Array< T, Alloc > &&source)
Definition: Matrix.h:139
Array< T, Alloc > operator()(const Slicer &slicer)
Definition: Matrix.h:287
virtual size_t fixedDimensionality() const override
Subclasses can return their dimensionality.
Definition: Matrix.h:318
Matrix< T, Alloc > & 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:185
Array< T, Alloc > operator()(const IPosition &blc, const IPosition &trc, const IPosition &incr)
Slice using IPositions.
Definition: Matrix.h:277
Matrix< T, Alloc > & assign_conforming(Array< T, Alloc > &&source)
Definition: Matrix.h:167
Matrix< T, Alloc > operator()(const Slice &sliceX, const Slice &sliceY)
Take a slice of this matrix.
void shape(int &s1, int &s2) const
Definition: Matrix.h:296
const IPosition & shape() const
The length of each axis of the Matrix.
Definition: Matrix.h:294
Matrix< T, Alloc > & assign_conforming(const Array< T, Alloc > &source)
Definition: Matrix.h:153
const T & operator()(const IPosition &i) const
Definition: Matrix.h:193
Matrix(const IPosition &len, const T &initialValue=T(), const Alloc &allocator=Alloc())
A matrix of shape with shape "len".
Vector< T, Alloc > row(size_t i)
Returns a reference to the i'th row.
size_t ncolumn() const
The number of columns in the Matrix, i.e.
Definition: Matrix.h:304
const Array< T, Alloc > operator()(const IPosition &blc, const IPosition &trc, const IPosition &incr) const
Definition: Matrix.h:280
const Vector< T, Alloc > column(size_t j) const
Matrix(Matrix< T, Alloc > &&source)
Matrix< T, Alloc > & operator=(const Matrix< T, Alloc > &source)
Definition: Matrix.h:133
const Array< T, Alloc > operator()(const Slicer &slicer) const
Definition: Matrix.h:289
const Matrix< T, Alloc > operator()(const Slice &sliceX, const Slice &sliceY) const
size_t nrow() const
The number of rows in the Matrix, i.e.
Definition: Matrix.h:300
Matrix(size_t l1, size_t l2, const T &initialValue=T(), const Alloc &allocator=Alloc())
A Matrix with "l1" rows and "l2" columns.
virtual bool ok() const override
Checks that the Matrix is consistent (invariants check out).
virtual void doNonDegenerate(const Array< T, Alloc > &other, const IPosition &ignoreAxes) override
Remove the degenerate axes from other and store result in this matrix.
size_t yinc() const
Definition: Matrix.h:325
T & operator()(const IPosition &i)
Single-pixel addressing.
Definition: Matrix.h:191
const T & operator()(size_t i1, size_t i2) const
Definition: Matrix.h:201
Matrix(Array< T, Alloc > &&source)
static Matrix< T, Alloc > identity(size_t n)
Create an identity matrix of side length n.
Matrix(const IPosition &shape, T *storage, StorageInitPolicy policy=COPY, const Alloc &allocator=Alloc())
Create an Matrix of a given shape from a pointer.
const Vector< T, Alloc > diagonal(long long n=0) const
Matrix(const IPosition &shape, const T *storage)
Create an Matrix of a given shape from a pointer.
T & operator()(size_t i1, size_t i2)
Definition: Matrix.h:195
size_t xinc() const
Cached constants to improve indexing.
Definition: Matrix.h:324
Matrix< T, Alloc > & operator=(Matrix< T, Alloc > &&source)
Definition: Matrix.h:135
Matrix(const Matrix< T, Alloc > &source)
The copy/move constructor uses reference semantics.
Matrix< T, Alloc > & operator=(const Array< T, Alloc > &source)
Definition: Matrix.h:137
Matrix(const Array< T, Alloc > &source)
Construct a Matrix by reference from "source".
virtual void preTakeStorage(const IPosition &shape) override
pre/post processing hook of takeStorage() for subclasses.
Vector< T, Alloc > column(size_t j)
Returns a reference to the j'th column.
Matrix(size_t l1, size_t l2, typename Array< T, Alloc >::uninitializedType, const Alloc &allocator=Alloc())
An uninitialized Matrix with "l1" rows and "l2" columns.
Matrix< T, Alloc > & assign_conforming(const Matrix< T, Alloc > &source)
Copy the values from other to this Matrix.
Definition: Matrix.h:148
Matrix(const IPosition &len, typename Array< T, Alloc >::uninitializedType, const Alloc &allocator=Alloc())
An uninitialized matrix of shape with shape "len".
Matrix(const Alloc &allocator=Alloc())
A Matrix of length zero in each dimension; zero origin.
const Array< T, Alloc > operator()(const IPosition &blc, const IPosition &trc) const
Definition: Matrix.h:285
Vector< T, Alloc > diagonal(long long n=0)
Returns a diagonal from the Matrix.
Array< T, Alloc > operator()(const IPosition &blc, const IPosition &trc)
Definition: Matrix.h:283
Array< T, Alloc > & operator=(const T &val)
Copy val into every element of this Matrix; i.e.
Definition: Matrix.h:180
void resize(size_t nx, size_t ny, bool copyValues=false)
StorageInitPolicy
Definition: ArrayBase.h:51
@ COPY
COPY is used when an internal copy of the storage is to be made.
Definition: ArrayBase.h:54
this file contains all the compiler specific defines
Definition: mainpage.dox:28
LatticeExprNode mask(const LatticeExprNode &expr)
This function returns the mask of the given expression.
TableExprNode marray(const TableExprNode &array, const TableExprNode &mask)
Form a masked array.
Definition: ExprNode.h:1935
This is a tag for the constructor that may be used to construct an uninitialized Array.
Definition: Array.h:181