Skip to content

Commit 5d0d23a

Browse files
committed
Add unit tests for TypeTensor::is_hpd()
1 parent 0600cdb commit 5d0d23a

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

tests/numerics/type_tensor_test.C

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public:
2424
#endif
2525
CPPUNIT_TEST(testRowCol);
2626
CPPUNIT_TEST(testIsZero);
27+
CPPUNIT_TEST(testIsHPD);
2728
#ifdef LIBMESH_HAVE_METAPHYSICL
2829
CPPUNIT_TEST(testReplaceAlgebraicType);
2930
#endif
@@ -104,6 +105,87 @@ private:
104105
}
105106
}
106107

108+
void testIsHPD()
109+
{
110+
LOG_UNIT_TEST;
111+
112+
{
113+
#if LIBMESH_DIM == 3
114+
{
115+
TensorValue<double> tensor(2., 1., 0.,
116+
1., 2., 1.,
117+
0., 1., 2.);
118+
119+
CPPUNIT_ASSERT(tensor.is_hpd(/*rel_tol=*/0.));
120+
}
121+
{
122+
// Symmetric but not positive-definite, because the upper 2x2
123+
// principal minor is zero.
124+
TensorValue<double> tensor(1, 0., 0.,
125+
0., 0., 1.,
126+
0., 1., 0.);
127+
128+
CPPUNIT_ASSERT(!tensor.is_hpd());
129+
}
130+
{
131+
// Random matrix that is SPD by construction
132+
133+
auto get_random = [&]()
134+
{
135+
return static_cast<Real>(std::rand()) / RAND_MAX; // in range [0,1]
136+
};
137+
138+
TensorValue<double> tensor(get_random(), get_random(), get_random(),
139+
get_random(), get_random(), get_random(),
140+
get_random(), get_random(), get_random());
141+
142+
// Make symmetric
143+
tensor = 0.5*(tensor + tensor.transpose());
144+
145+
// Make positive definite
146+
for (auto i : make_range(LIBMESH_DIM))
147+
tensor(i,i) += 3.;
148+
149+
CPPUNIT_ASSERT(tensor.is_hpd());
150+
}
151+
152+
#ifdef LIBMESH_USE_COMPLEX_NUMBERS
153+
154+
auto i = Complex(0, 1);
155+
auto one = Complex(1, 0);
156+
{
157+
// Symmetric but not Hermitian, because Hermitian matrices must
158+
// have real-valued entries on the diagonal.
159+
TensorValue<Complex> tensor(i, 0., 0.,
160+
0., 1., 0.,
161+
0., 0., 1.);
162+
163+
CPPUNIT_ASSERT(!tensor.is_hpd());
164+
}
165+
{
166+
// Symmetric but not Hermitian, because the off-diagonal
167+
// entries must be complex conjugates of one another.
168+
TensorValue<Complex> tensor(2, i, 0.,
169+
i, 2., i,
170+
0., i, 2.);
171+
172+
CPPUNIT_ASSERT(!tensor.is_hpd());
173+
}
174+
{
175+
// Both Hermitian and positive-definite
176+
TensorValue<Complex> tensor(2., one+i, 0.,
177+
one-i, 2., one+i,
178+
0., one-i, 2.);
179+
180+
CPPUNIT_ASSERT(tensor.is_hpd());
181+
}
182+
183+
#endif
184+
185+
#endif // LIBMESH_DIM == 3
186+
}
187+
}
188+
107189
void testRotation()
108190
{
109191
LOG_UNIT_TEST;

0 commit comments

Comments
 (0)