-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmutator.hpp
119 lines (99 loc) · 2.92 KB
/
mutator.hpp
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
#pragma once
#include <cmath>
#include <tr1/random>
#include "misc.hpp"
using namespace std;
using namespace tr1;
struct U1Mutator {
U1Mutator( double e ): _eps( e ) {}
template<class RandGen>
complex<double> operator()( complex<double> const& u, RandGen& rng ) {
double im = uniform_real_ex<double>( -_eps, +_eps )( rng );
return complex<double>( cos( im ), sin( im ) ) * u;
}
private:
double const _eps;
};
template<class RandGen>
inline MatrixSU2<double> randSU2( double eps, RandGen& rng ) {
double x, y, z, r2;
do {
x = uniform_real_ex<double>( -eps, +eps )( rng );
y = uniform_real_ex<double>( -eps, +eps )( rng );
z = uniform_real_ex<double>( -eps, +eps )( rng );
r2 = x * x + y * y + z * z;
} while( r2 > eps * eps );
return MatrixSU2<double>( sqrt( 1.0 - r2 ), x, y, z );
}
struct SU2Mutator {
SU2Mutator( double e ): _eps( e ) {}
template<class RandGen>
MatrixSU2<double> operator()( MatrixSU2<double> const& u, RandGen& rng ) {
return randSU2( _eps, rng ) * u;
}
private:
double const _eps;
};
template<class Matrix, class RandGen>
inline Matrix randAntiHermite( double eps, RandGen& rng ) {
Matrix m;
double tr = 0.0;
for( int i = 0; i < m.rows(); ++i ) {
for( int j = 0; j < i; ++j ) {
double re = normal_distribution_ex<double>( 0.0, eps )( rng );
double im = normal_distribution_ex<double>( 0.0, eps )( rng );
m( i, j ) = complex<double>( +re, im );
m( j, i ) = complex<double>( -re, im );
}
double im = normal_distribution_ex<double>( 0.0, eps )( rng );
m( i, i ) = complex<double>( 0.0, im );
tr += im;
}
for( int i = 0; i < m.rows(); ++i ) {
m( i, i ).imag() -= tr / m.rows();
}
return m;
}
template<class Matrix, class RandGen>
inline Matrix randSUn( double eps, RandGen& rng ) {
Matrix m = Matrix::Identity();
assert( m.rows() == m.cols() );
int i, j;
do {
i = uniform_int<int>( 0, m.rows() - 1 )( rng );
j = uniform_int<int>( 0, m.cols() - 1 )( rng );
} while( i == j );
MatrixSU2<double> su2 = randSU2( eps, rng );
m( i, i ) = complex<double>( +su2.a0, +su2.a3 );
m( i, j ) = complex<double>( -su2.a2, +su2.a1 );
m( j, i ) = complex<double>( +su2.a2, +su2.a1 );
m( j, j ) = complex<double>( +su2.a0, -su2.a3 );
return m;
}
struct SUnMutator {
SUnMutator( double e ): _eps( e ) {}
template<class Derived, class RandGen>
typename Derived::PlainObject operator()( MatrixBase<Derived> const& u, RandGen& rng ) {
typedef typename Derived::PlainObject Matrix;
/*
Matrix m = orthonormalize_ex(
Derived::Identity() + randAntiHermite<Matrix>( _eps, rng )
);
return m * u;
*/
/*
Matrix a = randAntiHermite<Matrix>( _eps, rng );
Matrix m = a * (
(1.0 / 2.0) * a * (
(1.0 / 3.0) * a * (
(1.0 / 4.0) * a + Derived::Identity()
).eval() + Derived::Identity()
).eval() + Derived::Identity()
).eval() + Derived::Identity();
return orthonormalize_ex( m ) * u;
*/
return randSUn<Matrix>( _eps, rng ) * u;
}
private:
double const _eps;
};