14411cf47Sjeremylt /// @file
252bfb9bbSJeremy L Thompson /// Test Symmetric Schur Decomposition
352bfb9bbSJeremy L Thompson /// \test Test Symmetric Schur Decomposition
4*f85e4a7bSJeremy L Thompson
5*f85e4a7bSJeremy L Thompson //TESTARGS(only="cpu") {ceed_resource}
657c64913Sjeremylt #include <ceed.h>
7673160d7Sjeremylt #include <ceed/backend.h>
8673160d7Sjeremylt #include <math.h>
949aac155SJeremy L Thompson #include <stdio.h>
1057c64913Sjeremylt
main(int argc,char ** argv)1157c64913Sjeremylt int main(int argc, char **argv) {
1257c64913Sjeremylt Ceed ceed;
134fee36f0SJeremy L Thompson CeedInt p = 4;
14673160d7Sjeremylt CeedScalar M[16], Q[16], lambda[4], Q_lambda_Qt[16];
15673160d7Sjeremylt CeedBasis basis;
164fee36f0SJeremy L Thompson const CeedScalar *interpolation, *quadrature_weights;
1757c64913Sjeremylt
1857c64913Sjeremylt CeedInit(argv[1], &ceed);
19288c0443SJeremy L Thompson
20673160d7Sjeremylt // Create mass matrix
214fee36f0SJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, p, p, CEED_GAUSS, &basis);
224fee36f0SJeremy L Thompson CeedBasisGetInterp(basis, &interpolation);
234fee36f0SJeremy L Thompson CeedBasisGetQWeights(basis, &quadrature_weights);
244fee36f0SJeremy L Thompson for (int i = 0; i < p; i++) {
254fee36f0SJeremy L Thompson for (int j = 0; j < p; j++) {
26673160d7Sjeremylt CeedScalar sum = 0;
274fee36f0SJeremy L Thompson for (int k = 0; k < p; k++) sum += interpolation[p * k + i] * quadrature_weights[k] * interpolation[p * k + j];
284fee36f0SJeremy L Thompson M[p * i + j] = sum;
294fee36f0SJeremy L Thompson Q[p * i + j] = sum;
3057c64913Sjeremylt }
312b730f8bSJeremy L Thompson }
32673160d7Sjeremylt
334fee36f0SJeremy L Thompson CeedSymmetricSchurDecomposition(ceed, Q, lambda, p);
34673160d7Sjeremylt
35673160d7Sjeremylt // Check diagonalization of M
364fee36f0SJeremy L Thompson for (int i = 0; i < p; i++) {
374fee36f0SJeremy L Thompson for (int j = 0; j < p; j++) {
38673160d7Sjeremylt CeedScalar sum = 0;
394fee36f0SJeremy L Thompson for (int k = 0; k < p; k++) sum += Q[p * i + k] * lambda[k] * Q[p * j + k];
404fee36f0SJeremy L Thompson Q_lambda_Qt[p * i + j] = sum;
4152bfb9bbSJeremy L Thompson }
422b730f8bSJeremy L Thompson }
434fee36f0SJeremy L Thompson for (int i = 0; i < p; i++) {
444fee36f0SJeremy L Thompson for (int j = 0; j < p; j++) {
454fee36f0SJeremy L Thompson if (fabs(M[p * i + j] - Q_lambda_Qt[p * i + j]) > 100. * CEED_EPSILON) {
46673160d7Sjeremylt // LCOV_EXCL_START
474fee36f0SJeremy L Thompson printf("Error in diagonalization [%" CeedInt_FMT ", %" CeedInt_FMT "]: %f != %f\n", i, j, M[p * i + j], Q_lambda_Qt[p * i + j]);
48673160d7Sjeremylt // LCOV_EXCL_STOP
492b730f8bSJeremy L Thompson }
502b730f8bSJeremy L Thompson }
512b730f8bSJeremy L Thompson }
52673160d7Sjeremylt
53673160d7Sjeremylt CeedBasisDestroy(&basis);
5457c64913Sjeremylt CeedDestroy(&ceed);
5557c64913Sjeremylt return 0;
5657c64913Sjeremylt }
57