ruby-mpfi 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +62 -0
  3. data/PostInstall.txt +7 -0
  4. data/README.rdoc +48 -0
  5. data/Rakefile +26 -0
  6. data/ext/mpfi/extconf.rb +10 -0
  7. data/ext/mpfi/func_mpfi_extention.c +52 -0
  8. data/ext/mpfi/func_mpfi_extention.h +2 -0
  9. data/ext/mpfi/make_c_source.rb +115 -0
  10. data/ext/mpfi/ruby_mpfi.c +1452 -0
  11. data/ext/mpfi/ruby_mpfi.h +39 -0
  12. data/ext/mpfi/ruby_mpfr.h +38 -0
  13. data/ext/mpfi/yasnippet_mpfi.el +44 -0
  14. data/ext/mpfi_complex/mpfi/extconf.rb +10 -0
  15. data/ext/mpfi_complex/mpfi/func_mpfi_extention.h +2 -0
  16. data/ext/mpfi_complex/mpfi/func_ruby_mpfi_complex.c +130 -0
  17. data/ext/mpfi_complex/mpfi/func_ruby_mpfi_complex.h +35 -0
  18. data/ext/mpfi_complex/mpfi/ruby_mpfi.h +39 -0
  19. data/ext/mpfi_complex/mpfi/ruby_mpfi_complex.c +217 -0
  20. data/ext/mpfi_complex/mpfi/ruby_mpfi_complex.h +15 -0
  21. data/ext/mpfi_complex/mpfi/ruby_mpfr.h +38 -0
  22. data/ext/mpfi_matrix/mpfi/extconf.rb +9 -0
  23. data/ext/mpfi_matrix/mpfi/func_mpfi_extention.h +2 -0
  24. data/ext/mpfi_matrix/mpfi/func_mpfi_matrix.c +795 -0
  25. data/ext/mpfi_matrix/mpfi/func_mpfi_matrix.h +103 -0
  26. data/ext/mpfi_matrix/mpfi/func_mpfr_matrix.h +72 -0
  27. data/ext/mpfi_matrix/mpfi/func_ruby_mpfi_complex.h +35 -0
  28. data/ext/mpfi_matrix/mpfi/ruby_mpfi.h +39 -0
  29. data/ext/mpfi_matrix/mpfi/ruby_mpfi_complex.h +15 -0
  30. data/ext/mpfi_matrix/mpfi/ruby_mpfi_matrix.c +1200 -0
  31. data/ext/mpfi_matrix/mpfi/ruby_mpfi_matrix.h +13 -0
  32. data/ext/mpfi_matrix/mpfi/ruby_mpfr.h +38 -0
  33. data/ext/mpfi_matrix/mpfi/ruby_mpfr_matrix.h +13 -0
  34. data/lib/mpfi/matrix.rb +188 -0
  35. data/lib/mpfi/version.rb +3 -0
  36. data/ruby-mpfi.gemspec +35 -0
  37. data/script/console +10 -0
  38. data/script/destroy +14 -0
  39. data/script/generate +14 -0
  40. data/spec/mpfi/generate_number_module.rb +48 -0
  41. data/spec/mpfi/mpfi_alloc_spec.rb +55 -0
  42. data/spec/mpfi/mpfi_diam_arithmetic_spec.rb +25 -0
  43. data/spec/mpfi/mpfi_interval_arithmetic_spec.rb +105 -0
  44. data/spec/mpfi/mpfi_interval_functions_spec.rb +95 -0
  45. data/spec/mpfi/mpfi_math_functions_spec.rb +16 -0
  46. data/spec/mpfi/mpfi_set_operation_spec.rb +102 -0
  47. data/spec/mpfi/ruby-mpfi_spec.rb +11 -0
  48. data/spec/mpfi/spec_helper.rb +10 -0
  49. data/spec/mpfi_complex/spec_helper.rb +10 -0
  50. data/spec/mpfi_matrix/generate_matrix_arguments.rb +65 -0
  51. data/spec/mpfi_matrix/mpfi_matrix_alloc_spec.rb +134 -0
  52. data/spec/mpfi_matrix/mpfi_matrix_arithmetic_spec.rb +156 -0
  53. data/spec/mpfi_matrix/mpfi_matrix_interval_func_spec.rb +30 -0
  54. data/spec/mpfi_matrix/mpfi_matrix_set_element_spec.rb +55 -0
  55. data/spec/mpfi_matrix/mpfi_matrix_set_operation_spec.rb +71 -0
  56. data/spec/mpfi_matrix/mpfi_matrix_string_spec.rb +32 -0
  57. data/spec/mpfi_matrix/mpfi_matrix_subdivision_spec.rb +14 -0
  58. data/spec/mpfi_matrix/mpfi_square_matrix_spec.rb +37 -0
  59. data/spec/mpfi_matrix/mpfi_vector_spec.rb +15 -0
  60. data/spec/mpfi_matrix/spec_helper.rb +19 -0
  61. data/spec/spec.opts +1 -0
  62. data/tasks/extconf.rake +36 -0
  63. metadata +132 -0
