/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
Application
Test-SquareMatrix
Description
Tests for \c SquareMatrix constructors, member functions, member
operators, global functions, global operators, and friend functions using
\c floatScalar, \c doubleScalar, and \c complex base types.
Cross-checks were obtained from 'NumPy 1.15.1' if no theoretical
cross-check exists (like eigendecomposition relations), and
were hard-coded for elementwise comparisons.
For \c complex base type, the cross-checks do only involve zero imag part.
Note
Pending tests were tagged as "## Pending ##".
\*---------------------------------------------------------------------------*/
#include "scalarMatrices.H"
#include "RectangularMatrix.H"
#include "SquareMatrix.H"
#include "scalar.H"
#include "complex.H"
#include "IOmanip.H"
#include "TestTools.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Create each constructor of SquareMatrix, and print output
template
void test_constructors(Type)
{
{
Info<< "# Construct for given size (rows == cols):" << nl;
const SquareMatrix A(2);
Info<< A << endl;
}
{
Info<< "# Construct for given size (rows == cols) "
<< "initializing all elements to zero:" << nl;
const SquareMatrix A(2, Zero);
Info<< A << endl;
}
{
Info<< "# Construct for given size (rows == cols) "
<< "initializing all elements to a value:" << nl;
const SquareMatrix A(2, Type(3));
Info<< A << endl;
}
{
Info<< "# Construct for given size (rows == cols) "
<< "initializing to the identity matrix:" << nl;
const SquareMatrix A(2, I);
Info<< A << endl;
}
{
Info<< "# Construct for given size (rows == cols) by using a labelPair"
<< "initializing to the identity matrix:" << nl;
const SquareMatrix A(labelPair(2, 2), I);
Info<< A << endl;
}
{
Info<< "# Construct given number of rows/columns "
<< "by using a label pair (checked to be equal):" << nl;
const SquareMatrix A(labelPair(2, 2));
Info<< A << endl;
}
{
Info<< "# Construct given number of rows/columns "
<< "by using a label pair (checked to be equal) "
<< "and initializing all elements to zero:" << nl;
const SquareMatrix A(labelPair(2, 2), Zero);
Info<< A << endl;
}
{
Info<< "# Construct given number of rows/columns "
<< "by using a label pair (checked to be equal) "
<< "and initializing all elements to the given value:" << nl;
const SquareMatrix A(labelPair(2, 2), Type(3));
Info<< A << endl;
}
{
Info<< "# Construct given number of rows/columns "
<< "(checked to be equal) initializing all elements to zero" << nl;
const SquareMatrix A(2, 2, Zero);
Info<< A << endl;
}
{
Info<< "# Construct from const sub-matrix block:" << nl;
const SquareMatrix B(labelPair(3, 3), Type(3));
const SquareMatrix A(B.subMatrix(1, 1));
Info<< A << endl;
}
{
Info<< "# Construct from sub-matrix block:" << nl;
SquareMatrix B(labelPair(3, 3), Type(3));
const SquareMatrix A(B.subMatrix(1, 1));
Info<< A << endl;
}
{
Info<< "#: Construct as copy of a RectangularMatrix:" << nl;
const RectangularMatrix B(2, 2, Zero);
const SquareMatrix A(B);
Info<< A << endl;
}
// ## Pending ##
// Construct from Istream
// Clone
// #############
}
// Execute each member function of SquareMatrix, and print output
template
void test_member_funcs(Type)
{
SquareMatrix A(labelPair(3, 3), Zero);
assignMatrix
(
A,
{
Type(1), Type(-2.2), Type(-3.4),
Type(-0.35), Type(1), Type(5),
Type(-0.35), Type(1), Type(5)
}
);
Info<< "# Operand: " << nl
<< " SquareMatrix = " << A << endl;
{
Info<< "# Access:" << nl;
cmp(" The number of rows = ", Type(A.m()), Type(3));
cmp(" The number of columns = ", Type(A.n()), Type(3));
cmp(" The number of elements in Matrix = ", Type(A.size()), Type(9));
cmp(" Return row/column sizes = ", A.sizes(), labelPair(3, 3));
cmp(" Return true if Matrix is empty = ", A.empty(), false);
cmp
(
" Return const pointer to the first data elem = ",
*(A.cdata()),
Type(1)
);
cmp
(
" Return pointer to the first data elem = ",
*(A.data()),
Type(1)
);
cmp
(
" Return const pointer to data in the specified row = ",
*(A.rowData(1)),
Type(-0.35)
);
cmp
(
" Return pointer to data in the specified row = ",
*(A.rowData(1)),
Type(-0.35)
);
const Type& a = A.at(4);
cmp(" Linear addressing const element access = ", a, Type(1));
Type& b = A.at(4);
cmp(" Linear addressing element access = ", b, Type(1));
}
{
Info<< "# Block access (const):" << nl;
const RectangularMatrix Acol(A.subColumn(1));
cmp
(
" Return const column or column's subset of Matrix = ",
flt(Acol),
List({Type(-2.2), Type(1), Type(1)})
);
const RectangularMatrix Arow(A.subRow(1));
cmp
(
" Return const row or row's subset of Matrix = ",
flt(Arow),
List({Type(-0.35), Type(1), Type(5)})
);
const RectangularMatrix Amat(A.subMatrix(1, 1));
cmp
(
" Return const sub-block of Matrix = ",
flt(Amat),
List({Type(1), Type(5), Type(1), Type(5)})
);
}
{
Info<< "# Block access (non-const):" << nl;
RectangularMatrix Acol(A.subColumn(1));
cmp
(
" Return column or column's subset of Matrix = ",
flt(Acol),
List({Type(-2.2), Type(1), Type(1)})
);
RectangularMatrix Arow(A.subRow(1));
cmp
(
" Return row or row's subset of Matrix = ",
flt(Arow),
List({Type(-0.35), Type(1), Type(5)})
);
RectangularMatrix Amat(A.subMatrix(1, 1));
cmp
(
" Return sub-block of Matrix = ",
flt(Amat),
List({Type(1), Type(5), Type(1), Type(5)})
);
}
{
Info<< "# Check:" << nl;
A.checki(0);
A.checkj(1);
A.checkSize();
cmp(" Check all entries have identical values = ", A.uniform(), false);
{
Random rndGen(1234);
const label mRows = 10;
SquareMatrix B
(
makeRandomMatrix>(labelPair(mRows, mRows), rndGen)
);
// Symmetrise
for (label n = 0; n < B.n() - 1; ++n)
{
for (label m = B.m() - 1; n < m; --m)
{
B(n, m) = B(m, n);
}
}
cmp
(
" Return true if the square matrix is "
"effectively symmetric/Hermitian",
B.symmetric(),
true
);
}
// ## Pending ##
// Return true if the square matrix is reduced tridiagonal
// #############
}
{
Info<< "# Edit:" << nl;
SquareMatrix cpA0(A);
cpA0.clear();
cmp(" Clear Matrix, i.e. set sizes to zero = ", cpA0.empty(), true);
SquareMatrix cpA1(A);
cmp
(
" Release storage management of Matrix contents by transferring "
"management to a List = ",
(cpA1.release()),
List
({
Type(1), Type(-2.2), Type(-3.4),
Type(-0.35), Type(1), Type(5),
Type(-0.35), Type(1), Type(5)
})
);
SquareMatrix cpA2(A);
cpA2.swap(cpA1);
cmp(" Swap contents = ", flt(cpA1), flt(A));
cpA2.transfer(cpA1);
cmp
(
" Transfer the contents of the argument Matrix into this Matrix "
"and annul the argument MatrixSwap contents = ",
flt(cpA2),
flt(A)
);
cpA2.resize(2, 2);
cmp
(
" Change Matrix dimensions, preserving the elements = ",
flt(cpA2),
List({Type(1), Type(-2.2), Type(-0.35), Type(1)})
);
cpA2.resize(1);
cmp
(
" Resize the matrix preserving the elements = ",
flt(cpA2),
List({Type(1)})
);
SquareMatrix cpA3(A);
cpA3.setSize(2);
cmp
(
" Resize the matrix preserving the elements = ",
flt(cpA3),
List({Type(1), Type(-2.2), Type(-0.35), Type(1)})
);
SquareMatrix cpA4(A);
cpA4.shallowResize(2);
cmp
(
" Resize the matrix without reallocating storage (unsafe) = ",
flt(cpA4),
List({Type(1), Type(-2.2), Type(-3.4), Type(-0.35)})
);
SquareMatrix smallA(2, Type(VSMALL));
smallA.round();
cmp
(
" Round elements with mag smaller than tol (SMALL) to zero = ",
flt(smallA),
List(4, Zero)
);
}
{
Info<< "# Sort:" << nl;
SquareMatrix cpA(A);
auto descend = [&](Type a, Type b){ return mag(a) > mag(b); };
const List