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 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>
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>
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>
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>
603 {
604  #ifdef FULLDEBUG
605  checki(irow);
606  #endif
607  return v_ + irow*nCols_;
608 }
609 
610 
611 template<class Form, class Type>
612 inline Foam::tmp<Foam::Field<Type>> Foam::operator*
613 (
614  const Matrix<Form, Type>& mat,
615  const UList<Type>& x
616 )
617 {
618  return mat.Amul(x);
619 }
620 
621 
622 template<class Form, class Type, class Addr>
623 inline Foam::tmp<Foam::Field<Type>> Foam::operator*
624 (
625  const Matrix<Form, Type>& mat,
626  const IndirectListBase<Type, Addr>& x
627 )
628 {
629  return mat.Amul(x);
630 }
631 
632 
633 template<class Form, class Type>
634 inline Foam::tmp<Foam::Field<Type>> Foam::operator*
635 (
636  const UList<Type>& x,
637  const Matrix<Form, Type>& mat
638 )
639 {
640  return mat.Tmul(x);
641 }
642 
643 
644 template<class Form, class Type, class Addr>
645 inline Foam::tmp<Foam::Field<Type>> Foam::operator*
646 (
647  const IndirectListBase<Type, Addr>& x,
648  const Matrix<Form, Type>& mat
649 )
650 {
651  return mat.Tmul(x);
652 }
653 
654 
655 // ************************************************************************* //
Foam::val
label ListType::const_reference val
Definition: ListOps.H:407
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:59
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
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:48
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
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
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::n
label n() const noexcept
The number of columns.
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::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
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:355
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:372
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:54
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:57
Foam::Matrix::Matrix
Matrix()
Construct null.
Definition: MatrixI.H:48
Foam::zero
A class representing the concept of 0 (zero), which can be used to avoid manipulating objects that ar...
Definition: zero.H:61