MatrixI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "MatrixBlock.H"
30 
31 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
32 
33 template<class Form, class Type>
35 {
36  const label len = size();
37 
38  if (len)
39  {
40  v_ = new Type[len];
41  }
42 }
43 
44 
45 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
46 
47 template<class Form, class Type>
49 :
50  mRows_(0),
51  nCols_(0),
52  v_(nullptr)
53 {}
54 
55 
56 template<class Form, class Type>
58 :
59  Matrix<Form, Type>(dims.first(), dims.second())
60 {}
61 
62 
63 template<class Form, class Type>
65 :
66  Matrix<Form, Type>(dims.first(), dims.second(), Zero)
67 {}
68 
69 
70 template<class Form, class Type>
71 inline Foam::Matrix<Form, Type>::Matrix(const labelPair& dims, const Type& val)
72 :
73  Matrix<Form, Type>(dims.first(), dims.second(), val)
74 {}
75 
76 
77 template<class Form, class Type>
80 {
81  return autoPtr<Matrix<Form, Type>>::New(*this);
82 }
83 
84 
85 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
86 
87 template<class Form, class Type>
89 {
90  return NullObjectRef<Matrix<Form, Type>>();
91 }
92 
93 
94 template<class Form, class Type>
95 inline Foam::label Foam::Matrix<Form, Type>::m() const noexcept
96 {
97  return mRows_;
98 }
99 
100 
101 template<class Form, class Type>
102 inline Foam::label Foam::Matrix<Form, Type>::n() const noexcept
103 {
104  return nCols_;
105 }
106 
107 
108 template<class Form, class Type>
109 inline Foam::label Foam::Matrix<Form, Type>::size() const
110 {
111  return mRows_ * nCols_;
112 }
113 
114 
115 template<class Form, class Type>
117 {
118  return labelPair(mRows_, nCols_);
119 }
120 
121 
122 template<class Form, class Type>
123 inline bool Foam::Matrix<Form, Type>::empty() const noexcept
124 {
125  return !mRows_ || !nCols_;
126 }
127 
128 
129 template<class Form, class Type>
130 inline void Foam::Matrix<Form, Type>::checki(const label i) const
131 {
132  if (!mRows_ || !nCols_)
133  {
135  << "Attempt to access element from empty matrix"
136  << abort(FatalError);
137  }
138  if (i < 0 || mRows_ <= i)
139  {
141  << "Index " << i << " out of range 0 ... " << mRows_-1
142  << abort(FatalError);
143  }
144 }
145 
146 
147 template<class Form, class Type>
148 inline void Foam::Matrix<Form, Type>::checkj(const label j) const
149 {
150  if (!mRows_ || !nCols_)
151  {
153  << "Attempt to access element from empty matrix"
154  << abort(FatalError);
155  }
156  if (j < 0 || nCols_ <= j)
157  {
159  << "index " << j << " out of range 0 ... " << nCols_-1
160  << abort(FatalError);
161  }
162 }
163 
164 
165 template<class Form, class Type>
167 {
168  if (mRows_ < 0 || nCols_ < 0)
169  {
171  << "Incorrect size (" << mRows_ << ", " << nCols_ << ')' << nl
172  << abort(FatalError);
173  }
174  // Could also check for odd sizes, like (0, N) and make (0,0)
175 }
176 
177 
178 template<class Form, class Type>
180 {
181  const label len = size();
182 
183  if (len == 0)
184  {
185  return false;
186  }
187 
188  for (label idx = 1; idx < len; ++idx)
189  {
190  if (v_[0] != v_[idx])
191  {
192  return false;
193  }
194  }
195 
196  return true;
197 }
198 
199 
200 template<class Form, class Type>
201 inline const Type* Foam::Matrix<Form, Type>::cdata() const noexcept
202 {
203  return v_;
204 }
205 
206 
207 template<class Form, class Type>
208 inline Type* Foam::Matrix<Form, Type>::data() noexcept
209 {
210  return v_;
211 }
212 
213 
214 template<class Form, class Type>
215 inline const Type* Foam::Matrix<Form, Type>::rowData(const label irow) const
216 {
217  #ifdef FULLDEBUG
218  checki(irow);
219  #endif
220  return (v_ + irow*nCols_);
221 }
222 
223 
224 template<class Form, class Type>
225 inline Type* Foam::Matrix<Form, Type>::rowData(const label irow)
226 {
227  #ifdef FULLDEBUG
228  checki(irow);
229  #endif
230  return (v_ + irow*nCols_);
231 }
232 
233 
234 template<class Form, class Type>
235 inline const Type& Foam::Matrix<Form, Type>::at(const label idx) const
236 {
237  #ifdef FULLDEBUG
238  if (idx < 0 || this->size() <= idx)
239  {
241  << "index " << idx << " out of range 0 ... " << this->size()
242  << abort(FatalError);
243  }
244  #endif
245  return *(v_ + idx);
246 }
247 
248 
249 template<class Form, class Type>
250 inline Type& Foam::Matrix<Form, Type>::at(const label idx)
251 {
252  #ifdef FULLDEBUG
253  if (idx < 0 || this->size() <= idx)
254  {
256  << "index " << idx << " out of range 0 ... " << this->size()
257  << abort(FatalError);
258  }
259  #endif
260  return *(v_ + idx);
261 }
262 
263 
264 template<class Form, class Type>
267 (
268  const label colIndex,
269  const label rowIndex,
270  label len
271 ) const
272 {
273  if (len < 0)
274  {
275  len = mRows_ - rowIndex;
276  }
277 
279  (
280  *this,
281  len, // rows
282  1,
283  rowIndex,
284  colIndex
285  );
286 }
287 
288 
289 template<class Form, class Type>
292 (
293  const label rowIndex,
294  const label colIndex,
295  label len
296 ) const
297 {
298  if (len < 0)
299  {
300  len = nCols_ - colIndex;
301  }
302 
304  (
305  *this,
306  1,
307  len, // columns
308  rowIndex,
309  colIndex
310  );
311 }
312 
313 
314 template<class Form, class Type>
317 (
318  const label rowIndex,
319  const label colIndex,
320  label szRows,
321  label szCols
322 ) const
323 {
324  if (szRows < 0) szRows = mRows_ - rowIndex;
325  if (szCols < 0) szCols = nCols_ - colIndex;
326 
328  (
329  *this,
330  szRows,
331  szCols,
332  rowIndex,
333  colIndex
334  );
335 }
336 
337 
338 template<class Form, class Type>
339 template<class VectorSpace>
342 (
343  const label rowIndex,
344  const label colIndex
345 ) const
346 {
348  (
349  *this,
350  VectorSpace::mRows,
351  VectorSpace::nCols,
352  rowIndex,
353  colIndex
354  );
355 }
356 
357 
358 template<class Form, class Type>
361 (
362  const label colIndex,
363  const label rowIndex,
364  label len
365 )
366 {
367  if (len < 0)
368  {
369  len = mRows_ - rowIndex;
370  }
371 
372  return MatrixBlock<mType>
373  (
374  *this,
375  len, // rows
376  1,
377  rowIndex,
378  colIndex
379  );
380 }
381 
382 
383 template<class Form, class Type>
386 (
387  const label rowIndex,
388  const label colIndex,
389  label len
390 )
391 {
392  if (len < 0)
393  {
394  len = nCols_ - colIndex;
395  }
396 
397  return MatrixBlock<mType>
398  (
399  *this,
400  1,
401  len, // columns
402  rowIndex,
403  colIndex
404  );
405 }
406 
407 
408 template<class Form, class Type>
411 (
412  const label rowIndex,
413  const label colIndex,
414  label szRows,
415  label szCols
416 )
417 {
418  if (szRows < 0) szRows = mRows_ - rowIndex;
419  if (szCols < 0) szCols = nCols_ - colIndex;
420 
421  return MatrixBlock<mType>
422  (
423  *this,
424  szRows,
425  szCols,
426  rowIndex,
427  colIndex
428  );
429 }
430 
431 
432 template<class Form, class Type>
433 template<class VectorSpace>
436 (
437  const label rowIndex,
438  const label colIndex
439 )
440 {
441  return MatrixBlock<mType>
442  (
443  *this,
444  VectorSpace::mRows,
445  VectorSpace::nCols,
446  rowIndex,
447  colIndex
448  );
449 }
450 
451 
452 template<class Form, class Type>
453 inline void Foam::Matrix<Form, Type>::setSize(const label m, const label n)
454 {
455  resize(m, n);
456 }
457 
458 
459 template<class Form, class Type>
460 void Foam::Matrix<Form, Type>::shallowResize(const label m, const label n)
461 {
462  mRows_ = m;
463  nCols_ = n;
464 }
465 
466 
467 template<class Form, class Type>
469 (
470  const UList<Type>& x
471 ) const
472 {
473  return this->AmulImpl(x);
474 }
475 
476 
477 template<class Form, class Type>
478 template<class Addr>
480 (
482 ) const
483 {
484  return this->AmulImpl(x);
485 }
486 
487 
488 template<class Form, class Type>
490 (
491  const UList<Type>& x
492 ) const
493 {
494  return this->TmulImpl(x);
495 }
496 
497 
498 template<class Form, class Type>
499 template<class Addr>
501 (
503 ) const
504 {
505  return this->TmulImpl(x);
506 }
507 
508 
509 // * * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * //
510 
511 template<class Form, class Type>
514 {
515  return v_;
516 }
517 
518 
519 template<class Form, class Type>
522 {
523  return v_ + (mRows_ * nCols_);
524 }
525 
526 
527 template<class Form, class Type>
530 {
531  return v_;
532 }
533 
534 
535 template<class Form, class Type>
538 {
539  return v_ + (mRows_ * nCols_);
540 }
541 
542 
543 template<class Form, class Type>
546 {
547  return v_;
548 }
549 
550 
551 template<class Form, class Type>
554 {
555  return v_ + (mRows_ * nCols_);
556 }
557 
558 
559 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
560 
561 template<class Form, class Type>
562 inline const Type& Foam::Matrix<Form, Type>::operator()
563 (
564  const label irow,
565  const label jcol
566 ) const
567 {
568  #ifdef FULLDEBUG
569  checki(irow);
570  checkj(jcol);
571  #endif
572  return v_[irow*nCols_ + jcol];
573 }
574 
575 
576 template<class Form, class Type>
578 (
579  const label irow,
580  const label jcol
581 )
582 {
583  #ifdef FULLDEBUG
584  checki(irow);
585  checkj(jcol);
586  #endif
587  return v_[irow*nCols_ + jcol];
588 }
589 
590 
591 template<class Form, class Type>
592 inline const Type* Foam::Matrix<Form, Type>::operator[](const label irow) const
593 {
594  #ifdef FULLDEBUG
595  checki(irow);
596  #endif
597  return v_ + irow*nCols_;
598 }
599 
600 
601 template<class Form, class Type>
602 inline Type* Foam::Matrix<Form, Type>::operator[](const label irow)
603 {
604  #ifdef FULLDEBUG
605  checki(irow);
606  #endif
607  return v_ + irow*nCols_;
608 }
609 
610 
611 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
612 
613 namespace Foam
614 {
615 
616 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
617 
618 //- Matrix-vector multiplication (A * x), where x is a column vector
619 template<class Form, class Type>
620 inline tmp<Field<Type>> operator*
621 (
622  const Matrix<Form, Type>& mat,
623  const UList<Type>& x
624 )
625 {
626  return mat.Amul(x);
627 }
628 
629 
630 //- Matrix-vector multiplication (A * x), where x is a column vector
631 template<class Form, class Type, class Addr>
632 inline tmp<Field<Type>> operator*
633 (
634  const Matrix<Form, Type>& mat,
636 )
637 {
638  return mat.Amul(x);
639 }
640 
641 
642 //- Vector-Matrix multiplication (x * A), where x is a row vector
643 template<class Form, class Type>
644 inline tmp<Field<Type>> operator*
645 (
646  const UList<Type>& x,
647  const Matrix<Form, Type>& mat
648 )
649 {
650  return mat.Tmul(x);
651 }
652 
653 
654 //- Vector-Matrix multiplication (x * A), where x is a row vector
655 template<class Form, class Type, class Addr>
656 inline tmp<Field<Type>> operator*
657 (
659  const Matrix<Form, Type>& mat
660 )
661 {
662  return mat.Tmul(x);
663 }
664 
665 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
666 
667 } // End namespace Foam
668 
669 // ************************************************************************* //
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::Matrix::n
label n() const noexcept
The number of columns.
Definition: MatrixI.H:102
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::Matrix::clone
autoPtr< mType > clone() const
Clone.
Definition: MatrixI.H:79
Foam::Matrix::Tmul
tmp< Field< Type > > Tmul(const UList< Type > &x) const
Left-multiply Matrix by a row vector (x * A)
Definition: MatrixI.H:490
Foam::Matrix::checkj
void checkj(const label jcol) const
Check index j is within valid range [0, n)
Definition: MatrixI.H:148
Foam::Matrix::sizes
labelPair sizes() const
Return row/column sizes.
Definition: MatrixI.H:116
Foam::Matrix
A templated (m x n) matrix of objects of <T>. The layout is (mRows x nCols) - row-major order:
Definition: DiagonalMatrix.H:53
Foam::labelPair
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:54
Foam::Matrix::data
Type * data() noexcept
Definition: MatrixI.H:208
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::Matrix::cend
const_iterator cend() const
Return const_iterator to end traversing a constant Matrix.
Definition: MatrixI.H:537
resize
patchWriters resize(patchIds.size())
Foam::Matrix::at
const Type & at(const label idx) const
Linear addressing const element access.
Definition: MatrixI.H:235
Foam::MatrixBlock
A templated block of an (m x n) matrix of type <MatrixType>.
Definition: Matrix.H:66
Foam::Matrix::subRow
ConstMatrixBlock< mType > subRow(const label rowIndex, const label colIndex=0, label len=-1) const
Return const row or const row's subset of Matrix.
Definition: MatrixI.H:292
Foam::Matrix::empty
bool empty() const noexcept
Return true if Matrix is empty (i.e., size() is zero)
Definition: MatrixI.H:123
Foam::Matrix::subMatrix
ConstMatrixBlock< mType > subMatrix(const label rowIndex, const label colIndex, label szRows=-1, label szCols=-1) const
Return const sub-block of Matrix.
Definition: MatrixI.H:317
Foam::Matrix::rowData
const Type * rowData(const label irow) const
Return const pointer to data in the specified row.
Definition: MatrixI.H:215
Foam::Matrix::iterator
Type * iterator
Random access iterator for traversing a Matrix.
Definition: Matrix.H:117
Foam::Matrix::shallowResize
void shallowResize(const label m, const label n)
Resize Matrix without reallocating storage (unsafe)
Definition: MatrixI.H:460
Foam::FatalError
error FatalError
Foam::Matrix::size
label size() const
The number of elements in Matrix (m*n)
Definition: MatrixI.H:109
Foam::Matrix::operator[]
const Type * operator[](const label irow) const
Return const pointer to data in the specified row - rowData().
Definition: MatrixI.H:592
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
MatrixBlock.H
Foam::Matrix::begin
iterator begin()
Return an iterator to begin traversing a Matrix.
Definition: MatrixI.H:513
Foam::Matrix::end
iterator end()
Return an iterator to end traversing a Matrix.
Definition: MatrixI.H:521
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::Matrix::Amul
tmp< Field< Type > > Amul(const UList< Type > &x) const
Right-multiply Matrix by a column vector (A * x)
Definition: MatrixI.H:469
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::Matrix::uniform
bool uniform() const
True if all entries have identical values, and Matrix is non-empty.
Definition: MatrixI.H:179
Foam::Matrix::m
label m() const noexcept
The number of rows.
Definition: MatrixI.H:95
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::Pair< label >
Foam::Matrix::checki
void checki(const label irow) const
Check index i is within valid range [0, m)
Definition: MatrixI.H:130
Foam::Matrix::checkSize
void checkSize() const
Check that dimensions are positive, non-zero.
Definition: MatrixI.H:166
Foam::Matrix::setSize
void setSize(const label m, const label n)
Change Matrix dimensions, preserving the elements.
Definition: MatrixI.H:453
Foam::Matrix::null
static const Matrix< Form, Type > & null()
Return a null Matrix.
Definition: MatrixI.H:88
Foam::Matrix::cbegin
const_iterator cbegin() const
Return const_iterator to begin traversing a constant Matrix.
Definition: MatrixI.H:529
Foam::Matrix::cdata
const Type * cdata() const noexcept
Definition: MatrixI.H:201
Foam::UList< Type >
Foam::Matrix::block
ConstMatrixBlock< mType > block(const label rowIndex, const label colIndex) const
Access Field as a ConstMatrixBlock.
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::ConstMatrixBlock
Definition: Matrix.H:65
Foam::Matrix::subColumn
ConstMatrixBlock< mType > subColumn(const label colIndex, const label rowIndex=0, label len=-1) const
Return const column or column's subset of Matrix.
Definition: MatrixI.H:267
Foam::IndirectListBase
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
Definition: IndirectListBase.H:56
Foam::Matrix::Matrix
Matrix()
Construct null.
Definition: MatrixI.H:48
Foam::zero
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:62