12template <
class Type1,
class Type2,
class Element>
18 { verbose =
false; scale=1e3; tolerance = 1e-12; random_init(); }
20 virtual ~MatrixTest () {}
22 virtual void runtest (
unsigned nloops);
32template <
class T,
class U>
33T max (
const T& a,
const U& b)
41template <
class Type1,
class Type2,
class Element>
42void test_matrix (
const Type1& t1_1,
const Type1& t1_2,
const Type2& t2_null,
43 const Element& p,
double scale,
double tolerance,
bool verbose)
54 std::cerr <<
"\n*************** Testing operator =" << std::endl;
57 std::cerr <<
"Type1 = Type1" << std::endl;
60 if (verbose) std::cerr <<
"Type2 = Type1" << std::endl;
63 if (verbose) std::cerr <<
"Type2 = Type2" << std::endl;
66 if (verbose) std::cerr <<
"Type1 = Type2" << std::endl;
69 if (verbose) std::cerr <<
"Type1 == Type1" << std::endl;
71 throw std::string (
"test_matrix "
72 "Error casting from Type1 to Type2");
74 if (verbose) std::cerr <<
"Type1 == Type2" << std::endl;
76 throw std::string (
"test_matrix "
77 "Error casting from Type1 to Type2");
83 std::cerr <<
"\n*************** Testing operator + and -" << std::endl;
87 if (verbose) std::cerr <<
"Type1 + Type2" << std::endl;
92 if (verbose) std::cerr <<
"Type2 - Type1" << std::endl;
95 if (verbose) std::cerr <<
"Type1 == Type2" << std::endl;
97 if (norm(t1_1 - t2_1)/norm(t2_1) > tolerance)
99 std::cerr <<
"t1_1 = " << t1_1 <<
" != "
100 <<
"t2_1 = " << t2_1 << std::endl;
102 throw std::string (
"test_matrix "
103 "Error adding and subtracting Type1 and Type2");
111 std::cerr <<
"\n*************** Testing operator * and / Element"
115 random_value (dfactor, scale);
119 if (verbose) std::cerr <<
"Element * Type2" << std::endl;
120 t2_2 = dfactor * t2_1;
122 if (verbose) std::cerr <<
"Type2 / Element" << std::endl;
123 t2_1 = t2_2 / dfactor;
125 if (verbose) std::cerr <<
"Type1 == Type2" << std::endl;
126 if (norm(t2_1 - t1_1)/norm(t2_1) > tolerance)
128 std::cerr <<
"Error Type2=" << t2_1
129 <<
" * / Element=" << dfactor
130 <<
" != Type1=" << t1_1 << std::endl;
131 throw std::string (
"test_matrix Error in Type2 * / Element");
137 if (verbose) std::cerr <<
"\n*************** Testing operator * Type1" << std::endl;
139 if (verbose) std::cerr <<
"Type1::identity=" << Type1::identity() << std::endl;
141 if (verbose) std::cerr <<
"Type1 * Type1::identity" << std::endl;
142 t2_1 = t1_1 * Type1::identity();
144 if (verbose) std::cerr <<
"Type1 == Type2" << std::endl;
146 throw std::string (
"test_matrix Error Type1 * Type1::identity");
152 if (verbose) std::cerr <<
"\n*************** Testing conjugate" << std::endl;
154 if (verbose) std::cerr <<
"conj (t1_1 * t1_2)" << std::endl;
155 t2_1 = conj (t1_1 * t1_2);
157 if (verbose) std::cerr <<
"conj (t1_1) * conj (t1_2)" << std::endl;
158 t2_2 = conj (t1_1) * conj (t1_2);
160 if (verbose) std::cerr <<
"Type2 == Type2" << std::endl;
161 if (norm(t2_1 - t2_2)/norm(t2_1) > tolerance)
163 std::cerr <<
"1=" << t2_1 <<
"\n2=" << t2_2 << std::endl;
164 throw std::string (
"test_matrix Error Conjugate");
170 if (verbose) std::cerr <<
"\n*************** Testing Hermitian" << std::endl;
175 if (verbose) std::cerr <<
"herm (t2_1 * t2_2)" << std::endl;
176 temp1 = herm (t2_1 * t2_2);
178 if (verbose) std::cerr <<
"herm (t2_2) * herm (t2_1)" << std::endl;
179 temp2 = herm (t2_2) * herm (t2_1);
181 if (verbose) std::cerr <<
"Type2 == Type2" << std::endl;
183 if ( norm(temp2 - temp1)/norm(temp2) > tolerance) {
184 std::cerr <<
"Error Hermitian"
187 "\n herm(M1*M2)=" << temp1 <<
188 "\n herm(M2)*herm(M1)=" << temp2 << std::endl;
190 throw std::string (
"test_matrix Error Hermitian");
196 if (verbose) std::cerr <<
"\n*************** Testing determinant" << std::endl;
200 if (verbose) std::cerr <<
"det(Type2)" << std::endl;
201 Element det1 (det(t2_1));
203 if (verbose) std::cerr <<
"Type2 /= sqrt(det)" << std::endl;
206 if (verbose) std::cerr <<
"det(Type2)" << std::endl;
207 Element det2 (det(t2_1));
209 if (norm(det2 - one) > tolerance)
210 throw std::string (
"test_matrix "
211 "Error normalizing by square root of determinant");
218 std::cerr <<
"\n*************** Testing norm and trace" << std::endl;
222 if (verbose) std::cerr <<
"norm (Type2)" << std::endl;
223 double variance1 = norm(t2_2);
225 if (verbose) std::cerr <<
"herm (Type2)" << std::endl;
226 t2_1 = t2_2*herm(t2_2);
228 if (verbose) std::cerr <<
"trace (Type2)" << std::endl;
229 Element variance2 (trace (t2_1));
231 if ( norm(variance1 - variance2) > tolerance )
233 std::cerr <<
"Q=" << t2_2 << std::endl;
234 std::cerr <<
"herm(Q)=" << herm(t2_2) << std::endl;
235 std::cerr <<
"Q*herm(Q)=" << t2_1 << std::endl;
236 std::cerr <<
"norm(Q) = " << variance1 << std::endl;
237 std::cerr <<
"trace (Q * herm(Q)) = " << variance2 << std::endl;
239 throw std::string (
"test_matrix "
240 "Error norm(Q) != trace (Q * herm(Q))");
246 if (verbose) std::cerr <<
"\n*************** Testing inverse" << std::endl;
248 if (verbose) std::cerr <<
"Type1::inv" << std::endl;
251 if (verbose) std::cerr <<
"Type2 * Type2" << std::endl;
252 t2_1 = Type2(t1_1) * t2_2;
254 double threshold = tolerance * max (norm(t1_1), norm(t2_2));
256 if (verbose) std::cerr <<
"norm (Type2)" << std::endl;
257 variance1 = norm (Type2::identity() - t2_1);
259 if ( variance1 > threshold ) {
260 std::cerr <<
"Error multipying Type1 by its inverse"
262 "\n inv(Q)=" << t2_2 <<
263 "\n Q*inv(Q)=" << t2_1 << std::endl;
265 throw std::string (
"test_matrix "
266 "Error multipying Type1 by its inverse");
270template <
class Type1,
class Type2,
class Element>
271void MatrixTest<Type1, Type2, Element>::runtest (
unsigned nloops)
277 std::cerr <<
"\n*************** Testing constructors" << std::endl;
280 std::cerr <<
"Type1 null construct" << std::endl;
284 std::cerr <<
"Element array (static)" << std::endl;
286 Element random_elements[4];
287 for (
int i=0; i<4; i++)
288 random_value (random_elements[i], scale);
291 std::cerr <<
"Type1 construct from 4 Elements" << std::endl;
292 Type1 t1_1 (random_elements[0], random_elements[1],
293 random_elements[2], random_elements[3]);
296 std::cerr <<
"Type1 construct from Type1" << std::endl;
300 std::cerr <<
"TEST: Type1 == Type1" << std::endl;
302 throw std::string (
"MatrixTest::runtest "
303 "Error in constructing Type1 from Type1");
306 std::cerr <<
"Type1 = Type1" << std::endl;
310 std::cerr <<
"TEST: Type1 == Type1" << std::endl;
312 throw std::string (
"MatrixTest::runtest "
313 "Error setting Type1 equal to Type1");
315 for (
unsigned iloop=0; iloop<nloops; iloop++) {
319 random_vector (t1_1, scale);
320 random_vector (t1_2, scale);
326 test_matrix (t1_1, t1_2, t2_null, null, scale, tolerance, verbose);
328 catch (std::string& error) {
329 std::cerr <<
"MatrixTest::runtest error on loop "<< iloop <<
"/"<< nloops