-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrandom_matrix.h
101 lines (76 loc) · 2.78 KB
/
random_matrix.h
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
# Copyright (c) 2016 The Caroline authors. All rights reserved.
# Use of this source file is governed by a MIT license that can be found in the
# LICENSE file.
# Author: Glazachev Vladimir <[email protected]>
#ifndef RANDOM_MATRIX_H
#define RANDOM_MATRIX_H
#include "matrix.h"
#include "interval.h"
#include "flint/arb_mat.h"
#include <string>
namespace interval {
// Generates random invertable matrix with small determenant.
// First generate random matrix A and then computes e^A.
// n - matrix dimension
// error_bound - number of digits in decimal part
// random - function for random number generation
// fname - output file name.
template<class Distribution>
Matrix<ArbInterval> random_matrix(size_t n, size_t error_bound,
Distribution random) {
const size_t prec = 1000;
arb_mat_t A;
arb_mat_t B;
arb_mat_init(A, n, n);
arb_mat_init(B, n, n);
for (size_t i = 0; i < n; ++i)
for (size_t j = 0; j < n; ++j)
arb_set_d(arb_mat_entry(A, i, j), random());
for (size_t i = 0; i < n; ++i)
arb_zero(arb_mat_entry(A, i, i));
arb_mat_exp(B, A, prec);
mag_t error;
mag_init(error);
mag_set_ui(error, 1);
mag_div_ui(error, error, 10);
mag_pow_ui(error, error, static_cast<slong>(error_bound));
for (size_t i = 0; i < n; ++i)
for (size_t j = 0; j < n; ++j)
mag_set(arb_radref(arb_mat_entry(B, i, j)), error);
Matrix<ArbInterval> result(n, n);
for (size_t i = 0; i < n; ++i)
for (size_t j = 0; j < n; ++j)
arb_set(result.at(i, j).data(), arb_mat_entry(B, i, j));
mag_clear(error);
arb_mat_clear(B);
arb_mat_clear(A);
return result;
}
// Generates random linear system using random_matrix().
// First generate random matrix A and then computes e^A.
// n - matrix dimension
// error_bound - number of digits in decimal part
// random - function for random number generation
// fname - output file name.
template<class Distribution>
Matrix<ArbInterval> random_linear_system(size_t n, size_t error_bound,
Distribution random) {
Matrix<ArbInterval> result(n, n + 1);
Matrix<ArbInterval> temp = random_matrix(n, error_bound, random);
for (size_t i = 0; i < n; ++i)
for (size_t j = 0; j < n; ++j)
result.at(i, j) = temp.at(i, j);
mag_t error;
mag_init(error);
mag_set_ui(error, 1);
mag_div_ui(error, error, 10);
mag_pow_ui(error, error, static_cast<slong>(error_bound));
for (size_t i = 0; i < n; ++i) {
result.at(i, n) = ArbInterval(random());
mag_set(arb_radref(result.at(i, n).data()), error);
}
mag_clear(error);
return result;
}
} // namespace interval
#endif // RANDOM_MATRIX_H