MyraMath
swaps


Source: tests/dense/swaps.cpp

1 // ========================================================================= //
2 // This file is part of MyraMath, copyright (c) 2014-2019 by Ryan A Chilton //
3 // and distributed by MyraCore, LLC. See LICENSE.txt for license terms. //
4 // ========================================================================= //
5 
11 // Containers.
12 #include <myramath/dense/Matrix.h>
13 
14 // Algorithms.
16 #include <myramath/dense/gemm.h>
17 #include <myramath/dense/swaps.h>
20 
21 // Reporting.
22 #include <tests/myratest.h>
23 
24 #include <algorithm>
25 
26 using namespace myra;
27 
28 namespace {
29 
30 // Tests various operations w/ swap sequences.
31 void test_swaps(int I)
32  {
33  // Define a random permutation perm[] ..
34  std::vector<int> perm = ilinspace(I);
35  std::random_shuffle(perm.begin(),perm.end());
36  // .. transform it into a swap sequence ..
37  std::vector<int> swaps = perm2swaps(perm);
38  // .. and also build it into a Matrix.
39  Matrix<double> P = swaps2Matrix<double>(swaps);
40 
41  // Define random matrix X.
42  auto X = Matrix<double>::random(I,I);
43 
44  // Check P*X = swap_rows(X)
45  {
46  Matrix<double> PX = gemm(P,X);
47  Matrix<double> X_copy = X;
48  swap_rows(swaps,X_copy);
49  double error = frobenius(PX-X_copy);
50  myra::out() << " |P*X-swap_rows(X)| = " << error << std::endl;
51  REQUIRE(error < 1.0e-9);
52  }
53 
54  // Check P'*X = iswap_rows(X)
55  {
56  Matrix<double> PtX = gemm(P,'T',X);
57  Matrix<double> X_copy = X;
58  iswap_rows(swaps,X_copy);
59  double error = frobenius(PtX-X_copy);
60  myra::out() << " |P'*X-iswap_rows(X)| = " << error << std::endl;
61  REQUIRE(error < 1.0e-9);
62  }
63 
64  // Check that swap_rows() and iswap_rows() are reverse operations.
65  {
66  Matrix<double> X_copy = X;
67  swap_rows(swaps,X_copy);
68  iswap_rows(swaps,X_copy);
69  double error = frobenius(X_copy-X);
70  myra::out() << " |iswap_rows(swap_rows(X))-X| = " << error << std::endl;
71  REQUIRE(error < 1.0e-9);
72  }
73 
74  // Check that X*P = swap_columns(X)
75  {
76  Matrix<double> XP = gemm(X,P);
77  Matrix<double> X_copy = X;
78  swap_columns(swaps,X_copy);
79  double error = frobenius(XP-X_copy);
80  myra::out() << " |X*P-swap_columns(X)| = " << error << std::endl;
81  REQUIRE(error < 1.0e-9);
82  }
83 
84  // Check X*P' = iswap_columns(X)
85  {
86  Matrix<double> XPt = gemm(X,P,'T');
87  Matrix<double> X_copy = X;
88  iswap_columns(swaps,X_copy);
89  double error = frobenius(XPt-X_copy);
90  myra::out() << " |X*P'-iswap_columns(X)| = " << error << std::endl;
91  REQUIRE(error < 1.0e-9);
92  }
93 
94  // Check that swap_columns() and iswap_columns() are reverse operations.
95  {
96  Matrix<double> X_copy = X;
97  swap_columns(swaps,X_copy);
98  iswap_columns(swaps,X_copy);
99  double error = frobenius(X_copy-X);
100  myra::out() << " |iswap_rows(swap_rows(X))-X| = " << error << std::endl;
101  REQUIRE(error < 1.0e-9);
102  }
103 
104  // Check that a perm and it's inverse_perm() lead to inverse matrices.
105  {
106  std::vector<int> iperm = inverse_perm(perm);
107  std::vector<int> iswaps = perm2swaps(iperm);
108  Matrix<double> iP = swaps2Matrix<double>(iswaps);
109  double error = frobenius(gemm(P,iP)-Matrix<double>::identity(I));
110  myra::out() << " |I - P'inverse(P))| = " << error << std::endl;
111  REQUIRE(error < 1.0e-9);
112  }
113 
114  }
115 
116 } // namespace
117 
118 ADD_TEST("swaps","[dense]")
119  {
120  myra::out() << "Testing swaps.." << std::endl;
121  test_swaps(20);
122  myra::out() << std::endl;
123  }
Tabulates an IxJ matrix. Allows random access, has column major layout to be compatible with BLAS/LAP...
Definition: bdsqr.h:20
Routines for computing Frobenius norms of various algebraic containers.
static Matrix< Number > random(int I, int J)
Generates a random Matrix of specified size.
Definition: Matrix.cpp:353
Definition: syntax.dox:1
Routines related to swap sequences, often used during pivoting.
Returns a vector of int&#39;s, over [min,max)
General purpose dense matrix container, O(i*j) storage.
Variety of routines all for dense Matrix*Matrix multiplies. Delegates to the BLAS.
Interface class for representing subranges of contiguous int&#39;s.


Results: [PASS]

Testing swaps..
|P*X-swap_rows(X)| = 0
|P'*X-iswap_rows(X)| = 0
|iswap_rows(swap_rows(X))-X| = 0
|X*P-swap_columns(X)| = 0
|X*P'-iswap_columns(X)| = 0
|iswap_rows(swap_rows(X))-X| = 0
|I - P'inverse(P))| = 0


Go back to Summary of /test programs.