@@ -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