ruby-mpfr 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +5 -2
- data/Manifest.txt +33 -7
- data/README.rdoc +10 -8
- data/Rakefile +4 -3
- data/ext/{extconf.rb → mpfr/extconf.rb} +4 -0
- data/ext/{ruby_mpfr.c → mpfr/ruby_mpfr.c} +466 -199
- data/ext/{ruby_mpfr.h → mpfr/ruby_mpfr.h} +2 -0
- data/ext/mpfr_matrix/mpfr/extconf.rb +7 -0
- data/ext/mpfr_matrix/mpfr/func_mpfr_matrix.c +524 -0
- data/ext/mpfr_matrix/mpfr/func_mpfr_matrix.h +72 -0
- data/ext/mpfr_matrix/mpfr/ruby_mpfr.h +40 -0
- data/ext/mpfr_matrix/mpfr/ruby_mpfr_matrix.c +1056 -0
- data/ext/mpfr_matrix/mpfr/ruby_mpfr_matrix.h +13 -0
- data/lib/mpfr/matrix.rb +145 -0
- data/lib/mpfr/version.rb +3 -0
- data/ruby-mpfr.gemspec +36 -0
- data/spec/mpfr/allocate_spec.rb +60 -0
- data/spec/mpfr/arithmetic_spec.rb +64 -0
- data/spec/mpfr/comparison_spec.rb +21 -0
- data/spec/mpfr/constant_spec.rb +23 -0
- data/spec/mpfr/conversion_spec.rb +14 -0
- data/spec/mpfr/exception_spec.rb +60 -0
- data/spec/mpfr/functions_spec.rb +25 -0
- data/spec/mpfr/generate_number_modulue.rb +44 -0
- data/spec/mpfr/precision_roundmode_spec.rb +65 -0
- data/spec/mpfr/rounding_spec.rb +51 -0
- data/spec/mpfr/set_value_spec.rb +77 -0
- data/spec/mpfr/spec_helper.rb +13 -0
- data/spec/mpfr/string_spec.rb +58 -0
- data/spec/mpfr_matrix/generate_matrix_arguments.rb +55 -0
- data/spec/mpfr_matrix/mpfr_matrix_alloc_spec.rb +126 -0
- data/spec/mpfr_matrix/mpfr_matrix_arithmetic_spec.rb +93 -0
- data/spec/mpfr_matrix/mpfr_matrix_set_element_spec.rb +55 -0
- data/spec/mpfr_matrix/mpfr_matrix_string_spec.rb +31 -0
- data/spec/mpfr_matrix/mpfr_square_matrix_spec.rb +75 -0
- data/spec/mpfr_matrix/spec_helper.rb +16 -0
- data/tasks/extconf.rake +36 -0
- metadata +48 -16
- data/lib/ruby-mpfr.rb +0 -6
- data/spec/ruby-mpfr_spec.rb +0 -11
- data/spec/spec_helper.rb +0 -10
- data/tasks/rspec.rake +0 -21
@@ -26,6 +26,8 @@ VALUE r_mpfr_class, r_mpfr_math;
|
|
26
26
|
#define r_mpfr_check_non_positive_number(c_val) { if(mpfr_number_p(c_val) == 0 && mpfr_sgn(c_val) > 0) rb_raise(rb_eArgError, "Not a non positive number."); }
|
27
27
|
|
28
28
|
void r_mpfr_free(void *ptr);
|
29
|
+
VALUE r_mpfr_make_new_fr_obj(MPFR *ptr);
|
30
|
+
VALUE r_mpfr_make_new_fr_obj2(MPFR *ptr, int prec);
|
29
31
|
VALUE r_mpfr_new_fr_obj(VALUE obj);
|
30
32
|
void r_mpfr_set_robj(MPFR *ptr, VALUE obj, mp_rnd_t rnd);
|
31
33
|
|
@@ -0,0 +1,524 @@
|
|
1
|
+
#include "func_mpfr_matrix.h"
|
2
|
+
|
3
|
+
void mpfr_matrix_init(MPFRMatrix *mat, int row, int column){
|
4
|
+
mat->row = row;
|
5
|
+
mat->column = column;
|
6
|
+
mat->size = row * column;
|
7
|
+
/* mat->data = (MPFR *)malloc(sizeof(MPF) * mat->size); */
|
8
|
+
mat->data = ALLOC_N(MPFR, mat->size);
|
9
|
+
int i;
|
10
|
+
for(i = 0; i < mat->size; i++){
|
11
|
+
mpfr_init(mat->data + i);
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
void mpfr_matrix_set_zeros(MPFRMatrix *mat){
|
16
|
+
int i;
|
17
|
+
for(i = 0; i < mat->size; i++){
|
18
|
+
mpfr_set_si(mat->data + i, 0, GMP_RNDN);
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
void mpfr_matrix_clear(MPFRMatrix *mat){
|
23
|
+
int i;
|
24
|
+
for(i = 0; i < mat->size; i++){
|
25
|
+
mpfr_clear(mat->data + i);
|
26
|
+
}
|
27
|
+
free(mat->data);
|
28
|
+
}
|
29
|
+
|
30
|
+
void mpfr_matrix_set_element(MPFRMatrix *mat, int row, int col, MPFR *a){
|
31
|
+
mpfr_set(mpfr_matrix_get_element(mat, row, col), a, GMP_RNDN);
|
32
|
+
}
|
33
|
+
|
34
|
+
void mpfr_matrix_set(MPFRMatrix *new, MPFRMatrix *x){
|
35
|
+
int i;
|
36
|
+
for(i = 0; i < x->size; i++){
|
37
|
+
mpfr_set(new->data + i, x->data + i, GMP_RNDN);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
void mpfr_matrix_swap(MPFRMatrix *x, MPFRMatrix *y){
|
42
|
+
int i;
|
43
|
+
for (i = 0; i < x->size; i++) {
|
44
|
+
mpfr_swap(mpfr_matrix_get_ptr(x, i), mpfr_matrix_get_ptr(y, i));
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
void mpfr_matrix_row(MPFRMatrix *new, MPFRMatrix *x, int row){
|
49
|
+
int i;
|
50
|
+
for (i = 0; i < x->column; i++) {
|
51
|
+
mpfr_set(new->data + i, mpfr_matrix_get_element(x, row, i), GMP_RNDN);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
void mpfr_matrix_column(MPFRMatrix *new, MPFRMatrix *x, int column){
|
56
|
+
int i;
|
57
|
+
for (i = 0; i < x->row; i++) {
|
58
|
+
mpfr_set(new->data + i, mpfr_matrix_get_element(x, i, column), GMP_RNDN);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
void mpfr_matrix_transpose(MPFRMatrix *new, MPFRMatrix *x){
|
63
|
+
int i, j, index;
|
64
|
+
for(j = 0; j < x->column; j++){
|
65
|
+
index = j * x->row;
|
66
|
+
for(i = 0; i < x->row; i++){
|
67
|
+
mpfr_set(new->data + j + i * new->row, x->data + i + index, GMP_RNDN);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
void mpfr_matrix_neg(MPFRMatrix *new, MPFRMatrix *x){
|
73
|
+
int i;
|
74
|
+
for(i = 0; i < x->size; i++){
|
75
|
+
mpfr_neg(new->data + i, x->data + i, GMP_RNDN);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
/* Return 0 if *x and *y has the same elements. Otherwise return 1. */
|
81
|
+
int mpfr_matrix_equal_p(MPFRMatrix *x, MPFRMatrix *y){
|
82
|
+
int i, ret = 0;
|
83
|
+
if (x->column == y->column && x->row == y->row) {
|
84
|
+
for (i = 0; i < x->size; i++) {
|
85
|
+
if (mpfr_cmp(x->data + i, y->data + i) != 0) {
|
86
|
+
ret = 1;
|
87
|
+
break;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}else{
|
91
|
+
ret = 1;
|
92
|
+
}
|
93
|
+
return ret;
|
94
|
+
}
|
95
|
+
|
96
|
+
void mpfr_matrix_add(MPFRMatrix *new, MPFRMatrix *x, MPFRMatrix *y){
|
97
|
+
int i, j, index;
|
98
|
+
for(j = 0; j < x->column; j++){
|
99
|
+
index = j * x->row;
|
100
|
+
for(i = 0; i < x->row; i++){
|
101
|
+
mpfr_add(new->data + i + index, x->data + i + index, y->data + i + index, GMP_RNDN);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
void mpfr_matrix_sub(MPFRMatrix *new, MPFRMatrix *x, MPFRMatrix *y){
|
107
|
+
int i, j, index;
|
108
|
+
for(j = 0; j < x->column; j++){
|
109
|
+
index = j * x->row;
|
110
|
+
for(i = 0; i < x->row; i++){
|
111
|
+
mpfr_sub(new->data + i + index, x->data + i + index, y->data + i + index, GMP_RNDN);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
/* x and new must be different pointer from each other. */
|
117
|
+
void mpfr_matrix_mul(MPFRMatrix *new, MPFRMatrix *x, MPFRMatrix *y){
|
118
|
+
int i, j, k, index, index_y;
|
119
|
+
MPFR *tmp;
|
120
|
+
r_mpfr_temp_alloc_init(tmp);
|
121
|
+
for(i = 0; i < new->size; i++){
|
122
|
+
mpfr_set_si(new->data + i, 0, GMP_RNDN);
|
123
|
+
}
|
124
|
+
for(j = 0; j < y->column; j++){
|
125
|
+
for(i = 0; i < x->row; i++){
|
126
|
+
index = i + j * new->row;
|
127
|
+
index_y = j * y->row;
|
128
|
+
for(k = 0; k < x->column; k++){
|
129
|
+
mpfr_mul(tmp, x->data + i + k * x->row, y->data + k + index_y, GMP_RNDN);
|
130
|
+
mpfr_add(new->data + index, new->data + index, tmp, GMP_RNDN);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
}
|
134
|
+
r_mpfr_temp_free(tmp);
|
135
|
+
}
|
136
|
+
|
137
|
+
void mpfr_matrix_mul_scalar(MPFRMatrix *new, MPFRMatrix *x, MPFR *scalar){
|
138
|
+
int i;
|
139
|
+
for(i = 0; i < x->size; i++){
|
140
|
+
mpfr_mul(new->data + i, x->data + i, scalar, GMP_RNDN);
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
void mpfr_matrix_div_scalar(MPFRMatrix *new, MPFRMatrix *x, MPFR *scalar){
|
145
|
+
int i;
|
146
|
+
for(i = 0; i < x->size; i++){
|
147
|
+
mpfr_div(new->data + i, x->data + i, scalar, GMP_RNDN);
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
void mpfr_matrix_inner_product(MPFR *pr, MPFRMatrix *x, MPFRMatrix *y){
|
152
|
+
MPFR *tmp;
|
153
|
+
r_mpfr_temp_alloc_init(tmp);
|
154
|
+
int i;
|
155
|
+
mpfr_set_si(pr, 0, GMP_RNDN);
|
156
|
+
for(i = 0; i < x->size; i++){
|
157
|
+
mpfr_mul(tmp, x->data + i, y->data + i, GMP_RNDN);
|
158
|
+
mpfr_add(pr, pr, tmp, GMP_RNDN);
|
159
|
+
}
|
160
|
+
r_mpfr_temp_free(tmp);
|
161
|
+
}
|
162
|
+
|
163
|
+
void mpfr_matrix_vector_distance(MPFR *distance, MPFRMatrix *x, MPFRMatrix *y){
|
164
|
+
MPFR *tmp;
|
165
|
+
r_mpfr_temp_alloc_init(tmp);
|
166
|
+
int i;
|
167
|
+
mpfr_set_si(distance, 0, GMP_RNDN);
|
168
|
+
for(i = 0; i < x->size; i++){
|
169
|
+
mpfr_sub(tmp, x->data + i, y->data + i, GMP_RNDN);
|
170
|
+
mpfr_mul(tmp, tmp, tmp, GMP_RNDN);
|
171
|
+
mpfr_add(distance, distance, tmp, GMP_RNDN);
|
172
|
+
}
|
173
|
+
mpfr_sqrt(distance, distance, GMP_RNDN);
|
174
|
+
r_mpfr_temp_free(tmp);
|
175
|
+
}
|
176
|
+
|
177
|
+
void mpfr_matrix_vector_norm(MPFR *norm, MPFRMatrix *x){
|
178
|
+
MPFR *tmp;
|
179
|
+
r_mpfr_temp_alloc_init(tmp);
|
180
|
+
int i;
|
181
|
+
mpfr_set_si(norm, 0, GMP_RNDN);
|
182
|
+
for(i = 0; i < x->size; i++){
|
183
|
+
mpfr_mul(tmp, x->data + i, x->data + i, GMP_RNDN);
|
184
|
+
mpfr_add(norm, norm, tmp, GMP_RNDN);
|
185
|
+
}
|
186
|
+
mpfr_sqrt(norm, norm, GMP_RNDN);
|
187
|
+
r_mpfr_temp_free(tmp);
|
188
|
+
}
|
189
|
+
|
190
|
+
void mpfr_matrix_max_norm(MPFR *norm, MPFRMatrix *x){
|
191
|
+
MPFR *tmp;
|
192
|
+
r_mpfr_temp_alloc_init(tmp);
|
193
|
+
int i;
|
194
|
+
mpfr_set_si(norm, 0, GMP_RNDN);
|
195
|
+
for(i = 0; i < x->size; i++){
|
196
|
+
mpfr_abs(tmp, x->data + i, GMP_RNDN);
|
197
|
+
if(mpfr_cmp(tmp, norm) > 0){
|
198
|
+
mpfr_set(norm, tmp, GMP_RNDN);
|
199
|
+
}
|
200
|
+
}
|
201
|
+
r_mpfr_temp_free(tmp);
|
202
|
+
}
|
203
|
+
|
204
|
+
void mpfr_col_vector_init(MPFRMatrix *mat, int row){
|
205
|
+
mat->row = row;
|
206
|
+
mat->column = 1;
|
207
|
+
mat->size = row;
|
208
|
+
/* mat->data = (MPFR *)malloc(sizeof(MPF) * mat->size); */
|
209
|
+
mat->data = ALLOC_N(MPFR, mat->size);
|
210
|
+
int i;
|
211
|
+
for(i = 0; i < mat->size; i++){
|
212
|
+
mpfr_init(mat->data + i);
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
void mpfr_row_vector_init(MPFRMatrix *mat, int column){
|
217
|
+
mat->row = 1;
|
218
|
+
mat->column = column;
|
219
|
+
mat->size = column;
|
220
|
+
/* mat->data = (MPFR *)malloc(sizeof(MPF) * mat->size); */
|
221
|
+
mat->data = ALLOC_N(MPFR, mat->size);
|
222
|
+
int i;
|
223
|
+
for(i = 0; i < mat->size; i++){
|
224
|
+
mpfr_init(mat->data + i);
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
/* If length of MPFRMatrix *x is zero, return 1. Otherwise return 0. */
|
229
|
+
int mpfr_vector_normalize(MPFRMatrix *new, MPFRMatrix *x){
|
230
|
+
MPFR *norm;
|
231
|
+
r_mpfr_temp_alloc_init(norm);
|
232
|
+
mpfr_matrix_vector_norm(norm, x);
|
233
|
+
int i, j, index, ret = 0;
|
234
|
+
if(mpfr_cmp_ui(norm, 0) > 0){
|
235
|
+
for(j = 0; j < x->column; j++){
|
236
|
+
index = j * x->row;
|
237
|
+
for(i = 0; i < x->row; i++){
|
238
|
+
mpfr_div(new->data + i + index, x->data + i + index, norm, GMP_RNDN);
|
239
|
+
}
|
240
|
+
}
|
241
|
+
}else{
|
242
|
+
ret = 1;
|
243
|
+
}
|
244
|
+
r_mpfr_temp_free(norm);
|
245
|
+
return ret;
|
246
|
+
}
|
247
|
+
|
248
|
+
/* If length of MPFRMatrix *x is zero, return 1. Otherwise return 0. */
|
249
|
+
int mpfr_vector_set_length(MPFRMatrix *new, MPFRMatrix *x, MPFR *length){
|
250
|
+
MPFR *factor;
|
251
|
+
r_mpfr_temp_alloc_init(factor);
|
252
|
+
mpfr_matrix_vector_norm(factor, x);
|
253
|
+
int i, j, index, ret = 0;
|
254
|
+
if(mpfr_cmp_ui(factor, 0) > 0){
|
255
|
+
mpfr_ui_div(factor, 1, factor, GMP_RNDN);
|
256
|
+
mpfr_mul(factor, factor, length, GMP_RNDN);
|
257
|
+
for(j = 0; j < x->column; j++){
|
258
|
+
index = j * x->row;
|
259
|
+
for(i = 0; i < x->row; i++){
|
260
|
+
mpfr_mul(new->data + i + index, x->data + i + index, factor, GMP_RNDN);
|
261
|
+
}
|
262
|
+
}
|
263
|
+
}else{
|
264
|
+
ret = 1;
|
265
|
+
}
|
266
|
+
r_mpfr_temp_free(factor);
|
267
|
+
return ret;
|
268
|
+
}
|
269
|
+
|
270
|
+
void mpfr_vector_midpoint(MPFRMatrix *new, MPFRMatrix *x, MPFRMatrix *y){
|
271
|
+
int i;
|
272
|
+
for (i = 0; i < new->size; i++) {
|
273
|
+
mpfr_add(mpfr_matrix_get_ptr(new, i), mpfr_matrix_get_ptr(x, i), mpfr_matrix_get_ptr(y, i), GMP_RNDN);
|
274
|
+
mpfr_div_ui(mpfr_matrix_get_ptr(new, i), mpfr_matrix_get_ptr(new, i), 2, GMP_RNDN);
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
/* "distance between *new and *x" / "distance between *y and *x" = *div */
|
279
|
+
void mpfr_vector_dividing_point(MPFRMatrix *new, MPFRMatrix *x, MPFRMatrix *y, MPFR *div){
|
280
|
+
MPFRMatrix *tmp_x, *tmp_y;
|
281
|
+
r_mpfr_matrix_temp_alloc_init(tmp_x, new->row, new->column);
|
282
|
+
r_mpfr_matrix_temp_alloc_init(tmp_y, new->row, new->column);
|
283
|
+
|
284
|
+
MPFR *ratio;
|
285
|
+
r_mpfr_temp_alloc_init(ratio);
|
286
|
+
mpfr_ui_sub(ratio, 1, div, GMP_RNDN);
|
287
|
+
mpfr_matrix_mul_scalar(tmp_y, y, ratio);
|
288
|
+
mpfr_matrix_mul_scalar(tmp_x, x, div);
|
289
|
+
mpfr_matrix_add(new, tmp_x, tmp_y);
|
290
|
+
|
291
|
+
r_mpfr_matrix_temp_free(tmp_x);
|
292
|
+
r_mpfr_matrix_temp_free(tmp_y);
|
293
|
+
r_mpfr_temp_free(ratio);
|
294
|
+
}
|
295
|
+
|
296
|
+
/* If length of MPFRMatrix *x, return 1. Set normalized normal vector to MPFRMatrix *new. */
|
297
|
+
int mpfr_2d_normal_vector(MPFRMatrix *new, MPFRMatrix *x){
|
298
|
+
int ret = 0;
|
299
|
+
if (mpfr_vector_normalize(new, x) == 0){
|
300
|
+
mpfr_swap(new->data, new->data + 1);
|
301
|
+
mpfr_neg(new->data + 1, new->data + 1, GMP_RNDN);
|
302
|
+
}else{
|
303
|
+
ret = 1;
|
304
|
+
}
|
305
|
+
return ret;
|
306
|
+
}
|
307
|
+
|
308
|
+
static void mpfr_2d_square_matrix_determinant(MPFR *det, MPFRMatrix *x){
|
309
|
+
MPFR *tmp;
|
310
|
+
r_mpfr_temp_alloc_init(tmp);
|
311
|
+
mpfr_mul(det, x->data, x->data + 3, GMP_RNDN);
|
312
|
+
mpfr_mul(tmp, x->data + 1, x->data + 2, GMP_RNDN);
|
313
|
+
mpfr_sub(det, det, tmp, GMP_RNDN);
|
314
|
+
r_mpfr_temp_free(tmp);
|
315
|
+
}
|
316
|
+
|
317
|
+
static void mpfr_3d_square_matrix_determinant(MPFR *det, MPFRMatrix *x){
|
318
|
+
MPFR *tmp;
|
319
|
+
r_mpfr_temp_alloc_init(tmp);
|
320
|
+
|
321
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 0, 0), mpfr_matrix_get_element(x, 1, 1), GMP_RNDN);
|
322
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 2, 2), tmp, GMP_RNDN);
|
323
|
+
mpfr_set(det, tmp, GMP_RNDN);
|
324
|
+
|
325
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 0, 1), mpfr_matrix_get_element(x, 1, 2), GMP_RNDN);
|
326
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 2, 0), tmp, GMP_RNDN);
|
327
|
+
mpfr_add(det, det, tmp, GMP_RNDN);
|
328
|
+
|
329
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 0, 2), mpfr_matrix_get_element(x, 1, 0), GMP_RNDN);
|
330
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 2, 1), tmp, GMP_RNDN);
|
331
|
+
mpfr_add(det, det, tmp, GMP_RNDN);
|
332
|
+
|
333
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 0, 0), mpfr_matrix_get_element(x, 1, 2), GMP_RNDN);
|
334
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 2, 1), tmp, GMP_RNDN);
|
335
|
+
mpfr_sub(det, det, tmp, GMP_RNDN);
|
336
|
+
|
337
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 0, 1), mpfr_matrix_get_element(x, 1, 0), GMP_RNDN);
|
338
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 2, 2), tmp, GMP_RNDN);
|
339
|
+
mpfr_sub(det, det, tmp, GMP_RNDN);
|
340
|
+
|
341
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 0, 2), mpfr_matrix_get_element(x, 1, 1), GMP_RNDN);
|
342
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(x, 2, 0), tmp, GMP_RNDN);
|
343
|
+
mpfr_sub(det, det, tmp, GMP_RNDN);
|
344
|
+
|
345
|
+
r_mpfr_temp_free(tmp);
|
346
|
+
}
|
347
|
+
|
348
|
+
/* Return 0 if we execute even permutation for matrix, 1 if odd permutation or */
|
349
|
+
/* -1 if matrix is singular. */
|
350
|
+
int mpfr_square_matrix_lu_decomp (MPFRMatrix *ret, int *indx, MPFRMatrix *x){
|
351
|
+
int i, j, k, imax, ret_val = 0;
|
352
|
+
MPFR *big, *sum, *dum, *tmp;
|
353
|
+
MPFRMatrix *vv, *tmp_ret;
|
354
|
+
r_mpfr_matrix_temp_alloc_init(tmp_ret, ret->row, ret->column);
|
355
|
+
|
356
|
+
mpfr_matrix_set(tmp_ret, x);
|
357
|
+
|
358
|
+
r_mpfr_temp_alloc_init(big);
|
359
|
+
r_mpfr_temp_alloc_init(sum);
|
360
|
+
r_mpfr_temp_alloc_init(dum);
|
361
|
+
r_mpfr_temp_alloc_init(tmp);
|
362
|
+
r_mpfr_matrix_temp_alloc_init(vv, x->size, 1);
|
363
|
+
for (i = 0; i < tmp_ret->row; i++) {
|
364
|
+
mpfr_set_si(big, 0, GMP_RNDN);
|
365
|
+
for (j = 0; j < tmp_ret->column; j++) {
|
366
|
+
mpfr_abs(tmp, mpfr_matrix_get_element(x, i, j), GMP_RNDN);
|
367
|
+
if (mpfr_cmp(tmp, big) > 0) {
|
368
|
+
mpfr_set(big, tmp, GMP_RNDN);
|
369
|
+
}
|
370
|
+
}
|
371
|
+
if (mpfr_cmp_si(big, 0) == 0) {
|
372
|
+
ret_val = -1;
|
373
|
+
break;
|
374
|
+
}
|
375
|
+
mpfr_ui_div(vv->data + i, 1, big, GMP_RNDN);
|
376
|
+
}
|
377
|
+
|
378
|
+
if (ret_val >= 0) {
|
379
|
+
for (j = 0; j < tmp_ret->column; j++) {
|
380
|
+
for (i = 0; i < j; i++) {
|
381
|
+
mpfr_set(sum, mpfr_matrix_get_element(tmp_ret, i, j), GMP_RNDN);
|
382
|
+
for (k = 0; k < i; k++) {
|
383
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(tmp_ret, i, k), mpfr_matrix_get_element(tmp_ret, k, j), GMP_RNDN);
|
384
|
+
mpfr_sub(sum, sum, tmp, GMP_RNDN);
|
385
|
+
}
|
386
|
+
mpfr_set(mpfr_matrix_get_element(tmp_ret, i, j), sum, GMP_RNDN);
|
387
|
+
}
|
388
|
+
mpfr_set_si(big, 0, GMP_RNDN);
|
389
|
+
imax = j;
|
390
|
+
for (i = j; i < tmp_ret->row; i++) {
|
391
|
+
mpfr_set(sum, mpfr_matrix_get_element(tmp_ret, i, j), GMP_RNDN);
|
392
|
+
for (k = 0; k < j; k++) {
|
393
|
+
mpfr_mul(tmp, mpfr_matrix_get_element(tmp_ret, i, k), mpfr_matrix_get_element(tmp_ret, k, j), GMP_RNDN);
|
394
|
+
mpfr_sub(sum, sum, tmp, GMP_RNDN);
|
395
|
+
}
|
396
|
+
mpfr_set(mpfr_matrix_get_element(tmp_ret, i, j), sum, GMP_RNDN);
|
397
|
+
mpfr_abs(dum, sum, GMP_RNDN);
|
398
|
+
mpfr_mul(dum, vv->data + i, dum, GMP_RNDN);
|
399
|
+
if (mpfr_cmp(dum, big) >= 0) {
|
400
|
+
mpfr_set(big, dum, GMP_RNDN);
|
401
|
+
imax = i;
|
402
|
+
}
|
403
|
+
}
|
404
|
+
if (j != imax) {
|
405
|
+
for (k = 0; k < tmp_ret->column; k++) {
|
406
|
+
mpfr_set(dum, mpfr_matrix_get_element(tmp_ret, imax, k), GMP_RNDN);
|
407
|
+
mpfr_set(mpfr_matrix_get_element(tmp_ret, imax, k), mpfr_matrix_get_element(tmp_ret, j, k), GMP_RNDN);
|
408
|
+
mpfr_set(mpfr_matrix_get_element(tmp_ret, j, k), dum, GMP_RNDN);
|
409
|
+
}
|
410
|
+
ret_val = (ret_val + 1) % 2;
|
411
|
+
mpfr_set(vv->data + imax, vv->data + j, GMP_RNDN);
|
412
|
+
}
|
413
|
+
indx[j] = imax;
|
414
|
+
if (mpfr_cmp_si(mpfr_matrix_get_element(tmp_ret, j, j), 0) == 0) {
|
415
|
+
ret_val = -1;
|
416
|
+
break;
|
417
|
+
}
|
418
|
+
if (j < tmp_ret->row - 1) {
|
419
|
+
mpfr_ui_div(dum, 1, mpfr_matrix_get_element(tmp_ret, j, j), GMP_RNDN);
|
420
|
+
for (i = j + 1; i < tmp_ret->row; i++) {
|
421
|
+
mpfr_mul(mpfr_matrix_get_element(tmp_ret, i, j), mpfr_matrix_get_element(tmp_ret, i, j), dum, GMP_RNDN);
|
422
|
+
}
|
423
|
+
}
|
424
|
+
}
|
425
|
+
}
|
426
|
+
mpfr_matrix_set(ret, tmp_ret);
|
427
|
+
|
428
|
+
r_mpfr_matrix_temp_free(tmp_ret);
|
429
|
+
r_mpfr_temp_free(big);
|
430
|
+
r_mpfr_temp_free(sum);
|
431
|
+
r_mpfr_temp_free(dum);
|
432
|
+
r_mpfr_temp_free(tmp);
|
433
|
+
r_mpfr_matrix_temp_free(vv);
|
434
|
+
return ret_val;
|
435
|
+
}
|
436
|
+
|
437
|
+
void mpfr_square_matrix_determinant(MPFR *det, MPFRMatrix *x){
|
438
|
+
if (x->column == 2 && x->row == 2){
|
439
|
+
mpfr_2d_square_matrix_determinant(det, x);
|
440
|
+
}else if(x->column == 3 && x->row == 3){
|
441
|
+
mpfr_3d_square_matrix_determinant(det, x);
|
442
|
+
}else{
|
443
|
+
MPFRMatrix *ptr_lu;
|
444
|
+
r_mpfr_matrix_temp_alloc_init(ptr_lu, x->row, x->column);
|
445
|
+
int indx[x->row], i;
|
446
|
+
if((i = mpfr_square_matrix_lu_decomp (ptr_lu, indx, x)) >= 0){
|
447
|
+
if (i == 0) {
|
448
|
+
mpfr_set_si(det, 1, GMP_RNDN);
|
449
|
+
} else if (i == 1) {
|
450
|
+
mpfr_set_si(det, -1, GMP_RNDN);
|
451
|
+
}
|
452
|
+
for (i = 0; i < x->row; i++) {
|
453
|
+
mpfr_mul(det, det, mpfr_matrix_get_element(ptr_lu, i, i), GMP_RNDN);
|
454
|
+
}
|
455
|
+
}else{
|
456
|
+
mpfr_set_ui(det, 0, GMP_RNDN);
|
457
|
+
}
|
458
|
+
r_mpfr_matrix_temp_free(ptr_lu);
|
459
|
+
}
|
460
|
+
|
461
|
+
}
|
462
|
+
|
463
|
+
void mpfr_square_matrix_qr_decomp(MPFRMatrix *q, MPFRMatrix *r, MPFRMatrix *x){
|
464
|
+
MPFRMatrix *q_mat, *r_mat;
|
465
|
+
r_mpfr_matrix_temp_alloc_init(q_mat, q->row, q->column);
|
466
|
+
r_mpfr_matrix_temp_alloc_init(r_mat, r->row, r->column);
|
467
|
+
|
468
|
+
int size = x->row;
|
469
|
+
MPFRMatrix *ary;
|
470
|
+
r_mpfr_matrix_temp_alloc_init(ary, size, size);
|
471
|
+
mpfr_matrix_set(ary, x);
|
472
|
+
MPFR *tmp;
|
473
|
+
r_mpfr_temp_alloc_init(tmp);
|
474
|
+
int i, j, k, ind1, ind2, ind3;
|
475
|
+
for (i = 0; i < size; i++) {
|
476
|
+
ind1 = i * size;
|
477
|
+
ind2 = i + ind1;
|
478
|
+
mpfr_set_si(r_mat->data + ind2, 0, GMP_RNDN);
|
479
|
+
for (j = 0; j < size; j++) {
|
480
|
+
mpfr_mul(tmp, ary->data + j + ind1, ary->data + j + ind1, GMP_RNDN);
|
481
|
+
mpfr_add(r_mat->data + ind2, r_mat->data + ind2, tmp, GMP_RNDN);
|
482
|
+
}
|
483
|
+
mpfr_sqrt(r_mat->data + ind2, r_mat->data + ind2, GMP_RNDN);
|
484
|
+
for (j = 0; j < size; j++) {
|
485
|
+
mpfr_div(q_mat->data + j + ind1, ary->data + j + ind1, r_mat->data + ind2, GMP_RNDN);
|
486
|
+
}
|
487
|
+
for (j = (i + 1); j < size; j++) {
|
488
|
+
ind2 = j * size;
|
489
|
+
ind3 = i + ind2;
|
490
|
+
mpfr_set_si(r_mat->data + ind3, 0, GMP_RNDN);
|
491
|
+
for (k = 0; k < size; k++) {
|
492
|
+
mpfr_mul(tmp, q_mat->data + k + ind1, ary->data + k + ind2, GMP_RNDN);
|
493
|
+
mpfr_add(r_mat->data + ind3, r_mat->data + ind3, tmp, GMP_RNDN);
|
494
|
+
}
|
495
|
+
for (k = 0; k < size; k++) {
|
496
|
+
mpfr_mul(tmp, r_mat->data + ind3, q_mat->data + k + ind1, GMP_RNDN);
|
497
|
+
mpfr_sub(ary->data + k + ind2, ary->data + k + ind2, tmp, GMP_RNDN);
|
498
|
+
}
|
499
|
+
}
|
500
|
+
}
|
501
|
+
mpfr_matrix_set(q, q_mat);
|
502
|
+
mpfr_matrix_set(r, r_mat);
|
503
|
+
|
504
|
+
r_mpfr_matrix_temp_free(q_mat);
|
505
|
+
r_mpfr_matrix_temp_free(r_mat);
|
506
|
+
r_mpfr_matrix_temp_free(ary);
|
507
|
+
r_mpfr_temp_free(tmp);
|
508
|
+
}
|
509
|
+
|
510
|
+
void mpfr_square_matrix_identity(MPFRMatrix *id){
|
511
|
+
int i, j, index;
|
512
|
+
for (j = 0; j < id->column; j++) {
|
513
|
+
index = j * id->row;
|
514
|
+
for (i = 0; i < id->row; i++) {
|
515
|
+
if(i == j){
|
516
|
+
mpfr_set_si(id->data + i + index, 1, GMP_RNDN);
|
517
|
+
}else{
|
518
|
+
mpfr_set_si(id->data + i + index, 0, GMP_RNDN);
|
519
|
+
}
|
520
|
+
}
|
521
|
+
}
|
522
|
+
|
523
|
+
}
|
524
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <ruby.h>
|
3
|
+
#include <mpfr.h>
|
4
|
+
#include "ruby_mpfr.h"
|
5
|
+
|
6
|
+
typedef struct __MPFRMatrix{
|
7
|
+
int row, column, size;
|
8
|
+
MPFR *data;
|
9
|
+
} MPFRMatrix;
|
10
|
+
|
11
|
+
/*
|
12
|
+
1 2 3
|
13
|
+
4 5 6
|
14
|
+
|
15
|
+
row = 2
|
16
|
+
column = 3
|
17
|
+
size = 6
|
18
|
+
MPFR *data 1 4 2 5 3 6
|
19
|
+
|
20
|
+
(i, j) element => data + i + row * j
|
21
|
+
0 <= i < 2, 0 <= j < 3
|
22
|
+
*/
|
23
|
+
|
24
|
+
#define r_mpfr_make_matrix_struct(ruby_var, c_var) { ruby_var = Data_Make_Struct(r_mpfr_matrix, MPFRMatrix, 0, r_mpfr_matrix_free, c_var); }
|
25
|
+
#define r_mpfr_get_matrix_struct(c_var, ruby_var) { Data_Get_Struct(ruby_var, MPFRMatrix, c_var); }
|
26
|
+
|
27
|
+
#define r_mpfr_make_square_matrix_struct(ruby_var, c_var) { ruby_var = Data_Make_Struct(r_mpfr_square_matrix, MPFRMatrix, 0, r_mpfr_matrix_free, c_var); }
|
28
|
+
#define r_mpfr_make_col_vector_struct(ruby_var, c_var) { ruby_var = Data_Make_Struct(r_mpfr_col_vector, MPFRMatrix, 0, r_mpfr_matrix_free, c_var); }
|
29
|
+
#define r_mpfr_make_row_vector_struct(ruby_var, c_var) { ruby_var = Data_Make_Struct(r_mpfr_row_vector, MPFRMatrix, 0, r_mpfr_matrix_free, c_var); }
|
30
|
+
|
31
|
+
#define r_mpfr_matrix_temp_alloc_init(c_var, i, j) { c_var = ALLOC_N(MPFRMatrix, 1); mpfr_matrix_init(c_var, i, j); }
|
32
|
+
#define r_mpfr_matrix_temp_free(c_var) { mpfr_matrix_clear(c_var); free(c_var); }
|
33
|
+
|
34
|
+
#define mpfr_matrix_get_ptr(matrix, i) (matrix->data + i)
|
35
|
+
#define mpfr_matrix_get_element(matrix, i, j) (matrix->data + i + matrix->row * j)
|
36
|
+
|
37
|
+
void mpfr_matrix_clear(MPFRMatrix *mat);
|
38
|
+
void mpfr_matrix_init(MPFRMatrix *mat, int row, int column);
|
39
|
+
void mpfr_matrix_set_zeros(MPFRMatrix *mat);
|
40
|
+
void mpfr_matrix_set_element(MPFRMatrix *mat, int row, int col, MPFR *a);
|
41
|
+
void mpfr_matrix_set(MPFRMatrix *new, MPFRMatrix *x);
|
42
|
+
void mpfr_matrix_swap(MPFRMatrix *x, MPFRMatrix *y);
|
43
|
+
|
44
|
+
void mpfr_matrix_row(MPFRMatrix *new, MPFRMatrix *x, int row);
|
45
|
+
void mpfr_matrix_column(MPFRMatrix *new, MPFRMatrix *x, int column);
|
46
|
+
void mpfr_matrix_transpose(MPFRMatrix *new, MPFRMatrix *x);
|
47
|
+
void mpfr_matrix_neg(MPFRMatrix *new, MPFRMatrix *x);
|
48
|
+
|
49
|
+
int mpfr_matrix_equal_p(MPFRMatrix *x, MPFRMatrix *y);
|
50
|
+
void mpfr_matrix_add(MPFRMatrix *new, MPFRMatrix *x, MPFRMatrix *y);
|
51
|
+
void mpfr_matrix_sub(MPFRMatrix *new, MPFRMatrix *x, MPFRMatrix *y);
|
52
|
+
void mpfr_matrix_mul(MPFRMatrix *new, MPFRMatrix *x, MPFRMatrix *y);
|
53
|
+
void mpfr_matrix_mul_scalar(MPFRMatrix *new, MPFRMatrix *x, MPFR *scalar);
|
54
|
+
void mpfr_matrix_div_scalar(MPFRMatrix *new, MPFRMatrix *x, MPFR *scalar);
|
55
|
+
void mpfr_matrix_inner_product(MPFR *pr, MPFRMatrix *x, MPFRMatrix *y);
|
56
|
+
void mpfr_matrix_vector_distance(MPFR *distance, MPFRMatrix *x, MPFRMatrix *y);
|
57
|
+
void mpfr_matrix_vector_norm(MPFR *norm, MPFRMatrix *x);
|
58
|
+
void mpfr_matrix_max_norm(MPFR *norm, MPFRMatrix *x);
|
59
|
+
|
60
|
+
void mpfr_col_vector_init(MPFRMatrix *mat, int row);
|
61
|
+
void mpfr_row_vector_init(MPFRMatrix *mat, int column);
|
62
|
+
int mpfr_vector_normalize(MPFRMatrix *new, MPFRMatrix *x);
|
63
|
+
int mpfr_vector_set_length(MPFRMatrix *new, MPFRMatrix *x, MPFR *l);
|
64
|
+
void mpfr_vector_midpoint(MPFRMatrix *new, MPFRMatrix *x, MPFRMatrix *y);
|
65
|
+
void mpfr_vector_dividing_point(MPFRMatrix *new, MPFRMatrix *x, MPFRMatrix *y, MPFR *div);
|
66
|
+
|
67
|
+
int mpfr_square_matrix_lu_decomp (MPFRMatrix *ret, int *indx, MPFRMatrix *x);
|
68
|
+
void mpfr_square_matrix_determinant(MPFR *det, MPFRMatrix *x);
|
69
|
+
void mpfr_square_matrix_qr_decomp(MPFRMatrix *q, MPFRMatrix *r, MPFRMatrix *x);
|
70
|
+
void mpfr_square_matrix_identity(MPFRMatrix *id);
|
71
|
+
|
72
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#ifndef _RUBY_MPFR_H_
|
2
|
+
#define _RUBY_MPFR_H_
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
#include <mpfr.h>
|
6
|
+
#include <stdio.h>
|
7
|
+
|
8
|
+
typedef __mpfr_struct MPFR;
|
9
|
+
|
10
|
+
VALUE r_mpfr_class, r_mpfr_math;
|
11
|
+
|
12
|
+
#define r_mpfr_make_struct(ruby_var, c_var) { ruby_var = Data_Make_Struct(r_mpfr_class, MPFR, 0, r_mpfr_free, c_var); }
|
13
|
+
#define r_mpfr_make_struct_init(ruby_var, c_var) { r_mpfr_make_struct(ruby_var, c_var); mpfr_init(c_var); }
|
14
|
+
#define r_mpfr_make_struct_init2(ruby_var, c_var, prec) { r_mpfr_make_struct(ruby_var, c_var); mpfr_init2(c_var, prec); }
|
15
|
+
#define r_mpfr_get_struct(c_var, ruby_var) { Data_Get_Struct(ruby_var, MPFR, c_var); }
|
16
|
+
|
17
|
+
#define r_mpfr_temp_alloc(var) { var=ALLOC_N(MPFR, 1); }
|
18
|
+
#define r_mpfr_temp_alloc_init(var) { r_mpfr_temp_alloc(var); mpfr_init(var); }
|
19
|
+
#define r_mpfr_temp_alloc_init2(var, prec) { r_mpfr_temp_alloc(var); mpfr_init2(var, prec); }
|
20
|
+
#define r_mpfr_temp_free(var) { mpfr_clear(var); free(var); }
|
21
|
+
|
22
|
+
#define r_mpfr_check_number(c_val) { if(mpfr_number_p(c_val) == 0) rb_raise(rb_eArgError, "Not an ordinary number."); }
|
23
|
+
#define r_mpfr_check_positive_number(c_val) { if(mpfr_number_p(c_val) == 0 && mpfr_sgn(c_val) <= 0) rb_raise(rb_eArgError, "Not a positive number."); }
|
24
|
+
#define r_mpfr_check_non_negative_number(c_val) { if(mpfr_number_p(c_val) == 0 && mpfr_sgn(c_val) < 0) rb_raise(rb_eArgError, "Not a non negative number."); }
|
25
|
+
#define r_mpfr_check_negative_number(c_val) { if(mpfr_number_p(c_val) == 0 && mpfr_sgn(c_val) >= 0) rb_raise(rb_eArgError, "Not a negative number."); }
|
26
|
+
#define r_mpfr_check_non_positive_number(c_val) { if(mpfr_number_p(c_val) == 0 && mpfr_sgn(c_val) > 0) rb_raise(rb_eArgError, "Not a non positive number."); }
|
27
|
+
|
28
|
+
void r_mpfr_free(void *ptr);
|
29
|
+
VALUE r_mpfr_make_new_fr_obj(MPFR *ptr);
|
30
|
+
VALUE r_mpfr_make_new_fr_obj2(MPFR *ptr, int prec);
|
31
|
+
VALUE r_mpfr_new_fr_obj(VALUE obj);
|
32
|
+
void r_mpfr_set_robj(MPFR *ptr, VALUE obj, mp_rnd_t rnd);
|
33
|
+
|
34
|
+
mp_rnd_t r_mpfr_rnd_from_value(VALUE rnd);
|
35
|
+
mp_rnd_t r_mpfr_rnd_from_optional_argument(int min, int max, int argc, VALUE *argv);
|
36
|
+
mp_rnd_t r_mpfr_prec_from_optional_argument(int min, int max, int argc, VALUE *argv);
|
37
|
+
void r_mpfr_get_rnd_prec_from_optional_arguments(mp_rnd_t *rnd, mp_prec_t *prec, int min, int max, int argc, VALUE *argv);
|
38
|
+
|
39
|
+
#endif /* _RUBY_MPFR_H_ */
|
40
|
+
|