Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
test/DenseMatrix/cxx_main_sym.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
14 #include "Teuchos_Version.hpp"
15 
16 #define OTYPE int
17 #define STYPE std::complex<double>
18 
19 template<typename TYPE>
20 int PrintTestResults(std::string, TYPE, TYPE, bool);
21 
22 int ReturnCodeCheck(std::string, int, int, bool);
23 
27 
28 int main(int argc, char* argv[])
29 {
30 
31  int i;
32  bool verbose = 0;
33  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;
34 
35  if (verbose)
36  std::cout << Teuchos::Teuchos_Version() << std::endl << std::endl;
37 
38  int numberFailedTests = 0;
39  int returnCode = 0;
40  std::string testName = "";
41 
42  if (verbose) std::cout<<std::endl<<"********** CHECKING TEUCHOS SERIAL SYMMETRIC DENSE MATRIX **********"<<std::endl<<std::endl;
43 
44  // default constructor test
45  SDMatrix DefConTest;
46  if (verbose) std::cout <<"default constructor -- construct empty matrix ";
47  if ( DefConTest.values()!=NULL || DefConTest.numCols()!=0 || DefConTest.numRows()!=0 ||DefConTest.stride()!=0 ||DefConTest.empty()!=true ) {
48  if (verbose) std::cout << "unsuccessful."<<std::endl;
49  numberFailedTests++;
50  } else {
51  if (verbose) std::cout << "successful."<<std::endl;
52  }
53 
54  // constructor 1 (matrix w/ dimension but empty)
55 
56  SDMatrix Con1Test( 4 );
57  if (verbose) std::cout <<"constructor 1 -- empty matrix with given dimensions ";
58  if ( Con1Test.numRows()!=4 || Con1Test.numCols()!=4 || Con1Test( 1, 2 )!=0.0 ) {
59  if (verbose) std::cout << "unsuccessful."<<std::endl;
60  numberFailedTests++;
61  } else {
62  if (verbose) std::cout << "successful."<<std::endl;
63  }
64 
65  // constructor 2 (from array) tests
66 
67  STYPE a[9];
68  for(i = 0; i < 9; i++)
69  {
70  a[i] = i;
71  }
72  SDMatrix Con2Test1ExpRes;
73  Con2Test1ExpRes.shape(3);
74  Con2Test1ExpRes(0, 0) = 0;
75  Con2Test1ExpRes(1, 0) = 1; Con2Test1ExpRes(1, 1) = 4;
76  Con2Test1ExpRes(2, 0) = 2; Con2Test1ExpRes(2, 1) = 5; Con2Test1ExpRes(2, 2) = 8;
77 
78  // Create another lower triangular matrix with a view of 'a'.
79  SDMatrix Con2Test1(Teuchos::View, false, a, 3, 3);
80  numberFailedTests += PrintTestResults("constructor 2 -- construct matrix from array subrange", Con2Test1, Con2Test1ExpRes, verbose);
81 
82 
83  // constructor 3 (copy constructor)
84 
85  SDMatrix Con3TestCopy( Con2Test1ExpRes );
86  if(verbose) std::cout <<"constructor 3 -- copy constructor ";
87  if ( Con3TestCopy != Con2Test1ExpRes ) {
88  if (verbose) std::cout << "unsuccessful."<<std::endl;
89  numberFailedTests++;
90  } else {
91  if (verbose) std::cout << "successful."<<std::endl;
92  }
93 
94  SDMatrix Con3TestCopyTrans( Con2Test1ExpRes );
95  Con3TestCopyTrans.setUpper();
96  if(verbose) std::cout <<"constructor 3 -- copy constructor (upper active storage) ";
97  if ( Con3TestCopyTrans(2, 0) != Con2Test1ExpRes(2, 0) ) {
98  if (verbose) std::cout << "unsuccessful."<<std::endl;
99  numberFailedTests++;
100  } else {
101  if (verbose) std::cout << "successful."<<std::endl;
102  }
103 
104  // constructor 4 (submatrix)
105 
106  SDMatrix Con4TestOrig(Teuchos::Copy, false, a, 3, 3);
107  SDMatrix Con4TestSubmatrix;
108  Con4TestSubmatrix.shape( 2 );
109  Con4TestSubmatrix(0, 0) = 4;
110  Con4TestSubmatrix(1, 0) = 5; Con4TestSubmatrix(1, 1) = 8;
111  SDMatrix Con4TestCopy1(Teuchos::Copy, Con4TestOrig, 2, 1);
112  numberFailedTests += PrintTestResults("constructor 4 -- submatrix copy", Con4TestCopy1, Con4TestSubmatrix, verbose);
113  SDMatrix Con4TestCopy2(Teuchos::Copy, Con4TestOrig, 3, 0);
114  numberFailedTests += PrintTestResults("constructor 4 -- full matrix copy", Con4TestCopy2, Con4TestOrig, verbose);
115  SDMatrix Con4TestView1(Teuchos::View, Con4TestOrig, 2, 1);
116  numberFailedTests += PrintTestResults("constructor 4 -- full matrix view", Con4TestView1, Con4TestSubmatrix, verbose);
117  SDMatrix Con4TestView2(Teuchos::View, Con4TestOrig, 3, 0);
118  numberFailedTests += PrintTestResults("constructor 4 -- submatrix view", Con4TestView2, Con4TestOrig, verbose);
119 
120  // Norm Tests
121 
122  SDMatrix AAA;
123  AAA.shape( 3 );
124  AAA(0, 0) = 8;
125  AAA(1, 0) = 1; AAA(1, 1) = 8;
126  AAA(2, 0) = 2; AAA(2, 1) = 3; AAA(2, 2) = 8;
127  SDMatrix BBB;
128  numberFailedTests += PrintTestResults("normOne of a 3x3", AAA.normOne(), 13.0, verbose);
129  numberFailedTests += PrintTestResults("normInf of a 3x3", AAA.normInf(), 13.0, verbose);
131  numberFailedTests += PrintTestResults("normFrobenius of a 3x3", AAA.normFrobenius(), 3.0, verbose);
132  numberFailedTests += PrintTestResults("normOne of a 0x0", BBB.normOne(), 0.0, verbose);
133  numberFailedTests += PrintTestResults("normInf of a 0x0", BBB.normInf(), 0.0, verbose);
134  numberFailedTests += PrintTestResults("normFrobenius of a 0x0", BBB.normFrobenius(), 0.0, verbose);
135 
136  // Multiplication Tests
137 
138  // Reset values of AAA.
139  AAA(0, 0) = 8;
140  AAA(1, 0) = 1; AAA(1, 1) = 8;
141  AAA(2, 0) = 2; AAA(2, 1) = 3; AAA(2, 2) = 8;
142 
143  DMatrix My_Prod( 4, 3 ), My_GenMatrix( 4, 3 );
144  My_GenMatrix = Teuchos::ScalarTraits<STYPE>::one();
145 
146  // Matrix multiplication ( My_Prod = 1.0*My_GenMatrix*My_Matrix )
147  My_Prod.multiply( Teuchos::RIGHT_SIDE, 1.0, AAA, My_GenMatrix, 0.0 );
148  numberFailedTests += PrintTestResults("multiply() -- general times symmetric matrix (storage = lower tri)", My_Prod.normOne(), 52.0, verbose);
149  AAA.setUpper();
150  AAA(2, 1) = 1.0;
151  My_Prod.multiply( Teuchos::RIGHT_SIDE, 1.0, AAA, My_GenMatrix, 0.0 );
152  numberFailedTests += PrintTestResults("multiply() -- general times symmetric matrix (storage = upper tri)", My_Prod.normOne(), 44.0, verbose);
153 
154  // Set Method Tests.
155 
156  SDMatrix CCC( 5 );
157  // Randomize the entries in CCC.
158  testName = "random() -- enter random entries into matrix";
159  returnCode = CCC.random();
160  numberFailedTests += ReturnCodeCheck(testName, returnCode, 0, verbose);
161  // Set the entries of CCC to 1.0.
162  testName = "putScalar() -- set every entry of this matrix to 1.0";
163  returnCode = CCC.putScalar(Teuchos::ScalarTraits<STYPE>::one());
164  numberFailedTests += ReturnCodeCheck(testName, returnCode, 0, verbose);
165  // Check assignment operator.
166  SDMatrix CCC2( 5 );
167  CCC2.assign( CCC );
168  if (verbose) std::cout << "assign() -- copy the values of an input matrix ";
169  if ( CCC( 3, 4 ) == Teuchos::ScalarTraits<STYPE>::one() ) {
170  if (verbose) std::cout<< "successful" <<std::endl;
171  } else {
172  if (verbose) std::cout<< "unsuccessful" <<std::endl;
173  numberFailedTests++;
174  }
175  // Create a swap testing matrix
176  SDMatrix CCC2swap( 3 );
177  CCC2swap.random();
178  SDMatrix copyCCC2(CCC2);
179  SDMatrix copyCCC2swap(CCC2swap);
180  if (verbose) std::cout << "swap() -- swap the values and attributes of two symmetric matrices -- ";
181  CCC2swap.swap(CCC2);
182  bool op_result = ( (CCC2swap == copyCCC2) && (CCC2 == copyCCC2swap) );
183  if (verbose)
184  std::cout << (op_result ? "successful" : "failed" )<<std::endl;
185  if( !op_result )
186  numberFailedTests++;
187  // Swap back using other matrix and allow downstream testing to proceed as if without swapping
188  CCC2.swap(CCC2swap);
189 
190  // Create a view into a submatrix of CCC
191  SDMatrix CCCview( Teuchos::View, CCC, 3 );
192  SDMatrix CCCtest1( 2 );
193  CCCtest1 = CCCview;
194  if (verbose) std::cout << "operator= -- small(empty) = large(view) ";
195  if (CCCtest1.numRows()==3 && CCCtest1.values()==CCC.values()) {
196  if (verbose) std::cout<< "successful" <<std::endl;
197  } else {
198  if (verbose) std::cout<< "unsuccessful" <<std::endl;
199  numberFailedTests++;
200  }
201  CCCtest1 = CCC;
202  if (verbose) std::cout << "operator= -- small(view) = large(copy) ";
203  if (CCCtest1.numRows()==5 && CCCtest1.values()!=CCC.values()) {
204  if (verbose) std::cout<< "successful"<<std::endl;
205  } else {
206  if (verbose) std::cout<< "unsuccessful"<<std::endl;
207  numberFailedTests++;
208  }
209  SDMatrix CCCtest2( 2 );
211  CCCtest1 = CCCtest2;
212  if (verbose) std::cout << "operator= -- large(copy) = small(copy) ";
213  if (CCCtest1.numRows()==2 ) {
214  if (verbose) std::cout<< "successful"<<std::endl;
215  } else {
216  if (verbose) std::cout<< "unsuccessful"<<std::endl;
217  numberFailedTests++;
218  }
219  CCCtest1 = CCCview;
220  if (verbose) std::cout << "operator= -- large(copy) = small(view) ";
221  if (CCCtest1.numRows()==3 && CCCtest1.stride()==5) {
222  if(verbose) std::cout<<"successful" <<std::endl;
223  } else {
224  if (verbose) std::cout<<"unsuccessful"<<std::endl;
225  numberFailedTests++;
226  }
227 
228  SDMatrix CCCtest3( CCCview );
229  CCCtest1 += CCCtest3;
230  if (verbose) std::cout << "operator+= -- add two matrices of the same size, but different leading dimension ";
231  if (CCCtest1(1,1)==2.0) {
232  if(verbose) std::cout<<"successful" <<std::endl;
233  } else {
234  if (verbose) std::cout<<"unsuccessful"<<std::endl;
235  numberFailedTests++;
236  }
237  if (verbose) std::cout << "operator+= -- add two matrices of different size (nothing should change) ";
238  CCCtest1 += CCC;
239  if (CCCtest1(1,1)==2.0) {
240  if(verbose) std::cout<<"successful" <<std::endl;
241  } else {
242  if (verbose) std::cout<<"unsuccessful"<<std::endl;
243  numberFailedTests++;
244  }
245 
246  // Scale Tests.
247 
248  SDMatrix ScalTest( 8 );
250  // Scale the entries by 8, it should be 8.
251  // The matrix is lower triangular, by default, so check a lower triangular entry.
252  if (verbose) std::cout << "operator*= -- scale matrix by some number ";
253  ScalTest *= 8.0;
254  if (ScalTest(7, 1) == 8.0) {
255  if (verbose) std::cout<< "successful." <<std::endl;
256  } else {
257  if (verbose) std::cout<< "unsuccessful." <<std::endl;
258  numberFailedTests++;
259  }
260 
261 
262  // Matrix Triple-Product Test
264  DMatrix W(3,2);
265  SDMatrix A1(2), A2(3);
266  A1(0,0) = 1.0, A1(1,1) = 2.0;
267  A2(0,0) = 1.0, A2(1,1) = 2.0, A2(2,2) = 3.00;
269 
270  SDMatrix C1upper(3), C1lower(3), C2upper(2), C2lower(2);
271  C1upper.setUpper(); C2upper.setUpper();
272  C1lower.setLower(); C2lower.setLower();
273 
274  // Test all combinations of triple products.
275 
276  // These should return a matrix with 1.5 in all entries
277  STYPE C1result = 1.5*Teuchos::ScalarTraits<STYPE>::one();
278  Teuchos::symMatTripleProduct<OTYPE,STYPE>( Teuchos::NO_TRANS, alpha, A1, W, C1upper );
279  Teuchos::symMatTripleProduct<OTYPE,STYPE>( Teuchos::NO_TRANS, alpha, A1, W, C1lower );
280 
281  // These should return a matrix with 3 in all entries
282  STYPE C2result = 3.0*Teuchos::ScalarTraits<STYPE>::one();
283  Teuchos::symMatTripleProduct<OTYPE,STYPE>( Teuchos::TRANS, alpha, A2, W, C2upper );
284  Teuchos::symMatTripleProduct<OTYPE,STYPE>( Teuchos::TRANS, alpha, A2, W, C2lower );
285 
286  if (verbose) std::cout << "triple product -- compute C = W'*A*W or C = W*A*W' ";
287  if (C1upper(2,1)==C1result && C1lower(1,2)==C1result && C2upper(1,0)==C2result && C2lower(0,1)==C2result) {
288  if (verbose) std::cout<< "successful." <<std::endl;
289  } else {
290  if (verbose) std::cout<< "unsuccessful." <<std::endl;
291  numberFailedTests++;
292  }
293 
294 
295 
296  //
297  // If a test failed output the number of failed tests.
298  //
299  if(numberFailedTests > 0)
300  {
301  if (verbose) {
302  std::cout << "Number of failed tests: " << numberFailedTests << std::endl;
303  std::cout << "End Result: TEST FAILED" << std::endl;
304  return -1;
305  }
306  }
307  if(numberFailedTests == 0)
308  std::cout << "End Result: TEST PASSED" << std::endl;
309 
310  return 0;
311 }
312 
313 template<typename TYPE>
314 int PrintTestResults(std::string testName, TYPE calculatedResult, TYPE expectedResult, bool verbose)
315 {
316  int result;
317  if(calculatedResult == expectedResult)
318  {
319  if(verbose) std::cout << testName << " successful." << std::endl;
320  result = 0;
321  }
322  else
323  {
324  if(verbose) std::cout << testName << " unsuccessful." << std::endl;
325  result = 1;
326  }
327  return result;
328 }
329 
330 int ReturnCodeCheck(std::string testName, int returnCode, int expectedResult, bool verbose)
331 {
332  int result;
333  if(expectedResult == 0)
334  {
335  if(returnCode == 0)
336  {
337  if(verbose) std::cout << testName << " test successful." << std::endl;
338  result = 0;
339  }
340  else
341  {
342  if(verbose) std::cout << testName << " test unsuccessful. Return code was " << returnCode << "." << std::endl;
343  result = 1;
344  }
345  }
346  else
347  {
348  if(returnCode != 0)
349  {
350  if(verbose) std::cout << testName << " test successful -- failed as expected." << std::endl;
351  result = 0;
352  }
353  else
354  {
355  if(verbose) std::cout << testName << " test unsuccessful -- did not fail as expected. Return code was " << returnCode << "." << std::endl;
356  result = 1;
357  }
358  }
359  return result;
360 }
SerialSymDenseMatrix< OTYPE, STYPE > SDMatrix
int PrintTestResults(std::string, TYPE, TYPE, bool)
Non-member helper functions on the templated serial, dense matrix/vector classes. ...
Templated serial dense matrix class.
Teuchos::SerialDenseVector< int, std::complex< Real > > DVector
ScalarType * values() const
Returns the pointer to the ScalarType data array contained in the object.
void swap(SerialSymDenseMatrix< OrdinalType, ScalarType > &B)
Swap values between this matrix and incoming matrix.
int shape(OrdinalType numRowsCols)
Set dimensions of a Teuchos::SerialSymDenseMatrix object; init values to zero.
This class creates and provides basic support for symmetric, positive-definite dense matrices of temp...
OrdinalType numRows() const
Returns the row dimension of this matrix.
ScalarTraits< ScalarType >::magnitudeType normInf() const
Returns the Infinity-norm of the matrix.
This class creates and provides basic support for dense vectors of templated type as a specialization...
This structure defines some basic traits for a scalar field type.
void setLower()
Specify that the lower triangle of the this matrix should be used.
void setUpper()
Specify that the upper triangle of the this matrix should be used.
ScalarTraits< ScalarType >::magnitudeType normOne() const
Returns the 1-norm of the matrix.
Teuchos::SerialDenseMatrix< int, std::complex< Real > > DMatrix
int random(const ScalarType bias=0.1 *Teuchos::ScalarTraits< ScalarType >::one())
Set all values in the active area (upper/lower triangle) of this matrix to be random numbers...
std::string Teuchos_Version()
int ReturnCodeCheck(std::string, int, int, bool)
Templated serial, dense, symmetric matrix class.
int main(int argc, char *argv[])
Templated serial dense vector class.
OrdinalType stride() const
Returns the stride between the columns of this matrix in memory.
OrdinalType numCols() const
Returns the column dimension of this matrix.
ScalarTraits< ScalarType >::magnitudeType normFrobenius() const
Returns the Frobenius-norm of the matrix.
SerialSymDenseMatrix< OrdinalType, ScalarType > & assign(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Source)
Copies values from one matrix to another.
static T one()
Returns representation of one for this scalar type.
bool empty() const
Returns whether this matrix is empty.
This class creates and provides basic support for dense rectangular matrix of templated type...