aboutsummaryrefslogtreecommitdiffhomepage
path: root/tvmet-1.7.1/tests/swap.cc
blob: 8d4d01d3d198b980138d79407c6c8e483f6f42f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
 * Test file for checking meta swap feature.
 *
 * Swapping using std::swap is faster than meta template implementation.
 */

#include <iostream>
#include <algorithm>				// min, max

#include <tvmet/Matrix.h>
#include <tvmet/Vector.h>


using namespace tvmet;
using namespace std;

NS_TVMET_BEGIN

template<size_t Sz, size_t Idx=0>
class MetaSwap // later, should be MetaVector
{
private:
  enum {
    doIt = (Idx < (Sz-1)) ? 1 : 0		/**< recursive counter */
  };

public:
  template<class E1, class E2>
  static inline
  void
  swap(E1& e1, E2& e2) {
    // XXX BUG: const problem?, we have to use the operator() for Vectors
    fcnl_Swap<typename E1::value_type, typename E2::value_type>::applyOn(e1(Idx), e2(Idx));
    MetaSwap<Sz * doIt, (Idx+1) * doIt>::swap(e1, e2);
  }
};

template<>
class MetaSwap<0, 0>
{
public:
  template<class E1, class E2> static inline void swap(E1&, E2&) { }
};


/**
 * \fun swap
 * \brief swaps to vector expressions XprVector<E, Sz>
 */
template<class E1, class E2, size_t Sz>
inline
void swap(XprVector<E1, Sz> e1, XprVector<E2, Sz> e2) {
  MetaSwap<Sz>::swap(e1, e2);
}

/**
 * \fun swap
 * \brief swaps to vector
 */
template<class T1, class T2, size_t Sz>
inline
void swap(Vector<T1, Sz>& lhs, Vector<T2, Sz>& rhs) {
  swap(lhs.asXpr(), rhs.asXpr());
}


/**
 * \fun swap2
 * \brief swaps to vector expressions XprVector<E, Sz>
 */
template<class E1, class E2, size_t Sz>
inline
void swap2(XprVector<E1, Sz> e1, XprVector<E2, Sz> e2) {
  // loops are faster than meta templates
  for(size_t i = 0; i < Sz; ++i)
    std::swap(e1[i], e2[i]);
}

/**
 * \fun swap2
 * \brief swaps to vector
 */
template<class T1, class T2, size_t Sz>
inline
void swap2(Vector<T1, Sz>& lhs, Vector<T2, Sz>& rhs) {
  // loops are faster than meta templates
  for(size_t i = 0; i < Sz; ++i)
    std::swap(lhs[i], rhs[i]);
}


NS_TVMET_END




template<class V1, class V2>
void test_meta_swap(V1& v1, V2& v2) {
  tvmet::swap(v1, v2);
}

template<class V1, class V2>
void test_loop_swap(V1& v1, V2& v2) {
  tvmet::swap2(v1, v2);
}



template<class M1, class M2>
void test_meta_mswap(M1& m1, M2& m2) {
  tvmet::swap2(row(m1, 0), row(m2, 0));
  tvmet::swap2(col(m1, 0), col(m2, 0));
}


#define LOOPS	1000000

int main() {
  typedef Matrix<double, 4, 4>				matrix_type;
  typedef Vector<double, 4>				vector_type;

  //----------------------------------------------------------------
  vector_type v1(1);
  vector_type v2(4);

  cout << "\nSwap Vectors\n\n";
  cout << v1 << endl;
  cout << v2 << endl;
  for(size_t i = 0; i < LOOPS; ++i)
    test_meta_swap(v1, v2);
  cout << v1 << endl;
  cout << v2 << endl;
  for(size_t i = 0; i < LOOPS; ++i)
    test_loop_swap(v1, v2);
  cout << v1 << endl;
  cout << v2 << endl;

  //----------------------------------------------------------------
  matrix_type m1, m2;
  vector_type rv;

  m1 = 1,2,3,4,
       5,6,7,8,
       9,10,11,12,
       13,14,15,16;
  m2 = transpose(m1);

  cout << "\nSwap Matrix\n\n";
  cout << m1 << endl;
  cout << m2 << endl;
  test_meta_mswap(m1, m2);
  cout << m1 << endl;
  cout << m2 << endl;
}