@@ -0,0 +1,795 @@
1
+ #include "ruby_mpfi_matrix.h"
2
+
3
+ void mpfi_matrix_init(MPFIMatrix *mat, int row, int column){
4
+ mat->row = row;
5
+ mat->column = column;
6
+ mat->size = row * column;
7
+ /* mat->data = (MPFI *)malloc(sizeof(MPFI) * mat->size); */
8
+ mat->data = ALLOC_N(MPFI, mat->size);
9
+ int i;
10
+ for(i = 0; i < mat->size; i++){
11
+ mpfi_init(mat->data + i);
12
+ }
13
+ }
14
+
15
+ void mpfi_matrix_set_zeros(MPFIMatrix *mat){
16
+ int i;
17
+ for(i = 0; i < mat->size; i++){
18
+ mpfi_set_si(mat->data + i, 0);
19
+ }
20
+ }
21
+
22
+ void mpfi_matrix_clear(MPFIMatrix *mat){
23
+ int i;
24
+ for(i = 0; i < mat->size; i++){
25
+ mpfi_clear(mat->data + i);
26
+ }
27
+ free(mat->data);
28
+ }
29
+
30
+ void mpfi_matrix_set_element(MPFIMatrix *mat, int row, int col, MPFI *a){
31
+ mpfi_set(mpfi_matrix_get_element(mat, row, col), a);
32
+ }
33
+
34
+ void mpfi_matrix_set(MPFIMatrix *new, MPFIMatrix *x){
35
+ int i;
36
+ for(i = 0; i < x->size; i++){
37
+ mpfi_set(new->data + i, x->data + i);
38
+ }
39
+ }
40
+
41
+ void mpfi_matrix_swap(MPFIMatrix *x, MPFIMatrix *y){
42
+ int i;
43
+ for (i = 0; i < x->size; i++) {
44
+ mpfi_swap(mpfi_matrix_get_ptr(x, i), mpfi_matrix_get_ptr(y, i));
45
+ }
46
+ }
47
+
48
+ void mpfi_matrix_row(MPFIMatrix *new, MPFIMatrix *x, int row){
49
+ int i;
50
+ for (i = 0; i < x->column; i++) {
51
+ mpfi_set(new->data + i, mpfi_matrix_get_element(x, row, i));
52
+ }
53
+ }
54
+
55
+ void mpfi_matrix_column(MPFIMatrix *new, MPFIMatrix *x, int column){
56
+ int i;
57
+ for (i = 0; i < x->row; i++) {
58
+ mpfi_set(new->data + i, mpfi_matrix_get_element(x, i, column));
59
+ }
60
+ }
61
+
62
+ void mpfi_matrix_transpose(MPFIMatrix *new, MPFIMatrix *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
+ mpfi_set(new->data + j + i * new->row, x->data + i + index);
68
+ }
69
+ }
70
+ }
71
+
72
+ void mpfi_matrix_neg(MPFIMatrix *new, MPFIMatrix *x){
73
+ int i;
74
+ for(i = 0; i < x->size; i++){
75
+ mpfi_neg(new->data + i, x->data + i);
76
+ }
77
+ }
78
+
79
+ /* Return 0 if *x and *y has the same elements. Otherwise return 1. */
80
+ int mpfi_matrix_equal_p(MPFIMatrix *x, MPFIMatrix *y){
81
+ int i, ret = 0;
82
+ if (x->column == y->column && x->row == y->row) {
83
+ for (i = 0; i < x->size; i++) {
84
+ if (mpfr_equal_p(r_mpfi_left_ptr(x->data + i), r_mpfi_left_ptr(y->data + i)) == 0 ||
85
+ mpfr_equal_p(r_mpfi_right_ptr(x->data + i), r_mpfi_right_ptr(y->data + i)) == 0) {
86
+ ret = 1;
87
+ break;
88
+ }
89
+ }
90
+ }else{
91
+ ret = 1;
92
+ }
93
+ return ret;
94
+ }
95
+
96
+ void mpfi_matrix_add(MPFIMatrix *new, MPFIMatrix *x, MPFIMatrix *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
+ mpfi_add(new->data + i + index, x->data + i + index, y->data + i + index);
102
+ }
103
+ }
104
+ }
105
+
106
+ void mpfi_matrix_add_fr(MPFIMatrix *new, MPFIMatrix *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
+ mpfi_add_fr(new->data + i + index, x->data + i + index, y->data + i + index);
112
+ }
113
+ }
114
+ }
115
+
116
+ void mpfi_matrix_sub(MPFIMatrix *new, MPFIMatrix *x, MPFIMatrix *y){
117
+ int i, j, index;
118
+ for(j = 0; j < x->column; j++){
119
+ index = j * x->row;
120
+ for(i = 0; i < x->row; i++){
121
+ mpfi_sub(new->data + i + index, x->data + i + index, y->data + i + index);
122
+ }
123
+ }
124
+ }
125
+
126
+ void mpfi_matrix_sub_fr(MPFIMatrix *new, MPFIMatrix *x, MPFRMatrix *y){
127
+ int i, j, index;
128
+ for(j = 0; j < x->column; j++){
129
+ index = j * x->row;
130
+ for(i = 0; i < x->row; i++){
131
+ mpfi_sub_fr(new->data + i + index, x->data + i + index, y->data + i + index);
132
+ }
133
+ }
134
+ }
135
+
136
+ /* x and new must be different pointer from each other. */
137
+ void mpfi_matrix_mul(MPFIMatrix *new, MPFIMatrix *x, MPFIMatrix *y){
138
+ int i, j, k, index, index_y;
139
+ MPFI *tmp;
140
+ r_mpfi_temp_alloc_init(tmp);
141
+ for(i = 0; i < new->size; i++){
142
+ mpfi_set_si(new->data + i, 0);
143
+ }
144
+ for(j = 0; j < y->column; j++){
145
+ for(i = 0; i < x->row; i++){
146
+ index = i + j * new->row;
147
+ index_y = j * y->row;
148
+ for(k = 0; k < x->column; k++){
149
+ mpfi_mul(tmp, x->data + i + k * x->row, y->data + k + index_y);
150
+ mpfi_add(new->data + index, new->data + index, tmp);
151
+ }
152
+ }
153
+ }
154
+ r_mpfi_temp_free(tmp);
155
+ }
156
+
157
+ /* x and new must be different pointer from each other. */
158
+ void mpfi_matrix_mul_fr(MPFIMatrix *new, MPFIMatrix *x, MPFRMatrix *y){
159
+ int i, j, k, index, index_y;
160
+ MPFI *tmp;
161
+ r_mpfi_temp_alloc_init(tmp);
162
+ for(i = 0; i < new->size; i++){
163
+ mpfi_set_si(new->data + i, 0);
164
+ }
165
+ for(j = 0; j < y->column; j++){
166
+ for(i = 0; i < x->row; i++){
167
+ index = i + j * new->row;
168
+ index_y = j * y->row;
169
+ for(k = 0; k < x->column; k++){
170
+ mpfi_mul_fr(tmp, x->data + i + k * x->row, y->data + k + index_y);
171
+ mpfi_add(new->data + index, new->data + index, tmp);
172
+ }
173
+ }
174
+ }
175
+ r_mpfi_temp_free(tmp);
176
+ }
177
+
178
+ void mpfi_matrix_mul_scalar(MPFIMatrix *new, MPFIMatrix *x, MPFI *scalar){
179
+ int i;
180
+ for(i = 0; i < x->size; i++){
181
+ mpfi_mul(new->data + i, x->data + i, scalar);
182
+ }
183
+ }
184
+
185
+ void mpfi_matrix_div_scalar(MPFIMatrix *new, MPFIMatrix *x, MPFI *scalar){
186
+ int i;
187
+ for(i = 0; i < x->size; i++){
188
+ mpfi_div(new->data + i, x->data + i, scalar);
189
+ }
190
+ }
191
+
192
+ /* Return 0 if *x includes *y. Otherwise return 1. */
193
+ int mpfi_matrix_include_p(MPFIMatrix *x, MPFIMatrix *y){
194
+ int i, ret = 0;
195
+ if (x->column == y->column && x->row == y->row) {
196
+ for (i = 0; i < x->size; i++) {
197
+ if (mpfi_is_inside(y->data + i, x->data + i) <= 0) {
198
+ ret = 1;
199
+ break;
200
+ }
201
+ }
202
+ }else{
203
+ ret = 1;
204
+ }
205
+ return ret;
206
+ }
207
+
208
+ /* Return 0 if *x includes *y. Otherwise return 1. */
209
+ int mpfi_matrix_include_fr_p(MPFIMatrix *x, MPFRMatrix *y){
210
+ int i, ret = 0;
211
+ if (x->column == y->column && x->row == y->row) {
212
+ for (i = 0; i < x->size; i++) {
213
+ if (mpfi_is_inside_fr(y->data + i, x->data + i) <= 0) {
214
+ ret = 1;
215
+ break;
216
+ }
217
+ }
218
+ }else{
219
+ ret = 1;
220
+ }
221
+ return ret;
222
+ }
223
+
224
+ /* Return 0 if *x includes *y. Otherwise return 1. */
225
+ int mpfi_matrix_strictly_include_p(MPFIMatrix *x, MPFIMatrix *y){
226
+ int i, ret = 0;
227
+ if (x->column == y->column && x->row == y->row) {
228
+ for (i = 0; i < x->size; i++) {
229
+ if (mpfi_is_strictly_inside(y->data + i, x->data + i) <= 0) {
230
+ ret = 1;
231
+ break;
232
+ }
233
+ }
234
+ }else{
235
+ ret = 1;
236
+ }
237
+ return ret;
238
+ }
239
+
240
+ /* Return 0 if *x is bonded. Otherwise return 1. */
241
+ int mpfi_matrix_bounded_p(MPFIMatrix *x){
242
+ int ret = 0, i;
243
+ for (i = 0; i < x->size; i++) {
244
+ if (mpfi_bounded_p(x->data + i) == 0) {
245
+ ret = 1;
246
+ break;
247
+ }
248
+ }
249
+ return ret;
250
+ }
251
+
252
+ void mpfi_matrix_mid(MPFRMatrix *ret, MPFIMatrix *x){
253
+ int i;
254
+ for(i = 0; i < x->size; i++){
255
+ mpfi_mid(ret->data + i, x->data + i);
256
+ }
257
+ }
258
+
259
+ void mpfi_matrix_mid_interval(MPFIMatrix *ret, MPFIMatrix *x){
260
+ int i;
261
+ for(i = 0; i < x->size; i++){
262
+ mpfi_mid_interval(ret->data + i, x->data + i);
263
+ }
264
+ }
265
+
266
+ void mpfi_matrix_from_mpfr_matrix(MPFIMatrix *ret, MPFRMatrix *x){
267
+ int i;
268
+ for(i = 0; i < x->size; i++){
269
+ mpfi_set_fr(ret->data + i, x->data + i);
270
+ }
271
+ }
272
+
273
+ /* This function returns 0 if the intersection of two boxes exists. */
274
+ /* Otherwise, it returns nonzero. */
275
+ int mpfi_matrix_intersect(MPFIMatrix *z, MPFIMatrix *x, MPFIMatrix *y){
276
+ int ret = 0;
277
+ int i;
278
+ if (x->column == y->column && x->row == y->row) {
279
+ for(i = 0; i < x->size; i++){
280
+ mpfi_intersect(z->data + i, x->data + i, y->data + i);
281
+ if(ret == 0 && mpfi_is_empty(z->data + i)){
282
+ ret = 1;
283
+ }
284
+ }
285
+ return ret;
286
+ }else{
287
+ return -1;
288
+ }
289
+ }
290
+
291
+ /* Return -1 if size of matrixies is not same. */
292
+ /* Otherwise, return 0 and set convex hull to MPFIMatrix *z. */
293
+ int mpfi_matrix_union(MPFIMatrix *z, MPFIMatrix *x, MPFIMatrix *y){
294
+ int ret = 0;
295
+ int i;
296
+ if (x->column == y->column && x->row == y->row) {
297
+ for(i = 0; i < x->size; i++){
298
+ mpfi_union(z->data + i, x->data + i, y->data + i);
299
+ }
300
+ return ret;
301
+ }else{
302
+ return -1;
303
+ }
304
+ }
305
+
306
+ void mpfi_matrix_inner_product(MPFI *pr, MPFIMatrix *x, MPFIMatrix *y){
307
+ MPFI *tmp;
308
+ r_mpfi_temp_alloc_init(tmp);
309
+ int i;
310
+ mpfi_set_si(pr, 0);
311
+ for(i = 0; i < x->size; i++){
312
+ mpfi_mul(tmp, x->data + i, y->data + i);
313
+ mpfi_add(pr, pr, tmp);
314
+ }
315
+ r_mpfi_temp_free(tmp);
316
+ }
317
+
318
+ void mpfi_matrix_vector_distance(MPFI *distance, MPFIMatrix *x, MPFIMatrix *y){
319
+ MPFI *tmp;
320
+ r_mpfi_temp_alloc_init(tmp);
321
+ int i;
322
+ mpfi_set_si(distance, 0);
323
+ for(i = 0; i < x->size; i++){
324
+ mpfi_sub(tmp, x->data + i, y->data + i);
325
+ mpfi_mul(tmp, tmp, tmp);
326
+ mpfi_add(distance, distance, tmp);
327
+ }
328
+ mpfi_sqrt(distance, distance);
329
+ r_mpfi_temp_free(tmp);
330
+ }
331
+
332
+ void mpfi_matrix_vector_distance_center_pts(MPFR *distance, MPFIMatrix *x, MPFIMatrix *y){
333
+ MPFRMatrix *tmp_x, *tmp_y;
334
+ r_mpfr_matrix_temp_alloc_init(tmp_x, x->row, x->column);
335
+ r_mpfr_matrix_temp_alloc_init(tmp_y, y->row, y->column);
336
+
337
+ mpfi_matrix_mid(tmp_x, x);
338
+ mpfi_matrix_mid(tmp_y, y);
339
+ mpfr_matrix_vector_distance(distance, tmp_x, tmp_y);
340
+
341
+ r_mpfr_matrix_temp_free(tmp_x);
342
+ r_mpfr_matrix_temp_free(tmp_y);
343
+ }
344
+
345
+ void mpfi_matrix_vector_norm(MPFI *norm, MPFIMatrix *x){
346
+ MPFI *tmp;
347
+ r_mpfi_temp_alloc_init(tmp);
348
+ int i;
349
+ mpfi_set_si(norm, 0);
350
+ for(i = 0; i < x->size; i++){
351
+ mpfi_mul(tmp, x->data + i, x->data + i);
352
+ mpfi_add(norm, norm, tmp);
353
+ }
354
+ mpfi_sqrt(norm, norm);
355
+ r_mpfi_temp_free(tmp);
356
+ }
357
+
358
+ void mpfi_matrix_max_norm(MPFI *norm, MPFIMatrix *x){
359
+ MPFI *tmp, *abs;
360
+ r_mpfi_temp_alloc_init(tmp);
361
+ r_mpfi_temp_alloc_init(abs);
362
+ int i;
363
+ mpfi_set_si(norm, 0);
364
+ for(i = 0; i < x->size; i++){
365
+ mpfi_abs(abs, x->data + i);
366
+ mpfi_intersect(tmp, abs, norm);
367
+ if(mpfi_is_empty(tmp) > 0){
368
+ if(mpfr_cmp(r_mpfi_right_ptr(abs), r_mpfi_left_ptr(norm)) > 0){
369
+ mpfi_set(norm, abs);
370
+ }
371
+ }else{
372
+ mpfi_union(norm, norm, abs);
373
+ }
374
+ }
375
+ r_mpfi_temp_free(tmp);
376
+ r_mpfi_temp_free(abs);
377
+ }
378
+
379
+ void mpfi_matrix_max_diam_abs(MPFR *diam, MPFIMatrix *x){
380
+ int i;
381
+ MPFR *tmp;
382
+ r_mpfr_temp_alloc_init(tmp);
383
+
384
+ mpfr_set_si(diam, 0, GMP_RNDN);
385
+ for (i = 0; i < x->size; i++) {
386
+ mpfi_diam_abs(tmp, x->data + i);
387
+ if(mpfr_cmp(tmp, diam) > 0){
388
+ mpfr_set(diam, tmp, GMP_RNDN);
389
+ }
390
+ }
391
+
392
+ r_mpfr_temp_free(tmp);
393
+ }
394
+
395
+ /* ------------------- vector --------------------- */
396
+
397
+ void mpfi_col_vector_init(MPFIMatrix *mat, int row){
398
+ mat->row = row;
399
+ mat->column = 1;
400
+ mat->size = row;
401
+ /* mat->data = (MPFI *)malloc(sizeof(MPF) * mat->size); */
402
+ mat->data = ALLOC_N(MPFI, mat->size);
403
+ int i;
404
+ for(i = 0; i < mat->size; i++){
405
+ mpfi_init(mat->data + i);
406
+ }
407
+ }
408
+
409
+ void mpfi_row_vector_init(MPFIMatrix *mat, int column){
410
+ mat->row = 1;
411
+ mat->column = column;
412
+ mat->size = column;
413
+ /* mat->data = (MPFI *)malloc(sizeof(MPF) * mat->size); */
414
+ mat->data = ALLOC_N(MPFI, mat->size);
415
+ int i;
416
+ for(i = 0; i < mat->size; i++){
417
+ mpfi_init(mat->data + i);
418
+ }
419
+ }
420
+
421
+ /* If length of MPFIMatrix *x is zero, return 1. Otherwise return 0. */
422
+ int mpfi_vector_normalize(MPFIMatrix *new, MPFIMatrix *x){
423
+ MPFRMatrix *fr_mat;
424
+ r_mpfr_matrix_temp_alloc_init(fr_mat, x->row, x->column);
425
+ mpfi_matrix_mid(fr_mat, x);
426
+ MPFR *norm;
427
+ r_mpfr_temp_alloc_init(norm);
428
+ mpfr_matrix_vector_norm(norm, fr_mat);
429
+ int i, j, index, ret = 0;
430
+ if(mpfr_cmp_ui(norm, 0) > 0){
431
+ for(j = 0; j < x->column; j++){
432
+ index = j * x->row;
433
+ for(i = 0; i < x->row; i++){
434
+ mpfi_div_fr(new->data + i + index, x->data + i + index, norm);
435
+ }
436
+ }
437
+ }else{
438
+ ret = 1;
439
+ }
440
+ r_mpfr_matrix_temp_free(fr_mat);
441
+ r_mpfr_temp_free(norm);
442
+ return ret;
443
+ }
444
+
445
+ void mpfi_vector_midpoint(MPFIMatrix *new, MPFIMatrix *x, MPFIMatrix *y){
446
+ int i;
447
+ for (i = 0; i < new->size; i++) {
448
+ mpfi_add(mpfi_matrix_get_ptr(new, i), mpfi_matrix_get_ptr(x, i), mpfi_matrix_get_ptr(y, i));
449
+ mpfi_div_ui(mpfi_matrix_get_ptr(new, i), mpfi_matrix_get_ptr(new, i), 2);
450
+ }
451
+ }
452
+
453
+ /* If length of MPFIMatrix *x is zero, return 1. Otherwise return 0. */
454
+ int mpfi_vector_set_length(MPFIMatrix *new, MPFIMatrix *x, MPFR *length){
455
+ MPFI *norm_i;
456
+ MPFR *factor_r;
457
+ r_mpfi_temp_alloc_init(norm_i);
458
+ r_mpfr_temp_alloc_init(factor_r);
459
+ mpfi_matrix_vector_norm(norm_i, x);
460
+ mpfi_mid(factor_r, norm_i);
461
+ int i, j, index, ret = 0;
462
+ if(mpfr_cmp_ui(factor_r, 0) > 0){
463
+ mpfr_ui_div(factor_r, 1, factor_r, GMP_RNDN);
464
+ mpfr_mul(factor_r, factor_r, length, GMP_RNDN);
465
+ for(j = 0; j < x->column; j++){
466
+ index = j * x->row;
467
+ for(i = 0; i < x->row; i++){
468
+ mpfi_mul_fr(new->data + i + index, x->data + i + index, factor_r);
469
+ }
470
+ }
471
+ }else{
472
+ ret = 1;
473
+ }
474
+ r_mpfi_temp_free(norm_i);
475
+ r_mpfr_temp_free(factor_r);
476
+ return ret;
477
+ }
478
+
479
+ /* ---------------------- square matrix ------------------------- */
480
+
481
+ /* Return 0 if we execute even permutation for matrix, 1 if odd permutation or */
482
+ /* -1 if matrix is singular. */
483
+ int mpfi_square_matrix_lu_decomp (MPFIMatrix *ret, int *indx, MPFIMatrix *x){
484
+ int i, j, k, imax, ret_val = 0;
485
+ MPFI *big, *sum, *dum, *tmp1, *tmp2;
486
+ MPFIMatrix *vv, *tmp_ret;
487
+ r_mpfi_matrix_temp_alloc_init(tmp_ret, ret->row, ret->column);
488
+
489
+ mpfi_matrix_set(tmp_ret, x);
490
+
491
+ r_mpfi_temp_alloc_init(big);
492
+ r_mpfi_temp_alloc_init(sum);
493
+ r_mpfi_temp_alloc_init(dum);
494
+ r_mpfi_temp_alloc_init(tmp1);
495
+ r_mpfi_temp_alloc_init(tmp2);
496
+ r_mpfi_matrix_temp_alloc_init(vv, x->size, 1);
497
+ for (i = 0; i < tmp_ret->row; i++) {
498
+ mpfi_set_si(big, 0);
499
+ for (j = 0; j < tmp_ret->column; j++) {
500
+ mpfi_abs(tmp1, mpfi_matrix_get_element(x, i, j));
501
+
502
+ mpfi_intersect(tmp2, tmp1, big);
503
+ if(mpfi_is_empty(tmp2) > 0){
504
+ if(mpfr_cmp(r_mpfi_right_ptr(tmp1), r_mpfi_left_ptr(big)) > 0){
505
+ mpfi_set(big, tmp1);
506
+ }
507
+ }else{
508
+ mpfi_union(big, tmp1, big);
509
+ }
510
+ }
511
+ if (mpfi_has_zero(big) > 0) {
512
+ ret_val = -1;
513
+ break;
514
+ }
515
+ mpfi_ui_div(vv->data + i, 1, big);
516
+ }
517
+
518
+ if (ret_val >= 0) {
519
+ for (j = 0; j < tmp_ret->column; j++) {
520
+ for (i = 0; i < j; i++) {
521
+ mpfi_set(sum, mpfi_matrix_get_element(tmp_ret, i, j));
522
+ for (k = 0; k < i; k++) {
523
+ mpfi_mul(tmp1, mpfi_matrix_get_element(tmp_ret, i, k), mpfi_matrix_get_element(tmp_ret, k, j));
524
+ mpfi_sub(sum, sum, tmp1);
525
+ }
526
+ mpfi_set(mpfi_matrix_get_element(tmp_ret, i, j), sum);
527
+ }
528
+ mpfi_set_si(big, 0);
529
+ imax = j;
530
+ for (i = j; i < tmp_ret->row; i++) {
531
+ mpfi_set(sum, mpfi_matrix_get_element(tmp_ret, i, j));
532
+ for (k = 0; k < j; k++) {
533
+ mpfi_mul(tmp1, mpfi_matrix_get_element(tmp_ret, i, k), mpfi_matrix_get_element(tmp_ret, k, j));
534
+ mpfi_sub(sum, sum, tmp1);
535
+ }
536
+ mpfi_set(mpfi_matrix_get_element(tmp_ret, i, j), sum);
537
+ mpfi_abs(dum, sum);
538
+ mpfi_mul(dum, vv->data + i, dum);
539
+
540
+ mpfi_intersect(tmp2, dum, big);
541
+ if(mpfi_is_empty(tmp2) > 0){
542
+ if(mpfr_cmp(r_mpfi_right_ptr(dum), r_mpfi_left_ptr(big)) > 0){
543
+ mpfi_set(big, dum);
544
+ imax = i;
545
+ }
546
+ }else{
547
+ mpfi_union(big, dum, big);
548
+ imax = i;
549
+ }
550
+ }
551
+ if (j != imax) {
552
+ for (k = 0; k < tmp_ret->column; k++) {
553
+ mpfi_set(dum, mpfi_matrix_get_element(tmp_ret, imax, k));
554
+ mpfi_set(mpfi_matrix_get_element(tmp_ret, imax, k), mpfi_matrix_get_element(tmp_ret, j, k));
555
+ mpfi_set(mpfi_matrix_get_element(tmp_ret, j, k), dum);
556
+ }
557
+ ret_val = (ret_val + 1) % 2;
558
+ mpfi_set(vv->data + imax, vv->data + j);
559
+ }
560
+ indx[j] = imax;
561
+ if (mpfi_has_zero(mpfi_matrix_get_element(tmp_ret, j, j)) > 0) {
562
+ ret_val = -1;
563
+ break;
564
+ }
565
+ if (j < tmp_ret->row - 1) {
566
+ mpfi_ui_div(dum, 1, mpfi_matrix_get_element(tmp_ret, j, j));
567
+ for (i = j + 1; i < tmp_ret->row; i++) {
568
+ mpfi_mul(mpfi_matrix_get_element(tmp_ret, i, j), mpfi_matrix_get_element(tmp_ret, i, j), dum);
569
+ }
570
+ }
571
+ }
572
+ }
573
+ mpfi_matrix_set(ret, tmp_ret);
574
+
575
+ r_mpfi_matrix_temp_free(tmp_ret);
576
+ r_mpfi_temp_free(big);
577
+ r_mpfi_temp_free(sum);
578
+ r_mpfi_temp_free(dum);
579
+ r_mpfi_temp_free(tmp1);
580
+ r_mpfi_temp_free(tmp2);
581
+ r_mpfi_matrix_temp_free(vv);
582
+ return ret_val;
583
+ }
584
+
585
+ void mpfi_2d_square_matrix_determinant(MPFI *det, MPFIMatrix *x){
586
+ MPFI *tmp;
587
+ r_mpfi_temp_alloc_init(tmp);
588
+ mpfi_mul(det, x->data, x->data + 3);
589
+ mpfi_mul(tmp, x->data + 1, x->data + 2);
590
+ mpfi_sub(det, det, tmp);
591
+ r_mpfi_temp_free(tmp);
592
+ }
593
+
594
+ void mpfi_3d_square_matrix_determinant(MPFI *det, MPFIMatrix *x){
595
+ MPFI *tmp;
596
+ r_mpfi_temp_alloc_init(tmp);
597
+
598
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 0, 0), mpfi_matrix_get_element(x, 1, 1));
599
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 2, 2), tmp);
600
+ mpfi_set(det, tmp);
601
+
602
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 0, 1), mpfi_matrix_get_element(x, 1, 2));
603
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 2, 0), tmp);
604
+ mpfi_add(det, det, tmp);
605
+
606
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 0, 2), mpfi_matrix_get_element(x, 1, 0));
607
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 2, 1), tmp);
608
+ mpfi_add(det, det, tmp);
609
+
610
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 0, 0), mpfi_matrix_get_element(x, 1, 2));
611
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 2, 1), tmp);
612
+ mpfi_sub(det, det, tmp);
613
+
614
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 0, 1), mpfi_matrix_get_element(x, 1, 0));
615
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 2, 2), tmp);
616
+ mpfi_sub(det, det, tmp);
617
+
618
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 0, 2), mpfi_matrix_get_element(x, 1, 1));
619
+ mpfi_mul(tmp, mpfi_matrix_get_element(x, 2, 0), tmp);
620
+ mpfi_sub(det, det, tmp);
621
+
622
+ r_mpfi_temp_free(tmp);
623
+ }
624
+
625
+ void mpfi_square_matrix_determinant(MPFI *det, MPFIMatrix *x){
626
+ if (x->column == 2 && x->row == 2){
627
+ mpfi_2d_square_matrix_determinant(det, x);
628
+ }else if(x->column == 3 && x->row == 3){
629
+ mpfi_3d_square_matrix_determinant(det, x);
630
+ }else{
631
+ MPFIMatrix *ptr_lu;
632
+ r_mpfi_matrix_temp_alloc_init(ptr_lu, x->row, x->column);
633
+ int indx[x->row], i;
634
+ if((i = mpfi_square_matrix_lu_decomp (ptr_lu, indx, x)) >= 0){
635
+ if (i == 0) {
636
+ mpfi_set_si(det, 1);
637
+ } else if (i == 1) {
638
+ mpfi_set_si(det, -1);
639
+ }
640
+ for (i = 0; i < x->row; i++) {
641
+ mpfi_mul(det, det, mpfi_matrix_get_element(ptr_lu, i, i));
642
+ }
643
+ }else{
644
+ mpfi_set_ui(det, 0);
645
+ }
646
+ r_mpfi_matrix_temp_free(ptr_lu);
647
+ }
648
+
649
+ }
650
+
651
+ void mpfi_square_matrix_qr_decomp(MPFIMatrix *q, MPFIMatrix *r, MPFIMatrix *x){
652
+ MPFIMatrix *q_mat, *r_mat;
653
+ r_mpfi_matrix_temp_alloc_init(q_mat, q->row, q->column);
654
+ r_mpfi_matrix_temp_alloc_init(r_mat, r->row, r->column);
655
+
656
+ int size = x->row;
657
+ MPFIMatrix *ary;
658
+ r_mpfi_matrix_temp_alloc_init(ary, size, size);
659
+ mpfi_matrix_set(ary, x);
660
+ MPFI *tmp;
661
+ r_mpfi_temp_alloc_init(tmp);
662
+ int i, j, k, ind1, ind2, ind3;
663
+ for (i = 0; i < size; i++) {
664
+ ind1 = i * size;
665
+ ind2 = i + ind1;
666
+ mpfi_set_si(r_mat->data + ind2, 0);
667
+ for (j = 0; j < size; j++) {
668
+ mpfi_mul(tmp, ary->data + j + ind1, ary->data + j + ind1);
669
+ mpfi_add(r_mat->data + ind2, r_mat->data + ind2, tmp);
670
+ }
671
+ mpfi_sqrt(r_mat->data + ind2, r_mat->data + ind2);
672
+ for (j = 0; j < size; j++) {
673
+ mpfi_div(q_mat->data + j + ind1, ary->data + j + ind1, r_mat->data + ind2);
674
+ }
675
+ for (j = (i + 1); j < size; j++) {
676
+ ind2 = j * size;
677
+ ind3 = i + ind2;
678
+ mpfi_set_si(r_mat->data + ind3, 0);
679
+ for (k = 0; k < size; k++) {
680
+ mpfi_mul(tmp, q_mat->data + k + ind1, ary->data + k + ind2);
681
+ mpfi_add(r_mat->data + ind3, r_mat->data + ind3, tmp);
682
+ }
683
+ for (k = 0; k < size; k++) {
684
+ mpfi_mul(tmp, r_mat->data + ind3, q_mat->data + k + ind1);
685
+ mpfi_sub(ary->data + k + ind2, ary->data + k + ind2, tmp);
686
+ }
687
+ }
688
+ }
689
+ mpfi_matrix_set(q, q_mat);
690
+ mpfi_matrix_set(r, r_mat);
691
+
692
+ r_mpfi_matrix_temp_free(q_mat);
693
+ r_mpfi_matrix_temp_free(r_mat);
694
+ r_mpfi_matrix_temp_free(ary);
695
+ r_mpfi_temp_free(tmp);
696
+ }
697
+
698
+ /* If inverse matrix does not exist, return 1. Otherwise return 0. */
699
+ int mpfi_2d_square_matrix_inverse_matrix(MPFIMatrix *inv, MPFIMatrix *x){
700
+ MPFIMatrix *t_mat;
701
+ r_mpfi_matrix_temp_alloc_init(t_mat, inv->row, inv->column);
702
+ MPFI *t_fi;
703
+ r_mpfi_temp_alloc_init(t_fi);
704
+ mpfi_2d_square_matrix_determinant(t_fi, x);
705
+ if(mpfi_has_zero(t_fi) > 0){
706
+ return 1;
707
+ }else{
708
+ mpfi_ui_div(t_fi, 1, t_fi);
709
+ mpfi_mul(t_mat->data, x->data + 3, t_fi);
710
+ mpfi_mul(t_mat->data + 3, x->data, t_fi);
711
+ mpfi_neg(t_fi, t_fi);
712
+ mpfi_mul(t_mat->data + 1, x->data + 1, t_fi);
713
+ mpfi_mul(t_mat->data + 2, x->data + 2, t_fi);
714
+ }
715
+ mpfi_matrix_set(inv, t_mat);
716
+ r_mpfi_matrix_temp_free(t_mat);
717
+ r_mpfi_temp_free(t_fi);
718
+ return 0;
719
+ }
720
+
721
+ /* x = -(sqrt(a11**2-2*a00*a11+4*a01*a10+a00**2)-a11-a00)/2.0E+0 */
722
+ /* x = (sqrt(a11**2-2*a00*a11+4*a01*a10+a00**2)+a11+a00)/2.0E+0 */
723
+ /* If there are two real eigenvalues, return positive number. */
724
+ /* If only one eigenvalue exists, return 0. */
725
+ /* If there are two complex eigenvalues, this functionreturn negative number and */
726
+ /* first returned value is real part and second one is imaginary part. */
727
+ int mpfi_2d_square_matrix_eigenvalue(MPFI *val1, MPFI *val2, MPFIMatrix *x){
728
+ int ret;
729
+ MPFI *d;
730
+ r_mpfi_temp_alloc_init(d);
731
+
732
+ mpfi_sub(val1, x->data, x->data + 3);
733
+ mpfi_mul(val1, val1, val1);
734
+ mpfi_mul(d, x->data + 1, x->data + 2);
735
+ mpfi_mul_ui(d, d, 4);
736
+ mpfi_add(d, d, val1);
737
+
738
+ mpfi_add(val1, x->data, x->data + 3);
739
+ mpfi_div_ui(val1, val1, 2);
740
+ if(mpfr_cmp_si(r_mpfi_right_ptr(d), 0) > 0){
741
+ ret = 1;
742
+ mpfi_sqrt(d, d);
743
+ mpfi_div_ui(d, d, 2);
744
+ mpfi_sub(val2, val1, d);
745
+ mpfi_add(val1, val1, d);
746
+ }else if(mpfr_cmp_si(r_mpfi_right_ptr(d), 0) < 0){
747
+ ret = -1;
748
+ mpfi_neg(d, d);
749
+ mpfi_sqrt(d, d);
750
+ mpfi_div_ui(val2, d, 2);
751
+ }else{
752
+ ret = 0;
753
+ mpfi_set(val2, val1);
754
+ }
755
+
756
+ r_mpfi_temp_free(d);
757
+ return ret;
758
+ }
759
+
760
+ void mpfi_2d_square_matrix_real_eigenvector(MPFIMatrix *vec, MPFIMatrix *x, MPFI *eigenval){
761
+ MPFIMatrix *tmp;
762
+ r_mpfi_matrix_temp_alloc_init(tmp, 2, 1);
763
+ MPFI *tmp_fi;
764
+ r_mpfi_temp_alloc_init(tmp_fi);
765
+ mpfi_sub(tmp_fi, x->data + 3, eigenval);
766
+ if(mpfi_has_zero(x->data + 1) > 0 && mpfi_has_zero(tmp_fi) > 0){
767
+ mpfi_set(tmp->data, x->data + 2);
768
+ mpfi_sub(tmp->data + 1, eigenval, x->data);
769
+ }else{
770
+ mpfi_sub(tmp->data, eigenval, x->data + 3);
771
+ mpfi_set(tmp->data + 1, x->data + 1);
772
+ }
773
+ if(mpfi_vector_normalize(vec, tmp) == 1){
774
+ gmp_printf("Argument matrix\n%.Ff\n%.Ff\n%.Ff\n%.Ff\n", x->data, x->data + 1, x->data + 2, x->data + 3);
775
+ gmp_printf("Argument eigenvalue\n%.Ff\n", eigenval);
776
+ rb_raise(rb_eArgError, "Invalid eigenvalue or eigenvector.");
777
+ }
778
+ r_mpfi_matrix_temp_free(tmp);
779
+ r_mpfi_temp_free(tmp_fi);
780
+ }
781
+
782
+ void mpfi_square_matrix_identity(MPFIMatrix *id){
783
+ int i, j, index;
784
+ for (j = 0; j < id->column; j++) {
785
+ index = j * id->row;
786
+ for (i = 0; i < id->row; i++) {
787
+ if(i == j){
788
+ mpfi_set_si(id->data + i + index, 1);
789
+ }else{
790
+ mpfi_set_si(id->data + i + index, 0);
791
+ }
792
+ }
793
+ }
794
+
795
+ }