decomp_eig_sym.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au)
  2. // Copyright 2015 National ICT Australia (NICTA)
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // ------------------------------------------------------------------------
  15. #include <armadillo>
  16. #include "catch.hpp"
  17. using namespace arma;
  18. TEST_CASE("decomp_eig_sym_1")
  19. {
  20. mat A =
  21. "\
  22. 0.061198 0.201990 0.019678 -0.493936 -0.126745;\
  23. 0.437242 0.058956 -0.149362 -0.045465 0.296153;\
  24. -0.492474 -0.031309 0.314156 0.419733 0.068317;\
  25. 0.336352 0.411541 0.458476 -0.393139 -0.135040;\
  26. 0.239585 -0.428913 -0.406953 -0.291020 -0.353768;\
  27. ";
  28. A = A*A.t();
  29. vec eigvals1 =
  30. {
  31. 0.0044188,
  32. 0.0697266,
  33. 0.3364172,
  34. 0.8192910,
  35. 1.1872184
  36. };
  37. vec eigvals2 = eig_sym(A);
  38. vec eigvals3;
  39. bool status = eig_sym(eigvals3, A);
  40. vec eigvals4;
  41. mat eigvecs4;
  42. eig_sym(eigvals4, eigvecs4, A);
  43. mat B = eigvecs4 * diagmat(eigvals4) * eigvecs4.t();
  44. REQUIRE( status == true );
  45. REQUIRE( accu(abs(eigvals2 - eigvals1)) == Approx(0.0) );
  46. REQUIRE( accu(abs(eigvals3 - eigvals1)) == Approx(0.0) );
  47. REQUIRE( accu(abs(eigvals4 - eigvals1)) == Approx(0.0) );
  48. REQUIRE( accu(abs(A - B )) == Approx(0.0) );
  49. }
  50. TEST_CASE("eig_sym_2")
  51. {
  52. cx_mat A =
  53. {
  54. { cx_double( 0.111205, +0.074101), cx_double(-0.225872, -0.068474), cx_double(-0.192660, +0.236887), cx_double( 0.355204, -0.355735) },
  55. { cx_double( 0.119869, +0.217667), cx_double(-0.412722, +0.366157), cx_double( 0.069916, -0.222238), cx_double( 0.234987, -0.072355) },
  56. { cx_double( 0.003791, +0.183253), cx_double(-0.212887, -0.172758), cx_double( 0.168689, -0.393418), cx_double( 0.008795, -0.289654) },
  57. { cx_double(-0.331639, -0.166660), cx_double( 0.436969, -0.313498), cx_double(-0.431574, +0.017421), cx_double(-0.104165, +0.145246) }
  58. };
  59. A = A*A.t();
  60. vec eigvals1 =
  61. {
  62. 0.030904,
  63. 0.253778,
  64. 0.432459,
  65. 1.204726
  66. };
  67. vec eigvals2 = eig_sym(A);
  68. vec eigvals3;
  69. bool status = eig_sym(eigvals3, A);
  70. vec eigvals4;
  71. cx_mat eigvecs4;
  72. eig_sym(eigvals4, eigvecs4, A);
  73. cx_mat B = eigvecs4 * diagmat(eigvals4) * eigvecs4.t();
  74. REQUIRE( status == true );
  75. REQUIRE( accu(abs(eigvals2 - eigvals1)) == Approx(0.0) );
  76. REQUIRE( accu(abs(eigvals3 - eigvals1)) == Approx(0.0) );
  77. REQUIRE( accu(abs(eigvals4 - eigvals1)) == Approx(0.0) );
  78. REQUIRE( accu(abs(A - B )) == Approx(0.0) );
  79. }
  80. TEST_CASE("eig_sym_3")
  81. {
  82. mat A(5,6,fill::randu);
  83. vec eigvals;
  84. mat eigvecs;
  85. REQUIRE_THROWS( eig_sym(eigvals, eigvecs, A) );
  86. }