ruby-mpfr 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/History.txt +5 -2
  2. data/Manifest.txt +33 -7
  3. data/README.rdoc +10 -8
  4. data/Rakefile +4 -3
  5. data/ext/{extconf.rb → mpfr/extconf.rb} +4 -0
  6. data/ext/{ruby_mpfr.c → mpfr/ruby_mpfr.c} +466 -199
  7. data/ext/{ruby_mpfr.h → mpfr/ruby_mpfr.h} +2 -0
  8. data/ext/mpfr_matrix/mpfr/extconf.rb +7 -0
  9. data/ext/mpfr_matrix/mpfr/func_mpfr_matrix.c +524 -0
  10. data/ext/mpfr_matrix/mpfr/func_mpfr_matrix.h +72 -0
  11. data/ext/mpfr_matrix/mpfr/ruby_mpfr.h +40 -0
  12. data/ext/mpfr_matrix/mpfr/ruby_mpfr_matrix.c +1056 -0
  13. data/ext/mpfr_matrix/mpfr/ruby_mpfr_matrix.h +13 -0
  14. data/lib/mpfr/matrix.rb +145 -0
  15. data/lib/mpfr/version.rb +3 -0
  16. data/ruby-mpfr.gemspec +36 -0
  17. data/spec/mpfr/allocate_spec.rb +60 -0
  18. data/spec/mpfr/arithmetic_spec.rb +64 -0
  19. data/spec/mpfr/comparison_spec.rb +21 -0
  20. data/spec/mpfr/constant_spec.rb +23 -0
  21. data/spec/mpfr/conversion_spec.rb +14 -0
  22. data/spec/mpfr/exception_spec.rb +60 -0
  23. data/spec/mpfr/functions_spec.rb +25 -0
  24. data/spec/mpfr/generate_number_modulue.rb +44 -0
  25. data/spec/mpfr/precision_roundmode_spec.rb +65 -0
  26. data/spec/mpfr/rounding_spec.rb +51 -0
  27. data/spec/mpfr/set_value_spec.rb +77 -0
  28. data/spec/mpfr/spec_helper.rb +13 -0
  29. data/spec/mpfr/string_spec.rb +58 -0
  30. data/spec/mpfr_matrix/generate_matrix_arguments.rb +55 -0
  31. data/spec/mpfr_matrix/mpfr_matrix_alloc_spec.rb +126 -0
  32. data/spec/mpfr_matrix/mpfr_matrix_arithmetic_spec.rb +93 -0
  33. data/spec/mpfr_matrix/mpfr_matrix_set_element_spec.rb +55 -0
  34. data/spec/mpfr_matrix/mpfr_matrix_string_spec.rb +31 -0
  35. data/spec/mpfr_matrix/mpfr_square_matrix_spec.rb +75 -0
  36. data/spec/mpfr_matrix/spec_helper.rb +16 -0
  37. data/tasks/extconf.rake +36 -0
  38. metadata +48 -16
  39. data/lib/ruby-mpfr.rb +0 -6
  40. data/spec/ruby-mpfr_spec.rb +0 -11
  41. data/spec/spec_helper.rb +0 -10
  42. 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,7 @@
1
+ require 'mkmf'
2
+
3
+ dir_config("mpfr")
4
+ dir_config("gmp")
5
+ if have_header('mpfr.h') && have_library('mpfr') && have_header('gmp.h') && have_library('gmp')
6
+ create_makefile("mpfr/matrix")
7
+ end
@@ -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
+