sollya 0.1.0

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/ext/sollya_rb.c ADDED
@@ -0,0 +1,3423 @@
1
+ /* Copyright (C) 2024 Théotime Bollengier <theotime.bollengier@ensta-bretagne.fr>
2
+ *
3
+ * This file is part of Sollya.rb. <https://gitlab.ensta-bretagne.fr/bollenth/sollya.rb>
4
+ *
5
+ * Sollya.rb is free software: you can redistribute it and/or modify it
6
+ * under the terms of the GNU General Public License as published
7
+ * by the Free Software Foundation, either version 3 of the License,
8
+ * or (at your option) any later version.
9
+ *
10
+ * Sollya.rb is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ * See the GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Sollya.rb. If not, see <https://www.gnu.org/licenses/>. 
17
+ */
18
+
19
+ #include "ruby/internal/intern/array.h"
20
+ #include <ruby.h>
21
+ #include <sollya.h>
22
+
23
+ extern void Init_mpfr(void);
24
+ extern void mpfrrb_bignum_to_mpz(VALUE, mpz_ptr);
25
+ extern void mpfrrb_rational_to_mpq(VALUE, mpq_ptr);
26
+ extern mpfr_ptr mpfrrb_rb2ref_ext(VALUE);
27
+ extern VALUE c_MPFR;
28
+ extern VALUE mpfrrb_alloc(VALUE klass);
29
+
30
+ static VALUE m_Sollya;
31
+ static VALUE c_SolObject;
32
+ static VALUE c_SolString;
33
+ static VALUE c_SolSpecial;
34
+ static VALUE c_SolRange;
35
+ static VALUE c_SolList;
36
+ static VALUE c_SolStructure;
37
+ static VALUE c_SolProcedure;
38
+ static VALUE c_SolExternalProcedure;
39
+ static VALUE c_SolExternalData;
40
+ static VALUE c_SolFunction;
41
+ static VALUE c_UnaryOp;
42
+ static VALUE c_BinaryOp;
43
+ static VALUE c_Abs;
44
+ static VALUE c_Acos;
45
+ static VALUE c_Acosh;
46
+ static VALUE c_Add;
47
+ static VALUE c_Asin;
48
+ static VALUE c_Asinh;
49
+ static VALUE c_Atan;
50
+ static VALUE c_Atanh;
51
+ static VALUE c_Ceil;
52
+ static VALUE c_Constant;
53
+ static VALUE c_Cos;
54
+ static VALUE c_Cosh;
55
+ static VALUE c_Div;
56
+ static VALUE c_Double;
57
+ static VALUE c_DoubleDouble;
58
+ static VALUE c_DoubleExtended;
59
+ static VALUE c_Erf;
60
+ static VALUE c_Erfc;
61
+ static VALUE c_Exp;
62
+ static VALUE c_Expm1;
63
+ static VALUE c_Floor;
64
+ static VALUE c_Freevariable;
65
+ static VALUE c_Halfprecision;
66
+ static VALUE c_Libraryconstant;
67
+ static VALUE c_Libraryfunction;
68
+ static VALUE c_Log;
69
+ static VALUE c_Log10;
70
+ static VALUE c_Log1p;
71
+ static VALUE c_Log2;
72
+ static VALUE c_Mul;
73
+ static VALUE c_Nearestint;
74
+ static VALUE c_Neg;
75
+ static VALUE c_Pi;
76
+ static VALUE c_Pow;
77
+ static VALUE c_Procedurefunction;
78
+ static VALUE c_Quad;
79
+ static VALUE c_Sin;
80
+ static VALUE c_Single;
81
+ static VALUE c_Sinh;
82
+ static VALUE c_Sqrt;
83
+ static VALUE c_Sub;
84
+ static VALUE c_Tan;
85
+ static VALUE c_Tanh;
86
+ static VALUE c_Tripledouble;
87
+
88
+ static VALUE sollyarb_cst_ON;
89
+ static VALUE sollyarb_cst_OFF;
90
+ static VALUE sollyarb_cst_DYADIC;
91
+ static VALUE sollyarb_cst_POWERS;
92
+ static VALUE sollyarb_cst_BINARY;
93
+ static VALUE sollyarb_cst_HEXADECIMAL;
94
+ static VALUE sollyarb_cst_FILE;
95
+ static VALUE sollyarb_cst_POSTSCRIPT;
96
+ static VALUE sollyarb_cst_POSTSCRIPTFILE;
97
+ static VALUE sollyarb_cst_PERTURB;
98
+ static VALUE sollyarb_cst_ROUND_DOWN;
99
+ static VALUE sollyarb_cst_ROUND_UP;
100
+ static VALUE sollyarb_cst_ROUND_TOWARDS_ZERO;
101
+ static VALUE sollyarb_cst_ROUND_TO_NEAREST;
102
+ static VALUE sollyarb_cst_HONORCOEFFPREC;
103
+ static VALUE sollyarb_cst_TRUE;
104
+ static VALUE sollyarb_cst_FALSE;
105
+ static VALUE sollyarb_cst_VOID;
106
+ static VALUE sollyarb_cst_DEFAULT;
107
+ static VALUE sollyarb_cst_DECIMAL;
108
+ static VALUE sollyarb_cst_ABSOLUTE;
109
+ static VALUE sollyarb_cst_RELATIVE;
110
+ static VALUE sollyarb_cst_FIXED;
111
+ static VALUE sollyarb_cst_FLOATING;
112
+ static VALUE sollyarb_cst_ERROR;
113
+ static VALUE sollyarb_cst_DOUBLE;
114
+ static VALUE sollyarb_cst_SINGLE;
115
+ static VALUE sollyarb_cst_QUAD;
116
+ static VALUE sollyarb_cst_HALFPRECISION;
117
+ static VALUE sollyarb_cst_DOUBLEEXTENDED;
118
+ static VALUE sollyarb_cst_DOUBLE_DOUBLE;
119
+ static VALUE sollyarb_cst_TRIPLE_DOUBLE;
120
+ static VALUE sollyarb_cst_PI;
121
+
122
+ static ID id_to_sollya;
123
+ static ID id_to_mpfr;
124
+ static ID id_to_s;
125
+ static ID id_end_elliptic;
126
+ static ID id_prec;
127
+
128
+ static ID id_on;
129
+ static ID id_off;
130
+ static ID id_dyadic;
131
+ static ID id_powers;
132
+ static ID id_binary;
133
+ static ID id_hexadecimal;
134
+ static ID id_file;
135
+ static ID id_postscript;
136
+ static ID id_postscriptfile;
137
+ static ID id_perturb;
138
+ static ID id_RD;
139
+ static ID id_round_down;
140
+ static ID id_RU;
141
+ static ID id_round_up;
142
+ static ID id_RZ;
143
+ static ID id_round_towards_zero;
144
+ static ID id_RN;
145
+ static ID id_round_to_nearest;
146
+ static ID id_honorcoeffprec;
147
+ static ID id_true;
148
+ static ID id_false;
149
+ static ID id_void;
150
+ static ID id_default;
151
+ static ID id_decimal;
152
+ static ID id_absolute;
153
+ static ID id_relative;
154
+ static ID id_fixed;
155
+ static ID id_floating;
156
+ static ID id_error;
157
+ static ID id_D;
158
+ static ID id_double;
159
+ static ID id_SG;
160
+ static ID id_single;
161
+ static ID id_QD;
162
+ static ID id_quad;
163
+ static ID id_HP;
164
+ static ID id_halfprecision;
165
+ static ID id_DE;
166
+ static ID id_doubleextended;
167
+ static ID id_DD;
168
+ static ID id_doubledouble;
169
+ static ID id_TD;
170
+ static ID id_tripledouble;
171
+
172
+
173
+ // static inline VALUE sollyarb_obj2sollya(VALUE obj) {
174
+ // return rb_funcallv(obj, id_to_sollya, 0, NULL);
175
+ // }
176
+
177
+
178
+ static void sollyarb_object_free(void *p)
179
+ {
180
+ sollya_obj_t obj = (sollya_obj_t)p;
181
+ if (obj) {
182
+ sollya_lib_clear_obj(obj);
183
+ }
184
+ }
185
+
186
+
187
+ const rb_data_type_t sollyarb_object_type = {
188
+ .wrap_struct_name = "Sollya::Object",
189
+ .function = {
190
+ .dmark = NULL,
191
+ .dfree = sollyarb_object_free,
192
+ .dsize = NULL,
193
+ },
194
+ .parent = NULL,
195
+ .data = NULL,
196
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
197
+ };
198
+
199
+
200
+ static VALUE sollyarb_object_alloc(VALUE klass)
201
+ {
202
+ sollya_obj_t obj = NULL;
203
+ return TypedData_Wrap_Struct(klass, &sollyarb_object_type, obj);
204
+ }
205
+
206
+
207
+ static inline VALUE sollyarb_ref2rb(sollya_obj_t obj, VALUE klass)
208
+ {
209
+ return TypedData_Wrap_Struct(klass, &sollyarb_object_type, obj);
210
+ }
211
+
212
+
213
+ static inline sollya_obj_t sollyarb_object_rb2ref(VALUE obj) {
214
+ sollya_obj_t p;
215
+ TypedData_Get_Struct(obj, __sollya_internal_type_object_base, &sollyarb_object_type, p);
216
+ return p;
217
+ }
218
+
219
+
220
+ static VALUE sollyarb_object_print(VALUE self)
221
+ {
222
+ sollya_obj_t sol = sollyarb_object_rb2ref(self);
223
+ sollya_lib_autoprint(sol, NULL);
224
+ return Qnil;
225
+ }
226
+
227
+
228
+ static VALUE sollyarb_object_to_s(VALUE self)
229
+ {
230
+ char buf[64];
231
+ sollya_obj_t sol = sollyarb_object_rb2ref(self);
232
+ int s = sollya_lib_snprintf(buf, sizeof(buf), "%b", sol);
233
+ if (s < (int)sizeof(buf)) {
234
+ return rb_str_new(buf, s);
235
+ }
236
+ char *strp = malloc(s+1);
237
+ if (!strp) return Qnil;
238
+ s = sollya_lib_snprintf(strp, s+1, "%b", sol);
239
+ VALUE rbstr = rb_str_new(strp, s);
240
+ free(strp);
241
+ return rbstr;
242
+ }
243
+
244
+
245
+ static VALUE sollyarb_object_to_sollya(VALUE self)
246
+ {
247
+ return self;
248
+ }
249
+
250
+
251
+ static VALUE sollyarb_float_to_sollya(VALUE self)
252
+ {
253
+ return sollyarb_ref2rb(sollya_lib_constant_from_double(NUM2DBL(self)), c_SolFunction);
254
+ }
255
+
256
+
257
+ static VALUE sollyarb_integer_to_sollya(VALUE self)
258
+ {
259
+ if (RB_FIXNUM_P(self)) {
260
+ return sollyarb_ref2rb(sollya_lib_constant_from_int64(NUM2LL(self)), c_SolFunction);
261
+ }
262
+ mpz_t mpz;
263
+ mpz_init(mpz);
264
+ mpfrrb_bignum_to_mpz(self, mpz);
265
+ VALUE r = sollyarb_ref2rb(sollya_lib_constant_from_mpz(mpz), c_SolFunction);
266
+ mpz_clear(mpz);
267
+ return r;
268
+ }
269
+
270
+
271
+ static VALUE sollyarb_rational_to_sollya(VALUE self)
272
+ {
273
+ mpq_t mpq;
274
+ mpq_init(mpq);
275
+ mpfrrb_rational_to_mpq(self, mpq);
276
+ VALUE r = sollyarb_ref2rb(sollya_lib_constant_from_mpq(mpq), c_SolFunction);
277
+ mpq_clear(mpq);
278
+ return r;
279
+ }
280
+
281
+
282
+ static VALUE sollyarb_MPFR_to_sollya(VALUE self)
283
+ {
284
+ return sollyarb_ref2rb(sollya_lib_constant(mpfrrb_rb2ref_ext(self)), c_SolFunction);
285
+ }
286
+
287
+
288
+ static VALUE sollyarb_string_to_sollya(VALUE self)
289
+ {
290
+ char *str = rb_string_value_cstr(&self);
291
+ VALUE r = sollyarb_ref2rb(sollya_lib_string(str), c_SolString);
292
+ RB_GC_GUARD(self);
293
+ return r;
294
+ }
295
+
296
+
297
+ static VALUE sollyarb_true_to_sollya(VALUE self)
298
+ {
299
+ return sollyarb_cst_TRUE;
300
+ }
301
+
302
+
303
+ static VALUE sollyarb_false_to_sollya(VALUE self)
304
+ {
305
+ return sollyarb_cst_FALSE;
306
+ }
307
+
308
+
309
+ static VALUE sollyarb_symbol_to_sollya(VALUE self)
310
+ {
311
+ ID id = rb_sym2id(self);
312
+ if (id == id_on) {
313
+ return sollyarb_cst_ON;
314
+ } else if (id == id_off) {
315
+ return sollyarb_cst_OFF;
316
+ } else if (id == id_dyadic) {
317
+ return sollyarb_cst_DYADIC;
318
+ } else if (id == id_powers) {
319
+ return sollyarb_cst_POWERS;
320
+ } else if (id == id_binary) {
321
+ return sollyarb_cst_BINARY;
322
+ } else if (id == id_hexadecimal) {
323
+ return sollyarb_cst_HEXADECIMAL;
324
+ } else if (id == id_file) {
325
+ return sollyarb_cst_FILE;
326
+ } else if (id == id_postscript) {
327
+ return sollyarb_cst_POSTSCRIPT;
328
+ } else if (id == id_postscriptfile) {
329
+ return sollyarb_cst_POSTSCRIPTFILE;
330
+ } else if (id == id_perturb) {
331
+ return sollyarb_cst_PERTURB;
332
+ } else if (id == id_RD || id == id_round_down) {
333
+ return sollyarb_cst_ROUND_DOWN;
334
+ } else if (id == id_RU || id == id_round_up) {
335
+ return sollyarb_cst_ROUND_UP;
336
+ } else if (id == id_RZ || id == id_round_towards_zero) {
337
+ return sollyarb_cst_ROUND_TOWARDS_ZERO;
338
+ } else if (id == id_RN || id == id_round_to_nearest) {
339
+ return sollyarb_cst_ROUND_TO_NEAREST;
340
+ } else if (id == id_honorcoeffprec) {
341
+ return sollyarb_cst_HONORCOEFFPREC;
342
+ } else if (id == id_true) {
343
+ return sollyarb_cst_TRUE;
344
+ } else if (id == id_false) {
345
+ return sollyarb_cst_FALSE;
346
+ } else if (id == id_void) {
347
+ return sollyarb_cst_VOID;
348
+ } else if (id == id_default) {
349
+ return sollyarb_cst_DEFAULT;
350
+ } else if (id == id_decimal) {
351
+ return sollyarb_cst_DECIMAL;
352
+ } else if (id == id_absolute) {
353
+ return sollyarb_cst_ABSOLUTE;
354
+ } else if (id == id_relative) {
355
+ return sollyarb_cst_RELATIVE;
356
+ } else if (id == id_fixed) {
357
+ return sollyarb_cst_FIXED;
358
+ } else if (id == id_floating) {
359
+ return sollyarb_cst_FLOATING;
360
+ } else if (id == id_error) {
361
+ return sollyarb_cst_ERROR;
362
+ } else if (id == id_D || id == id_double) {
363
+ return sollyarb_cst_DOUBLE;
364
+ } else if (id == id_SG || id == id_single) {
365
+ return sollyarb_cst_SINGLE;
366
+ } else if (id == id_QD || id == id_quad) {
367
+ return sollyarb_cst_QUAD;
368
+ } else if (id == id_HP || id == id_halfprecision) {
369
+ return sollyarb_cst_HALFPRECISION;
370
+ } else if (id == id_DE || id == id_doubleextended) {
371
+ return sollyarb_cst_DOUBLEEXTENDED;
372
+ } else if (id == id_DD || id == id_doubledouble) {
373
+ return sollyarb_cst_DOUBLE_DOUBLE;
374
+ } else if (id == id_TD || id == id_tripledouble) {
375
+ return sollyarb_cst_TRIPLE_DOUBLE;
376
+ } else {
377
+ rb_raise(rb_eArgError, "cannot convert symbol %" PRIsVALUE " into a Sollya object", self);
378
+ }
379
+ }
380
+
381
+
382
+ static VALUE sollyarb_autowrap_object(sollya_obj_t obj)
383
+ {
384
+ VALUE r = Qnil;
385
+
386
+ if (sollya_lib_obj_is_function(obj)) {
387
+ sollya_base_function_t base_func;
388
+ if (!sollya_lib_get_head_function(&base_func, obj)) {
389
+ r = sollyarb_ref2rb(obj, c_SolFunction);
390
+ } else {
391
+ switch (base_func) {
392
+ case SOLLYA_BASE_FUNC_ABS: r = sollyarb_ref2rb(obj, c_Abs); break;
393
+ case SOLLYA_BASE_FUNC_ACOS: r = sollyarb_ref2rb(obj, c_Acos); break;
394
+ case SOLLYA_BASE_FUNC_ACOSH: r = sollyarb_ref2rb(obj, c_Acosh); break;
395
+ case SOLLYA_BASE_FUNC_ADD: r = sollyarb_ref2rb(obj, c_Add); break;
396
+ case SOLLYA_BASE_FUNC_ASIN: r = sollyarb_ref2rb(obj, c_Asin); break;
397
+ case SOLLYA_BASE_FUNC_ASINH: r = sollyarb_ref2rb(obj, c_Asinh); break;
398
+ case SOLLYA_BASE_FUNC_ATAN: r = sollyarb_ref2rb(obj, c_Atan); break;
399
+ case SOLLYA_BASE_FUNC_ATANH: r = sollyarb_ref2rb(obj, c_Atanh); break;
400
+ case SOLLYA_BASE_FUNC_CEIL: r = sollyarb_ref2rb(obj, c_Ceil); break;
401
+ case SOLLYA_BASE_FUNC_CONSTANT: r = sollyarb_ref2rb(obj, c_Constant); break;
402
+ case SOLLYA_BASE_FUNC_COS: r = sollyarb_ref2rb(obj, c_Cos); break;
403
+ case SOLLYA_BASE_FUNC_COSH: r = sollyarb_ref2rb(obj, c_Cosh); break;
404
+ case SOLLYA_BASE_FUNC_DIV: r = sollyarb_ref2rb(obj, c_Div); break;
405
+ case SOLLYA_BASE_FUNC_DOUBLE: r = sollyarb_ref2rb(obj, c_Double); break;
406
+ case SOLLYA_BASE_FUNC_DOUBLEDOUBLE: r = sollyarb_ref2rb(obj, c_DoubleDouble); break;
407
+ case SOLLYA_BASE_FUNC_DOUBLEEXTENDED: r = sollyarb_ref2rb(obj, c_DoubleExtended); break;
408
+ case SOLLYA_BASE_FUNC_ERF: r = sollyarb_ref2rb(obj, c_Erf); break;
409
+ case SOLLYA_BASE_FUNC_ERFC: r = sollyarb_ref2rb(obj, c_Erfc); break;
410
+ case SOLLYA_BASE_FUNC_EXP: r = sollyarb_ref2rb(obj, c_Exp); break;
411
+ case SOLLYA_BASE_FUNC_EXP_M1: r = sollyarb_ref2rb(obj, c_Expm1); break;
412
+ case SOLLYA_BASE_FUNC_FLOOR: r = sollyarb_ref2rb(obj, c_Floor); break;
413
+ case SOLLYA_BASE_FUNC_FREE_VARIABLE: r = sollyarb_ref2rb(obj, c_Freevariable); break;
414
+ case SOLLYA_BASE_FUNC_HALFPRECISION: r = sollyarb_ref2rb(obj, c_Halfprecision); break;
415
+ case SOLLYA_BASE_FUNC_LIBRARYCONSTANT: r = sollyarb_ref2rb(obj, c_Libraryconstant); break;
416
+ case SOLLYA_BASE_FUNC_LIBRARYFUNCTION: r = sollyarb_ref2rb(obj, c_Libraryfunction); break;
417
+ case SOLLYA_BASE_FUNC_LOG: r = sollyarb_ref2rb(obj, c_Log); break;
418
+ case SOLLYA_BASE_FUNC_LOG_10: r = sollyarb_ref2rb(obj, c_Log10); break;
419
+ case SOLLYA_BASE_FUNC_LOG_1P: r = sollyarb_ref2rb(obj, c_Log1p); break;
420
+ case SOLLYA_BASE_FUNC_LOG_2: r = sollyarb_ref2rb(obj, c_Log2); break;
421
+ case SOLLYA_BASE_FUNC_MUL: r = sollyarb_ref2rb(obj, c_Mul); break;
422
+ case SOLLYA_BASE_FUNC_NEARESTINT: r = sollyarb_ref2rb(obj, c_Nearestint); break;
423
+ case SOLLYA_BASE_FUNC_NEG: r = sollyarb_ref2rb(obj, c_Neg); break;
424
+ case SOLLYA_BASE_FUNC_PI: r = sollyarb_ref2rb(obj, c_Pi); break;
425
+ case SOLLYA_BASE_FUNC_POW: r = sollyarb_ref2rb(obj, c_Pow); break;
426
+ case SOLLYA_BASE_FUNC_PROCEDUREFUNCTION: r = sollyarb_ref2rb(obj, c_Procedurefunction); break;
427
+ case SOLLYA_BASE_FUNC_QUAD: r = sollyarb_ref2rb(obj, c_Quad); break;
428
+ case SOLLYA_BASE_FUNC_SIN: r = sollyarb_ref2rb(obj, c_Sin); break;
429
+ case SOLLYA_BASE_FUNC_SINGLE: r = sollyarb_ref2rb(obj, c_Single); break;
430
+ case SOLLYA_BASE_FUNC_SINH: r = sollyarb_ref2rb(obj, c_Sinh); break;
431
+ case SOLLYA_BASE_FUNC_SQRT: r = sollyarb_ref2rb(obj, c_Sqrt); break;
432
+ case SOLLYA_BASE_FUNC_SUB: r = sollyarb_ref2rb(obj, c_Sub); break;
433
+ case SOLLYA_BASE_FUNC_TAN: r = sollyarb_ref2rb(obj, c_Tan); break;
434
+ case SOLLYA_BASE_FUNC_TANH: r = sollyarb_ref2rb(obj, c_Tanh); break;
435
+ case SOLLYA_BASE_FUNC_TRIPLEDOUBLE: r = sollyarb_ref2rb(obj, c_Tripledouble); break;
436
+ default: r = sollyarb_ref2rb(obj, c_SolFunction);
437
+ }
438
+ }
439
+ } else if (sollya_lib_obj_is_list(obj)) {
440
+ r = sollyarb_ref2rb(obj, c_SolList);
441
+ } else if (sollya_lib_obj_is_end_elliptic_list(obj)) {
442
+ r = sollyarb_ref2rb(obj, c_SolList);
443
+ } else if (sollya_lib_obj_is_range(obj)) {
444
+ r = sollyarb_ref2rb(obj, c_SolRange);
445
+ } else if (sollya_lib_obj_is_string(obj)) {
446
+ r = sollyarb_ref2rb(obj, c_SolString);
447
+ } else if (sollya_lib_obj_is_error(obj)) {
448
+ r = sollyarb_cst_ERROR;
449
+ sollya_lib_clear_obj(obj);
450
+ } else if (sollya_lib_obj_is_structure(obj)) {
451
+ r = sollyarb_ref2rb(obj, c_SolStructure);
452
+ } else if (sollya_lib_obj_is_procedure(obj)) {
453
+ r = sollyarb_ref2rb(obj, c_SolProcedure);
454
+ } else if (sollya_lib_obj_is_externalprocedure(obj)) {
455
+ r = sollyarb_ref2rb(obj, c_SolExternalProcedure);
456
+ } else if (sollya_lib_obj_is_externaldata(obj)) {
457
+ r = sollyarb_ref2rb(obj, c_SolExternalData);
458
+ } else if (sollya_lib_is_on(obj)) {
459
+ r = sollyarb_cst_ON;
460
+ sollya_lib_clear_obj(obj);
461
+ } else if (sollya_lib_is_off(obj)) {
462
+ r = sollyarb_cst_OFF;
463
+ sollya_lib_clear_obj(obj);
464
+ } else if (sollya_lib_is_dyadic(obj)) {
465
+ r = sollyarb_cst_DYADIC;
466
+ sollya_lib_clear_obj(obj);
467
+ } else if (sollya_lib_is_powers(obj)) {
468
+ r = sollyarb_cst_POWERS;
469
+ sollya_lib_clear_obj(obj);
470
+ } else if (sollya_lib_is_binary(obj)) {
471
+ r = sollyarb_cst_BINARY;
472
+ sollya_lib_clear_obj(obj);
473
+ } else if (sollya_lib_is_hexadecimal(obj)) {
474
+ r = sollyarb_cst_HEXADECIMAL;
475
+ sollya_lib_clear_obj(obj);
476
+ } else if (sollya_lib_is_file(obj)) {
477
+ r = sollyarb_cst_FILE;
478
+ sollya_lib_clear_obj(obj);
479
+ } else if (sollya_lib_is_postscript(obj)) {
480
+ r = sollyarb_cst_POSTSCRIPT;
481
+ sollya_lib_clear_obj(obj);
482
+ } else if (sollya_lib_is_postscriptfile(obj)) {
483
+ r = sollyarb_cst_POSTSCRIPTFILE;
484
+ sollya_lib_clear_obj(obj);
485
+ } else if (sollya_lib_is_perturb(obj)) {
486
+ r = sollyarb_cst_PERTURB;
487
+ sollya_lib_clear_obj(obj);
488
+ } else if (sollya_lib_is_round_down(obj)) {
489
+ r = sollyarb_cst_ROUND_DOWN;
490
+ sollya_lib_clear_obj(obj);
491
+ } else if (sollya_lib_is_round_up(obj)) {
492
+ r = sollyarb_cst_ROUND_UP;
493
+ sollya_lib_clear_obj(obj);
494
+ } else if (sollya_lib_is_round_towards_zero(obj)) {
495
+ r = sollyarb_cst_ROUND_TOWARDS_ZERO;
496
+ sollya_lib_clear_obj(obj);
497
+ } else if (sollya_lib_is_round_to_nearest(obj)) {
498
+ r = sollyarb_cst_ROUND_TO_NEAREST;
499
+ sollya_lib_clear_obj(obj);
500
+ } else if (sollya_lib_is_honorcoeffprec(obj)) {
501
+ r = sollyarb_cst_HONORCOEFFPREC;
502
+ sollya_lib_clear_obj(obj);
503
+ } else if (sollya_lib_is_true(obj)) {
504
+ r = sollyarb_cst_TRUE;
505
+ sollya_lib_clear_obj(obj);
506
+ } else if (sollya_lib_is_false(obj)) {
507
+ r = sollyarb_cst_FALSE;
508
+ sollya_lib_clear_obj(obj);
509
+ } else if (sollya_lib_is_void(obj)) {
510
+ r = sollyarb_cst_VOID;
511
+ sollya_lib_clear_obj(obj);
512
+ } else if (sollya_lib_is_default(obj)) {
513
+ r = sollyarb_cst_DEFAULT;
514
+ sollya_lib_clear_obj(obj);
515
+ } else if (sollya_lib_is_decimal(obj)) {
516
+ r = sollyarb_cst_DECIMAL;
517
+ sollya_lib_clear_obj(obj);
518
+ } else if (sollya_lib_is_absolute(obj)) {
519
+ r = sollyarb_cst_ABSOLUTE;
520
+ sollya_lib_clear_obj(obj);
521
+ } else if (sollya_lib_is_relative(obj)) {
522
+ r = sollyarb_cst_RELATIVE;
523
+ sollya_lib_clear_obj(obj);
524
+ } else if (sollya_lib_is_fixed(obj)) {
525
+ r = sollyarb_cst_FIXED;
526
+ sollya_lib_clear_obj(obj);
527
+ } else if (sollya_lib_is_floating(obj)) {
528
+ r = sollyarb_cst_FLOATING;
529
+ sollya_lib_clear_obj(obj);
530
+ } else if (sollya_lib_is_double_obj(obj)) {
531
+ r = sollyarb_cst_DOUBLE;
532
+ sollya_lib_clear_obj(obj);
533
+ } else if (sollya_lib_is_single_obj(obj)) {
534
+ r = sollyarb_cst_SINGLE;
535
+ sollya_lib_clear_obj(obj);
536
+ } else if (sollya_lib_is_quad_obj(obj)) {
537
+ r = sollyarb_cst_QUAD;
538
+ sollya_lib_clear_obj(obj);
539
+ } else if (sollya_lib_is_halfprecision_obj(obj)) {
540
+ r = sollyarb_cst_HALFPRECISION;
541
+ sollya_lib_clear_obj(obj);
542
+ } else if (sollya_lib_is_doubleextended_obj(obj)) {
543
+ r = sollyarb_cst_DOUBLEEXTENDED;
544
+ sollya_lib_clear_obj(obj);
545
+ } else if (sollya_lib_is_double_double_obj(obj)) {
546
+ r = sollyarb_cst_DOUBLE_DOUBLE;
547
+ sollya_lib_clear_obj(obj);
548
+ } else if (sollya_lib_is_triple_double_obj(obj)) {
549
+ r = sollyarb_cst_TRIPLE_DOUBLE;
550
+ sollya_lib_clear_obj(obj);
551
+ } else if (sollya_lib_is_pi(obj)) {
552
+ r = sollyarb_cst_PI;
553
+ sollya_lib_clear_obj(obj);
554
+ } else {
555
+ r = sollyarb_ref2rb(obj, c_SolObject);
556
+ }
557
+ return r;
558
+ r = sollyarb_cst_ERROR;
559
+ }
560
+
561
+ static VALUE sollyarb_range_to_sollya(VALUE self)
562
+ {
563
+ VALUE beg = Qnil, end = Qnil;
564
+ int exclp;
565
+ rb_range_values(self, &beg, &end, &exclp);
566
+ #if 0
567
+ beg = rb_funcallv(beg, id_to_mpfr, 0, NULL);
568
+ end = rb_funcallv(end, id_to_mpfr, 0, NULL);
569
+ mpfr_ptr mpbeg = mpfrrb_rb2ref_ext(beg);
570
+ mpfr_ptr mpend = mpfrrb_rb2ref_ext(end);
571
+ return sollyarb_ref2rb(sollya_lib_range_from_bounds(mpbeg, mpend), c_SolRange);
572
+ #else
573
+ beg = rb_funcallv(beg, id_to_sollya, 0, NULL);
574
+ end = rb_funcallv(end, id_to_sollya, 0, NULL);
575
+ return sollyarb_ref2rb(sollya_lib_range(sollyarb_object_rb2ref(beg), sollyarb_object_rb2ref(end)), c_SolRange);
576
+ #endif
577
+ }
578
+
579
+
580
+ static VALUE sollyarb_array_to_sollya(VALUE self)
581
+ {
582
+ long i;
583
+ long l = rb_array_len(self);
584
+ sollya_obj_t *carr = malloc(l*sizeof(sollya_obj_t));
585
+ for (i = 0; i < l; i++) {
586
+ VALUE elem = rb_ary_entry(self, i);
587
+ elem = rb_funcallv(elem, id_to_sollya, 0, NULL);
588
+ carr[i] = sollyarb_object_rb2ref(elem);
589
+ }
590
+ sollya_obj_t r = sollya_lib_list(carr, l);
591
+ free(carr);
592
+ return sollyarb_ref2rb(r, c_SolList);
593
+ }
594
+
595
+
596
+ static VALUE sollyarb_object_inspect(VALUE self)
597
+ {
598
+ return rb_sprintf("#<%s %" PRIsVALUE ">", rb_obj_classname(self), rb_funcallv(self, id_to_s, 0, NULL));
599
+ }
600
+
601
+
602
+ #define SOLLYARB_ARGV(i) sollyarb_object_rb2ref(rb_funcallv(argv[i], id_to_sollya, 0, NULL))
603
+ #define SOLLYARB_TO_SOLLYA(arg) sollyarb_object_rb2ref(rb_funcallv(arg, id_to_sollya, 0, NULL))
604
+
605
+ #define SOLLYARB_FUNC_VA_1(func) \
606
+ (void)self; \
607
+ switch (argc) { \
608
+ case 1: func(SOLLYARB_ARGV(0), NULL); break; \
609
+ case 2: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), NULL); break; \
610
+ case 3: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), NULL); break; \
611
+ case 4: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), NULL); break; \
612
+ case 5: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), NULL); break; \
613
+ case 6: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), NULL); break; \
614
+ case 7: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), NULL); break; \
615
+ case 8: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), NULL); break; \
616
+ case 9: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), NULL); break; \
617
+ case 10: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), NULL); break; \
618
+ case 11: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), NULL); break; \
619
+ case 12: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), NULL); break; \
620
+ case 13: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), NULL); break; \
621
+ case 14: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), NULL); break; \
622
+ case 15: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), NULL); break; \
623
+ case 16: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), SOLLYARB_ARGV(15), NULL); break; \
624
+ default: rb_raise(rb_eArgError, "expecting 1 to 16 arguments, got %d", argc); \
625
+ } \
626
+ return Qnil
627
+
628
+ #define SOLLYARB_FUNC_VA_2(func) \
629
+ (void)self; \
630
+ switch (argc) { \
631
+ case 2: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), NULL); break; \
632
+ case 3: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), NULL); break; \
633
+ case 4: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), NULL); break; \
634
+ case 5: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), NULL); break; \
635
+ case 6: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), NULL); break; \
636
+ case 7: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), NULL); break; \
637
+ case 8: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), NULL); break; \
638
+ case 9: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), NULL); break; \
639
+ case 10: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), NULL); break; \
640
+ case 11: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), NULL); break; \
641
+ case 12: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), NULL); break; \
642
+ case 13: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), NULL); break; \
643
+ case 14: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), NULL); break; \
644
+ case 15: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), NULL); break; \
645
+ case 16: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), SOLLYARB_ARGV(15), NULL); break; \
646
+ default: rb_raise(rb_eArgError, "expecting 2 to 16 arguments, got %d", argc); \
647
+ } \
648
+ return Qnil
649
+
650
+ #define SOLLYARB_FUNC_VA_3(func) \
651
+ (void)self; \
652
+ switch (argc) { \
653
+ case 3: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), NULL); break; \
654
+ case 4: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), NULL); break; \
655
+ case 5: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), NULL); break; \
656
+ case 6: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), NULL); break; \
657
+ case 7: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), NULL); break; \
658
+ case 8: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), NULL); break; \
659
+ case 9: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), NULL); break; \
660
+ case 10: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), NULL); break; \
661
+ case 11: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), NULL); break; \
662
+ case 12: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), NULL); break; \
663
+ case 13: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), NULL); break; \
664
+ case 14: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), NULL); break; \
665
+ case 15: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), NULL); break; \
666
+ case 16: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), SOLLYARB_ARGV(15), NULL); break; \
667
+ default: rb_raise(rb_eArgError, "expecting 3 to 16 arguments, got %d", argc); \
668
+ } \
669
+ return Qnil
670
+
671
+ #define SOLLYARB_FUNC_VA_4(func) \
672
+ (void)self; \
673
+ switch (argc) { \
674
+ case 4: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), NULL); break; \
675
+ case 5: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), NULL); break; \
676
+ case 6: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), NULL); break; \
677
+ case 7: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), NULL); break; \
678
+ case 8: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), NULL); break; \
679
+ case 9: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), NULL); break; \
680
+ case 10: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), NULL); break; \
681
+ case 11: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), NULL); break; \
682
+ case 12: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), NULL); break; \
683
+ case 13: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), NULL); break; \
684
+ case 14: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), NULL); break; \
685
+ case 15: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), NULL); break; \
686
+ case 16: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), SOLLYARB_ARGV(15), NULL); break; \
687
+ default: rb_raise(rb_eArgError, "expecting 4 to 16 arguments, got %d", argc); \
688
+ } \
689
+ return Qnil
690
+
691
+ #define SOLLYARB_FUNC_VA_5(func) \
692
+ (void)self; \
693
+ switch (argc) { \
694
+ case 5: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), NULL); break; \
695
+ case 6: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), NULL); break; \
696
+ case 7: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), NULL); break; \
697
+ case 8: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), NULL); break; \
698
+ case 9: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), NULL); break; \
699
+ case 10: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), NULL); break; \
700
+ case 11: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), NULL); break; \
701
+ case 12: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), NULL); break; \
702
+ case 13: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), NULL); break; \
703
+ case 14: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), NULL); break; \
704
+ case 15: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), NULL); break; \
705
+ case 16: func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), SOLLYARB_ARGV(15), NULL); break; \
706
+ default: rb_raise(rb_eArgError, "expecting 5 to 16 arguments, got %d", argc); \
707
+ } \
708
+ return Qnil
709
+
710
+
711
+ #define SOLLYARB_PROC_VA_1(func) \
712
+ (void)self; \
713
+ sollya_obj_t r; \
714
+ switch (argc) { \
715
+ case 1: r = func(SOLLYARB_ARGV(0), NULL); break; \
716
+ case 2: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), NULL); break; \
717
+ case 3: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), NULL); break; \
718
+ case 4: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), NULL); break; \
719
+ case 5: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), NULL); break; \
720
+ case 6: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), NULL); break; \
721
+ case 7: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), NULL); break; \
722
+ case 8: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), NULL); break; \
723
+ case 9: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), NULL); break; \
724
+ case 10: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), NULL); break; \
725
+ case 11: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), NULL); break; \
726
+ case 12: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), NULL); break; \
727
+ case 13: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), NULL); break; \
728
+ case 14: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), NULL); break; \
729
+ case 15: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), NULL); break; \
730
+ case 16: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), SOLLYARB_ARGV(15), NULL); break; \
731
+ default: rb_raise(rb_eArgError, "expecting 1 to 16 arguments, got %d", argc); \
732
+ } \
733
+ return sollyarb_autowrap_object(r)
734
+
735
+ #define SOLLYARB_PROC_VA_2(func) \
736
+ (void)self; \
737
+ sollya_obj_t r; \
738
+ switch (argc) { \
739
+ case 2: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), NULL); break; \
740
+ case 3: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), NULL); break; \
741
+ case 4: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), NULL); break; \
742
+ case 5: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), NULL); break; \
743
+ case 6: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), NULL); break; \
744
+ case 7: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), NULL); break; \
745
+ case 8: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), NULL); break; \
746
+ case 9: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), NULL); break; \
747
+ case 10: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), NULL); break; \
748
+ case 11: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), NULL); break; \
749
+ case 12: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), NULL); break; \
750
+ case 13: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), NULL); break; \
751
+ case 14: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), NULL); break; \
752
+ case 15: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), NULL); break; \
753
+ case 16: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), SOLLYARB_ARGV(15), NULL); break; \
754
+ default: rb_raise(rb_eArgError, "expecting 2 to 16 arguments, got %d", argc); \
755
+ } \
756
+ return sollyarb_autowrap_object(r)
757
+
758
+ #define SOLLYARB_PROC_VA_3(func) \
759
+ (void)self; \
760
+ sollya_obj_t r; \
761
+ switch (argc) { \
762
+ case 3: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), NULL); break; \
763
+ case 4: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), NULL); break; \
764
+ case 5: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), NULL); break; \
765
+ case 6: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), NULL); break; \
766
+ case 7: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), NULL); break; \
767
+ case 8: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), NULL); break; \
768
+ case 9: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), NULL); break; \
769
+ case 10: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), NULL); break; \
770
+ case 11: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), NULL); break; \
771
+ case 12: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), NULL); break; \
772
+ case 13: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), NULL); break; \
773
+ case 14: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), NULL); break; \
774
+ case 15: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), NULL); break; \
775
+ case 16: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), SOLLYARB_ARGV(15), NULL); break; \
776
+ default: rb_raise(rb_eArgError, "expecting 3 to 16 arguments, got %d", argc); \
777
+ } \
778
+ return sollyarb_autowrap_object(r)
779
+
780
+ #define SOLLYARB_PROC_VA_4(func) \
781
+ (void)self; \
782
+ sollya_obj_t r; \
783
+ switch (argc) { \
784
+ case 4: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), NULL); break; \
785
+ case 5: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), NULL); break; \
786
+ case 6: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), NULL); break; \
787
+ case 7: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), NULL); break; \
788
+ case 8: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), NULL); break; \
789
+ case 9: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), NULL); break; \
790
+ case 10: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), NULL); break; \
791
+ case 11: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), NULL); break; \
792
+ case 12: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), NULL); break; \
793
+ case 13: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), NULL); break; \
794
+ case 14: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), NULL); break; \
795
+ case 15: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), NULL); break; \
796
+ case 16: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), SOLLYARB_ARGV(15), NULL); break; \
797
+ default: rb_raise(rb_eArgError, "expecting 4 to 16 arguments, got %d", argc); \
798
+ } \
799
+ return sollyarb_autowrap_object(r)
800
+
801
+ #define SOLLYARB_PROC_VA_5(func) \
802
+ (void)self; \
803
+ sollya_obj_t r; \
804
+ switch (argc) { \
805
+ case 5: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), NULL); break; \
806
+ case 6: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), NULL); break; \
807
+ case 7: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), NULL); break; \
808
+ case 8: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), NULL); break; \
809
+ case 9: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), NULL); break; \
810
+ case 10: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), NULL); break; \
811
+ case 11: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), NULL); break; \
812
+ case 12: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), NULL); break; \
813
+ case 13: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), NULL); break; \
814
+ case 14: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), NULL); break; \
815
+ case 15: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), NULL); break; \
816
+ case 16: r = func(SOLLYARB_ARGV(0), SOLLYARB_ARGV(1), SOLLYARB_ARGV(2), SOLLYARB_ARGV(3), SOLLYARB_ARGV(4), SOLLYARB_ARGV(5), SOLLYARB_ARGV(6), SOLLYARB_ARGV(7), SOLLYARB_ARGV(8), SOLLYARB_ARGV(9), SOLLYARB_ARGV(10), SOLLYARB_ARGV(11), SOLLYARB_ARGV(12), SOLLYARB_ARGV(13), SOLLYARB_ARGV(14), SOLLYARB_ARGV(15), NULL); break; \
817
+ default: rb_raise(rb_eArgError, "expecting 5 to 16 arguments, got %d", argc); \
818
+ } \
819
+ return sollyarb_autowrap_object(r)
820
+
821
+
822
+
823
+ static VALUE sollyarb_list(int argc, VALUE *argv, VALUE self)
824
+ {
825
+ VALUE splat;
826
+ VALUE kw;
827
+ const ID kwkeys[1] = {id_end_elliptic};
828
+ VALUE kwvalues[1] = {Qundef};
829
+ int is_end_elliptic = 0;
830
+ rb_scan_args(argc, argv, "*:", &splat, &kw);
831
+ if (!NIL_P(kw)) {
832
+ rb_get_kwargs(kw, kwkeys, 0, 1, kwvalues);
833
+ if (kwvalues[0] != Qundef) {
834
+ if (RB_TEST(kwvalues[0])) {
835
+ is_end_elliptic = 1;
836
+ }
837
+ }
838
+ }
839
+
840
+ long i;
841
+ long l = rb_array_len(splat);
842
+ sollya_obj_t *carr = malloc(l*sizeof(sollya_obj_t));
843
+ sollya_obj_t r;
844
+ for (i = 0; i < l; i++) {
845
+ carr[i] = SOLLYARB_TO_SOLLYA(rb_ary_entry(splat, i));
846
+ }
847
+ if (is_end_elliptic) {
848
+ r = sollya_lib_end_elliptic_list(carr, l);
849
+ } else {
850
+ r = sollya_lib_list(carr, l);
851
+ }
852
+ free(carr);
853
+ return sollyarb_autowrap_object(r);
854
+ }
855
+
856
+
857
+ static VALUE sollyarb_list_is_end_elliptic(VALUE self)
858
+ {
859
+ sollya_obj_t l = sollyarb_object_rb2ref(self);
860
+ if (sollya_lib_obj_is_end_elliptic_list(l))
861
+ return Qtrue;
862
+ if (sollya_lib_obj_is_list(l))
863
+ return Qfalse;
864
+ return Qfalse;
865
+ }
866
+
867
+
868
+ /* @return [MPFR]
869
+ */
870
+ static VALUE sollyarb_range_lower_bound(VALUE self)
871
+ {
872
+ sollya_obj_t rng = sollyarb_object_rb2ref(self);
873
+ mp_prec_t prec = 0;
874
+ if (!sollya_lib_get_prec_of_range(&prec, rng)) {
875
+ sollya_obj_t p = sollya_lib_get_prec();
876
+ sollya_lib_get_constant_as_int64(&prec, p);
877
+ sollya_lib_clear_obj(p);
878
+ }
879
+ if (!prec) {
880
+ return Qnil;
881
+ }
882
+ VALUE mprb = mpfrrb_alloc(c_MPFR);
883
+ mpfr_ptr mp = mpfrrb_rb2ref_ext(mprb);
884
+ mpfr_init2(mp, prec);
885
+
886
+ mpfr_t dummy;
887
+ mpfr_init2(dummy, 32);
888
+ if (!sollya_lib_get_bounds_from_range(mp, dummy, rng)) {
889
+ mpfr_clear(dummy);
890
+ return Qnil;
891
+ }
892
+ return mprb;
893
+ }
894
+
895
+
896
+ /* @return [MPFR]
897
+ */
898
+ static VALUE sollyarb_range_upper_bound(VALUE self)
899
+ {
900
+ sollya_obj_t rng = sollyarb_object_rb2ref(self);
901
+ mp_prec_t prec = 0;
902
+ if (!sollya_lib_get_prec_of_range(&prec, rng)) {
903
+ sollya_obj_t p = sollya_lib_get_prec();
904
+ sollya_lib_get_constant_as_int64(&prec, p);
905
+ sollya_lib_clear_obj(p);
906
+ }
907
+ if (!prec) {
908
+ return Qnil;
909
+ }
910
+ VALUE mprb = mpfrrb_alloc(c_MPFR);
911
+ mpfr_ptr mp = mpfrrb_rb2ref_ext(mprb);
912
+ mpfr_init2(mp, prec);
913
+
914
+ mpfr_t dummy;
915
+ mpfr_init2(dummy, 32);
916
+ if (!sollya_lib_get_bounds_from_range(dummy, mp, rng)) {
917
+ mpfr_clear(dummy);
918
+ return Qnil;
919
+ }
920
+ return mprb;
921
+ }
922
+
923
+
924
+ /* @return [Sollya::Range]
925
+ */
926
+ static VALUE sollyarb_range(VALUE self, VALUE inf, VALUE sup)
927
+ {
928
+ return sollyarb_autowrap_object(sollya_lib_range(SOLLYARB_TO_SOLLYA(inf), SOLLYARB_TO_SOLLYA(sup)));
929
+ }
930
+
931
+
932
+ /* @param str [String]
933
+ * @return [Sollya::Object]
934
+ */
935
+ static VALUE sollyarb_parse(VALUE self, VALUE str)
936
+ {
937
+ (void)self;
938
+ str = rb_funcallv(str, id_to_s, 0, NULL);
939
+ const char *cstr = rb_string_value_cstr(&str);
940
+ sollya_obj_t sr = sollya_lib_parse_string(cstr);
941
+ RB_GC_GUARD(str);
942
+ return sollyarb_autowrap_object(sr);
943
+ }
944
+
945
+
946
+ /* Returns the precision of the floating-point format used in numerical computations.
947
+ * Many commands try to adapt their working precision in order to have approximately _𝑛_ correct bits in output,
948
+ * where _𝑛_ is the value of `prec`.
949
+ * @return [Integer]
950
+ */
951
+ static VALUE sollyarb_get_prec(VALUE self)
952
+ {
953
+ sollya_obj_t p = sollya_lib_get_prec();
954
+ int64_t i;
955
+ int r = sollya_lib_get_constant_as_int64(&i, p);
956
+ sollya_lib_clear_obj(p);
957
+ if (!r) {
958
+ rb_raise(rb_eRuntimeError, "Cannot get prec as integer");
959
+ }
960
+ return LL2NUM(i);
961
+ }
962
+
963
+
964
+ /* Set the precision of the floating-point format used in numerical computations.
965
+ * That is, the number of bits of the significand of floating-point numbers.
966
+ * @param prec [Integer]
967
+ * @return [Integer]
968
+ */
969
+ static VALUE sollyarb_set_prec(VALUE self, VALUE prec)
970
+ {
971
+ sollya_obj_t p = sollya_lib_constant_from_int(NUM2INT(prec));
972
+ sollya_lib_set_prec(p);
973
+ sollya_lib_clear_obj(p);
974
+ return prec;
975
+ }
976
+
977
+
978
+ /* Returns the number of points chosen by Sollya in certain commands.
979
+ * Its value represents the number of points used in numerical algorithms
980
+ * of Sollya (namely {dirtyinfnorm}, {dirtyintegral}, {dirtyfindzeros} and {plot}).
981
+ * @return [Integer]
982
+ * @see points=
983
+ */
984
+ static VALUE sollyarb_get_points(VALUE self)
985
+ {
986
+ sollya_obj_t p = sollya_lib_get_points();
987
+ int64_t i;
988
+ int r = sollya_lib_get_constant_as_int64(&i, p);
989
+ sollya_lib_clear_obj(p);
990
+ if (!r) {
991
+ rb_raise(rb_eRuntimeError, "Cannot get points as integer");
992
+ }
993
+ return LL2NUM(i);
994
+ }
995
+
996
+
997
+ /* Set the number of points chosen by Sollya in certain commands.
998
+ * @param [Integer]
999
+ * @return [Integer]
1000
+ * @see points
1001
+ */
1002
+ static VALUE sollyarb_set_points(VALUE self, VALUE points)
1003
+ {
1004
+ sollya_obj_t p = sollya_lib_constant_from_int(NUM2INT(points));
1005
+ sollya_lib_set_points(p);
1006
+ sollya_lib_clear_obj(p);
1007
+ return points;
1008
+ }
1009
+
1010
+
1011
+ /* Returns the maximal width allowed for intervals involved in safe algorithms of Sollya.
1012
+ * These are {infnorm}, {checkinfnorm}, {accurateinfnorm}, {integral}, {findzeros} and {supnorm}.
1013
+ * More precisely, _diam_ is relative to the width of the input interval of the command.
1014
+ * For instance, suppose that diam=1e-5: if infnorm is called on interval [0, 1], the maximal width of an interval
1015
+ * will be 1e-5. But if it is called on interval [0, 1e-3], the maximal width will be 1e-8.
1016
+ * @return [MPFR,Float] the maximal relative width of the intervals used
1017
+ * @see diam=
1018
+ */
1019
+ static VALUE sollyarb_get_diam(VALUE self)
1020
+ {
1021
+ sollya_obj_t c = sollya_lib_get_diam();
1022
+ mp_prec_t prec = 0;
1023
+ if (!sollya_lib_get_prec_of_constant(&prec, c)) {
1024
+ sollya_obj_t p = sollya_lib_get_prec();
1025
+ sollya_lib_get_constant_as_int64(&prec, p);
1026
+ sollya_lib_clear_obj(p);
1027
+ }
1028
+ if (!prec) return Qnil;
1029
+ if (prec <= 53) {
1030
+ double d;
1031
+ if (sollya_lib_get_constant_as_double(&d, c))
1032
+ return DBL2NUM(d);
1033
+ }
1034
+ VALUE mprb = mpfrrb_alloc(c_MPFR);
1035
+ mpfr_ptr mp = mpfrrb_rb2ref_ext(mprb);
1036
+ mpfr_init2(mp, prec);
1037
+ if (!sollya_lib_get_constant(mp, c)) {
1038
+ return Qnil;
1039
+ }
1040
+ return mprb;
1041
+ }
1042
+
1043
+
1044
+ /* Sets the maximal width allowed for intervals involved in safe algorithms of Sollya.
1045
+ * These are {infnorm}, {checkinfnorm}, {accurateinfnorm}, {integral}, {findzeros} and {supnorm}.
1046
+ * More precisely, _diam_ is relative to the width of the input interval of the command.
1047
+ * For instance, suppose that diam=1e-5: if infnorm is called on interval [0, 1], the maximal width of an interval
1048
+ * will be 1e-5. But if it is called on interval [0, 1e-3], the maximal width will be 1e-8.
1049
+ * @param width [MPFR] the maximal relative width of the intervals used
1050
+ * @return [MPFR,Float]
1051
+ * @see diam
1052
+ */
1053
+ static VALUE sollyarb_set_diam(VALUE self, VALUE width)
1054
+ {
1055
+ width = rb_funcallv(width, id_to_sollya, 0, NULL);
1056
+ sollya_obj_t w = sollyarb_object_rb2ref(width);
1057
+ sollya_lib_set_diam(w);
1058
+ return width;
1059
+ }
1060
+
1061
+
1062
+ /* Gets the global variable specifying number notation.
1063
+ * @see display=
1064
+ * @return [Symbol] `:decimal`, `:dyadic`, `:powers`, `:binary` or `:hexadecimal`
1065
+ */
1066
+ static VALUE sollyarb_get_display(VALUE self)
1067
+ {
1068
+ sollya_obj_t c = sollya_lib_get_display();
1069
+ if (sollya_lib_is_decimal(c)) {
1070
+ sollya_lib_clear_obj(c);
1071
+ return ID2SYM(id_decimal);
1072
+ } else if (sollya_lib_is_binary(c)) {
1073
+ sollya_lib_clear_obj(c);
1074
+ return ID2SYM(id_binary);
1075
+ } else if (sollya_lib_is_dyadic(c)) {
1076
+ sollya_lib_clear_obj(c);
1077
+ return ID2SYM(id_dyadic);
1078
+ } else if (sollya_lib_is_powers(c)) {
1079
+ sollya_lib_clear_obj(c);
1080
+ return ID2SYM(id_powers);
1081
+ } else if (sollya_lib_is_hexadecimal(c)) {
1082
+ sollya_lib_clear_obj(c);
1083
+ return ID2SYM(id_hexadecimal);
1084
+ }
1085
+ return sollyarb_autowrap_object(c);
1086
+ }
1087
+
1088
+
1089
+ /* Gets the global variable specifying number notation.
1090
+ * An assignment `display = notation_value`, where notation value is one of `:decimal`, `:dyadic`, `:powers`,
1091
+ * `:binary` or `:hexadecimal`, activates the corresponding notation for output of values in print, write
1092
+ * or at the Sollya prompt.
1093
+ *
1094
+ * - If the global notation variable display is `:decimal`, all numbers will be output in scientific decimal notation.
1095
+ * - If the global notation variable display is `:dyadic`, all numbers will be output as dyadic numbers with Gappa notation.
1096
+ * - If the global notation variable display is `:powers`, all numbers will be output as dyadic numbers with a notation
1097
+ * compatible with Maple and PARI/GP.
1098
+ * - If the global notation variable display is `:binary`, all numbers will be output in binary notation.
1099
+ * - If the global notation variable display is `:hexadecimal`, all numbers will be output in C99/ IEEE754-2008 notation.
1100
+ *
1101
+ * All output notations can be parsed back by Sollya, inducing no error if the input and
1102
+ * output precisions are the same (see {prec}).
1103
+ * @param display_notation [Symbol] `:decimal`, `:dyadic`, `:powers`, `:binary` or `:hexadecimal`
1104
+ */
1105
+ static VALUE sollyarb_set_display(VALUE self, VALUE notation_value)
1106
+ {
1107
+ notation_value = rb_funcallv(notation_value, id_to_sollya, 0, NULL);
1108
+ sollya_obj_t nv = sollyarb_object_rb2ref(notation_value);
1109
+ sollya_lib_set_display(nv);
1110
+ return notation_value;
1111
+ }
1112
+
1113
+
1114
+
1115
+ /* Returns the verbosity level.
1116
+ * At level 0, commands do not display anything on standard output.
1117
+ * Default level is 1. It displays important information such as warnings when roundings happen.
1118
+ * @return [Integer]
1119
+ * @see verbosity=
1120
+ */
1121
+ static VALUE sollyarb_get_verbosity(VALUE self)
1122
+ {
1123
+ sollya_obj_t p = sollya_lib_get_verbosity();
1124
+ int64_t i;
1125
+ if (!sollya_lib_get_constant_as_int64(&i, p)) return Qnil;
1126
+ sollya_lib_clear_obj(p);
1127
+ return LL2NUM(i);
1128
+ }
1129
+
1130
+
1131
+ /* Set the amount of information displayed by commands.
1132
+ * At level 0, commands do not display anything on standard output.
1133
+ * Note that very critical information may however be displayed on standard error.
1134
+ * Default level is 1. It displays important information such as warnings when roundings happen.
1135
+ * For higher levels more information is displayed depending on the command.
1136
+ * @param n [Integer] level of verbosity
1137
+ * @return [Integer]
1138
+ * @see verbosity
1139
+ * @see roundingwarnings
1140
+ * @see suppressmessage
1141
+ */
1142
+ static VALUE sollyarb_set_verbosity(VALUE self, VALUE n)
1143
+ {
1144
+ sollya_obj_t p = sollya_lib_constant_from_int(NUM2INT(n));
1145
+ sollya_lib_set_verbosity(p);
1146
+ sollya_lib_clear_obj(p);
1147
+ return n;
1148
+ }
1149
+
1150
+
1151
+ /* Returns whether or not a warning is displayed when roundings occur.
1152
+ * When it is `true`, warnings are emitted in appropriate verbosity modes (see {verbosity}) when roundings occur.
1153
+ * When it is `false`, these warnings are suppressed.
1154
+ *
1155
+ * This mode depends on a verbosity of at least 1. See {verbosity} for more details.
1156
+ *
1157
+ * Default is `true` when the standard input is a terminal and `false` when Sollya input is read from a file.
1158
+ * @see roundingwarnings=
1159
+ * @return [Boolean]
1160
+ */
1161
+ static VALUE sollyarb_get_roundingwarnings(VALUE self)
1162
+ {
1163
+ sollya_obj_t w = sollya_lib_get_roundingwarnings();
1164
+ if (sollya_lib_is_on(w)) {
1165
+ sollya_lib_clear_obj(w);
1166
+ return Qtrue;
1167
+ } else if (sollya_lib_is_off(w)) {
1168
+ sollya_lib_clear_obj(w);
1169
+ return Qfalse;
1170
+ }
1171
+ return sollyarb_autowrap_object(w);
1172
+ }
1173
+
1174
+
1175
+ /* Sets whether or not a warning is displayed when roundings occur.
1176
+ * When set to `true`, warnings are emitted in appropriate verbosity modes (see {verbosity}) when roundings occur.
1177
+ * When set to `false`, these warnings are suppressed.
1178
+ * @param v [Boolean]
1179
+ * @return [Boolean]
1180
+ * @see roundingwarnings
1181
+ */
1182
+ static VALUE sollyarb_set_roundingwarnings(VALUE self, VALUE v)
1183
+ {
1184
+ sollya_obj_t w = (v != sollyarb_cst_OFF && v != sollyarb_cst_FALSE && (v == sollyarb_cst_ON || RB_TEST(v))) ? sollyarb_object_rb2ref(sollyarb_cst_ON) : sollyarb_object_rb2ref(sollyarb_cst_OFF);
1185
+ sollya_lib_set_roundingwarnings(w);
1186
+ return v;
1187
+ }
1188
+
1189
+
1190
+ /* Returns the value of the automatic simplification state variable.
1191
+ * @see autosimplify=
1192
+ * @return [Boolean]
1193
+ */
1194
+ static VALUE sollyarb_get_autosimplify(VALUE self)
1195
+ {
1196
+ sollya_obj_t w = sollya_lib_get_autosimplify();
1197
+ if (sollya_lib_is_on(w)) {
1198
+ sollya_lib_clear_obj(w);
1199
+ return Qtrue;
1200
+ } else if (sollya_lib_is_off(w)) {
1201
+ sollya_lib_clear_obj(w);
1202
+ return Qfalse;
1203
+ }
1204
+ return sollyarb_autowrap_object(w);
1205
+ }
1206
+
1207
+
1208
+ /* Activates or deactivates automatic simplification.
1209
+ * That is, the automatic safe simplification of expressions of functions generated
1210
+ * by the evaluation of commands or in argument of other commands.
1211
+ *
1212
+ * Sollya commands like {remez}, {taylor} or {rationalapprox} sometimes produce expressions that
1213
+ * can be simplified. Constant subexpressions can be evaluated to dyadic floating-point numbers,
1214
+ * monomials with coefficients 0 can be eliminated. Further, expressions indicated by the user perform
1215
+ * better in many commands when simplified before being passed in argument to a command. When
1216
+ * the automatic simplification of expressions is activated, Sollya automatically performs a safe (not
1217
+ * value changing) simplification process on such expressions.
1218
+ *
1219
+ * The automatic generation of subexpressions can be annoying, in particular if it takes too much
1220
+ * time for not enough benefit. Further the user might want to inspect the structure of the expression
1221
+ * tree returned by a command. In this case, the automatic simplification should be deactivated.
1222
+ * @param v [Boolean]
1223
+ * @return [Boolean]
1224
+ * @see autosimplify
1225
+ */
1226
+ static VALUE sollyarb_set_autosimplify(VALUE self, VALUE v)
1227
+ {
1228
+ sollya_obj_t w = (v != sollyarb_cst_OFF && v != sollyarb_cst_FALSE && (v == sollyarb_cst_ON || RB_TEST(v))) ? sollyarb_object_rb2ref(sollyarb_cst_ON) : sollyarb_object_rb2ref(sollyarb_cst_OFF);
1229
+ sollya_lib_set_autosimplify(w);
1230
+ return v;
1231
+ }
1232
+
1233
+
1234
+ /* Returns the value of the state variable controlling output with full parenthesising.
1235
+ * @see fullparentheses=
1236
+ * @return [Boolean]
1237
+ */
1238
+ static VALUE sollyarb_get_fullparentheses(VALUE self)
1239
+ {
1240
+ sollya_obj_t w = sollya_lib_get_fullparentheses();
1241
+ if (sollya_lib_is_on(w)) {
1242
+ sollya_lib_clear_obj(w);
1243
+ return Qtrue;
1244
+ } else if (sollya_lib_is_off(w)) {
1245
+ sollya_lib_clear_obj(w);
1246
+ return Qfalse;
1247
+ }
1248
+ return sollyarb_autowrap_object(w);
1249
+ }
1250
+
1251
+
1252
+ /* Activates or deactivates the output of expressions with full parenthesising.
1253
+ * In full parenthesising mode, Sollya commands like {print}, {write} and the implicit command when an expression
1254
+ * is given at the prompt will output expressions with parenthesising at all places where it is necessary
1255
+ * for expressions containing infix operators to be parsed back with the same result. Otherwise
1256
+ * parentheses around associative operators are omitted.
1257
+ * @param v [Boolean]
1258
+ * @return [Boolean]
1259
+ * @see fullparentheses
1260
+ */
1261
+ static VALUE sollyarb_set_fullparentheses(VALUE self, VALUE v)
1262
+ {
1263
+ sollya_obj_t w = (v != sollyarb_cst_OFF && v != sollyarb_cst_FALSE && (v == sollyarb_cst_ON || RB_TEST(v))) ? sollyarb_object_rb2ref(sollyarb_cst_ON) : sollyarb_object_rb2ref(sollyarb_cst_OFF);
1264
+ sollya_lib_set_fullparentheses(w);
1265
+ return v;
1266
+ }
1267
+
1268
+
1269
+ /* Returns whether message numbers are displayed in messages.
1270
+ * @see showmessagenumbers=
1271
+ * @return [Boolean]
1272
+ */
1273
+ static VALUE sollyarb_get_showmessagenumbers(VALUE self)
1274
+ {
1275
+ sollya_obj_t w = sollya_lib_get_showmessagenumbers();
1276
+ if (sollya_lib_is_on(w)) {
1277
+ sollya_lib_clear_obj(w);
1278
+ return Qtrue;
1279
+ } else if (sollya_lib_is_off(w)) {
1280
+ sollya_lib_clear_obj(w);
1281
+ return Qfalse;
1282
+ }
1283
+ return sollyarb_autowrap_object(w);
1284
+ }
1285
+
1286
+
1287
+ /* Activates or deactivates the displaying of numbers for warning and information
1288
+ * messages. Every Sollya warning or information message (that is not fatal to the tool's execution)
1289
+ * has a message number. By default, these numbers are not displayed when a message is output.
1290
+ * When message number displaying is activated, the message numbers are displayed together with
1291
+ * the message. This allows the user to recover the number of a particular message in order to
1292
+ * suppress resp. unsuppress the displaying of this particular message (see suppressmessage and
1293
+ * unsuppressmessage).
1294
+ *
1295
+ * The user should be aware of the fact that message number display activation resp. deactivation
1296
+ * through showmessagenumbers does not affect message displaying in general. For instance, even
1297
+ * with message number displaying activated, messages with only displayed when general verbosity
1298
+ * and rounding warning mode are set accordingly.
1299
+ * @param v [Boolean]
1300
+ * @return [Boolean]
1301
+ * @see showmessagenumbers
1302
+ */
1303
+ static VALUE sollyarb_set_showmessagenumbers(VALUE self, VALUE v)
1304
+ {
1305
+ sollya_obj_t w = (v != sollyarb_cst_OFF && v != sollyarb_cst_FALSE && (v == sollyarb_cst_ON || RB_TEST(v))) ? sollyarb_object_rb2ref(sollyarb_cst_ON) : sollyarb_object_rb2ref(sollyarb_cst_OFF);
1306
+ sollya_lib_set_showmessagenumbers(w);
1307
+ return v;
1308
+ }
1309
+
1310
+
1311
+ /* Returns the the way intervals are displayed.
1312
+ * @return [Boolean]
1313
+ * @see midpointmode=
1314
+ */
1315
+ static VALUE sollyarb_get_midpointmode(VALUE self)
1316
+ {
1317
+ sollya_obj_t w = sollya_lib_get_midpointmode();
1318
+ if (sollya_lib_is_on(w)) {
1319
+ sollya_lib_clear_obj(w);
1320
+ return Qtrue;
1321
+ } else if (sollya_lib_is_off(w)) {
1322
+ sollya_lib_clear_obj(w);
1323
+ return Qfalse;
1324
+ }
1325
+ return sollyarb_autowrap_object(w);
1326
+ }
1327
+
1328
+ /* Enables or disables midpoint mode.
1329
+ * When not activated, intervals are displayed as usual (in the form [𝑎; 𝑏]).
1330
+ * When it is on, and if _𝑎_ and _𝑏_ have the same first significant digits, the interval
1331
+ * in displayed in a way that lets one immediately see the common digits of the two bounds.
1332
+ *
1333
+ * This mode is supported only with {display} set to `:decimal`.
1334
+ * In other modes of {display}, midpointmode value is simply ignored.
1335
+ * @param v [Boolean]
1336
+ * @return [Boolean]
1337
+ * @see midpointmode
1338
+ */
1339
+ static VALUE sollyarb_set_midpointmode(VALUE self, VALUE v)
1340
+ {
1341
+ sollya_obj_t w = (v != sollyarb_cst_OFF && v != sollyarb_cst_FALSE && (v == sollyarb_cst_ON || RB_TEST(v))) ? sollyarb_object_rb2ref(sollyarb_cst_ON) : sollyarb_object_rb2ref(sollyarb_cst_OFF);
1342
+ sollya_lib_set_midpointmode(w);
1343
+ return v;
1344
+ }
1345
+
1346
+
1347
+ /* Without arguments, returns the global variable controlling the canonical form printing;
1348
+ * with an expression argument, brings all polynomial subexpressions to canonical form.
1349
+ *
1350
+ * @overload canonical
1351
+ * @return [Boolean] canonical form printing
1352
+ * @see canonical=
1353
+ *
1354
+ * The command canonical rewrites the expression representing the function `expr` in a way such
1355
+ * that all polynomial subexpressions (or the whole expression itself, if it is a polynomial) are written
1356
+ * in canonical form, i.e. as a sum of monomials in the canonical base. The canonical base is the
1357
+ * base of the integer powers of the global free variable. The command canonical does not endanger
1358
+ * the safety of computations even in Sollya's floating-point environment: the function returned is
1359
+ * mathematically equal to the function function.
1360
+ * @overload canonical(expr)
1361
+ * @param expr [Function] the expression to be rewritten in canonical form
1362
+ * @return [Function]
1363
+ */
1364
+ static VALUE sollyarb_get_canonical(int argc, VALUE *argv, VALUE self)
1365
+ {
1366
+ if (argc == 0) {
1367
+ sollya_obj_t w = sollya_lib_get_canonical();
1368
+ if (sollya_lib_is_on(w)) {
1369
+ sollya_lib_clear_obj(w);
1370
+ return Qtrue;
1371
+ } else if (sollya_lib_is_off(w)) {
1372
+ sollya_lib_clear_obj(w);
1373
+ return Qfalse;
1374
+ }
1375
+ return sollyarb_autowrap_object(w);
1376
+ } else if (argc == 1) {
1377
+ argv[0] = rb_funcallv(argv[0], id_to_sollya, 0, NULL);
1378
+ sollya_obj_t r = sollya_lib_canonical(sollyarb_object_rb2ref(argv[0]));
1379
+ return sollyarb_autowrap_object(r);
1380
+ } else {
1381
+ rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 0..1)", argc);
1382
+ }
1383
+ }
1384
+
1385
+ /* Enables or disables canonical form printing.
1386
+ * Canonical form printing is the automatic printing of polynomial expressions in canonical form, i.e. as
1387
+ * a sum of monomials in the canonical base. If automatic printing in canonical form is deactivated,
1388
+ * automatic printing yields to displaying polynomial subexpressions in Horner form.
1389
+ * @param v [Boolean]
1390
+ * @return [Boolean]
1391
+ * @see canonical
1392
+ */
1393
+ static VALUE sollyarb_set_canonical(VALUE self, VALUE v)
1394
+ {
1395
+ sollya_obj_t w = (v != sollyarb_cst_OFF && v != sollyarb_cst_FALSE && (v == sollyarb_cst_ON || RB_TEST(v))) ? sollyarb_object_rb2ref(sollyarb_cst_ON) : sollyarb_object_rb2ref(sollyarb_cst_OFF);
1396
+ sollya_lib_set_canonical(w);
1397
+ return v;
1398
+ }
1399
+
1400
+
1401
+ /* Returns if rational arithmetic is used or not.
1402
+ * @return [Boolean]
1403
+ * @see rationalmode=
1404
+ */
1405
+ static VALUE sollyarb_get_rationalmode(VALUE self)
1406
+ {
1407
+ sollya_obj_t w = sollya_lib_get_rationalmode();
1408
+ if (sollya_lib_is_on(w)) {
1409
+ sollya_lib_clear_obj(w);
1410
+ return Qtrue;
1411
+ } else if (sollya_lib_is_off(w)) {
1412
+ sollya_lib_clear_obj(w);
1413
+ return Qfalse;
1414
+ }
1415
+ return sollyarb_autowrap_object(w);
1416
+ }
1417
+
1418
+ /* Sets whether rational arithmetic should be used or not.
1419
+ * _rationalmode_ is a global variable. When its value is off, which is the default, Sollya will
1420
+ * not use rational arithmetic to simplify expressions. All computations, including the evaluation
1421
+ * of constant expressions given on the Sollya prompt, will be performed using floating-point and
1422
+ * interval arithmetic. Constant expressions will be approximated by floating-point numbers, which
1423
+ * are in most cases faithful roundings of the expressions, when shown at the prompt.
1424
+ *
1425
+ * When it is on, Sollya will use rational arithmetic
1426
+ * when simplifying expressions. Constant expressions, given at the Sollya prompt, will be simplified
1427
+ * to rational numbers and displayed as such when they are in the set of the rational numbers. Other-
1428
+ * wise, floating-point and interval arithmetic will be used to compute a floating-point approximation,
1429
+ * which is in most cases a faithful rounding of the constant expression.
1430
+ *
1431
+ * When a decimal value is parsed, the behavior of Sollya is different depending on the value of
1432
+ * the global variable rationalmode. If it is off, the value gets rounded as a floating-point at
1433
+ * precision prec. But if rationalmode is set to on, the decimal value is interpreted exactly and
1434
+ * converted as a rational number of the form 𝑀/10𝑁 where 𝑀 and 𝑁 are integers. Accordingly, when
1435
+ * rationalmode is set to on and display is set to decimal, all floating-point values are displayed
1436
+ * exactly: indeed, any floating-point number with radix 2 has a finite decimal expansion. Therefore,
1437
+ * any rational number of the form 𝑀/(2^P · 5^Q ) gets displayed as an exact decimal value (while other
1438
+ * fractions get displayed as fractions).
1439
+ *
1440
+ * @param v [Boolean]
1441
+ * @return [Boolean]
1442
+ * @see rationalmode
1443
+ */
1444
+ static VALUE sollyarb_set_rationalmode(VALUE self, VALUE v)
1445
+ {
1446
+ sollya_obj_t w = (v != sollyarb_cst_OFF && v != sollyarb_cst_FALSE && (v == sollyarb_cst_ON || RB_TEST(v))) ? sollyarb_object_rb2ref(sollyarb_cst_ON) : sollyarb_object_rb2ref(sollyarb_cst_OFF);
1447
+ sollya_lib_set_rationalmode(w);
1448
+ return v;
1449
+ }
1450
+
1451
+
1452
+ /* Returns whether timing measures are performed in Sollya.
1453
+ * @return [Boolean]
1454
+ * @see timing=
1455
+ */
1456
+ static VALUE sollyarb_get_timing(VALUE self)
1457
+ {
1458
+ sollya_obj_t w = sollya_lib_get_timing();
1459
+ if (sollya_lib_is_on(w)) {
1460
+ sollya_lib_clear_obj(w);
1461
+ return Qtrue;
1462
+ } else if (sollya_lib_is_off(w)) {
1463
+ sollya_lib_clear_obj(w);
1464
+ return Qfalse;
1465
+ }
1466
+ return sollyarb_autowrap_object(w);
1467
+ }
1468
+
1469
+ /* Sets whether timing measures a re performed in Sollya.
1470
+ *
1471
+ * When set to `true`, the time spent in each command is measured
1472
+ * and displayed (for {verbosity} levels higher than 1).
1473
+ *
1474
+ * @param v [Boolean]
1475
+ * @return [Boolean]
1476
+ * @see timing
1477
+ */
1478
+ static VALUE sollyarb_set_timing(VALUE self, VALUE v)
1479
+ {
1480
+ sollya_obj_t w = (v != sollyarb_cst_OFF && v != sollyarb_cst_FALSE && (v == sollyarb_cst_ON || RB_TEST(v))) ? sollyarb_object_rb2ref(sollyarb_cst_ON) : sollyarb_object_rb2ref(sollyarb_cst_OFF);
1481
+ sollya_lib_set_timing(w);
1482
+ return v;
1483
+ }
1484
+
1485
+
1486
+ /* Returns the number of recursion steps when applying Taylor's rule.
1487
+ * @return [Integer]
1488
+ * @see taylorrecursions=
1489
+ */
1490
+ static VALUE sollyarb_get_taylorrecursions(VALUE self)
1491
+ {
1492
+ sollya_obj_t p = sollya_lib_get_taylorrecursions();
1493
+ int64_t i;
1494
+ int r = sollya_lib_get_constant_as_int64(&i, p);
1495
+ sollya_lib_clear_obj(p);
1496
+ if (!r) {
1497
+ rb_raise(rb_eRuntimeError, "Cannot get taylorrecursions as integer");
1498
+ }
1499
+ return LL2NUM(i);
1500
+ }
1501
+
1502
+
1503
+ /* Set the number of recursion steps when applying Taylor's rule.
1504
+ * This rule is applied by the interval evaluator present in the
1505
+ * core of Sollya (and particularly visible in commands like infnorm).
1506
+ *
1507
+ * To improve the quality of an interval evaluation of a function _𝑓_ , in particular when there are
1508
+ * problems of decorrelation), the evaluator of Sollya uses Taylor's rule:
1509
+ * 𝑓([𝑎, 𝑏]) ⊆ 𝑓(𝑚) + [𝑎 - 𝑚, 𝑏 − 𝑚] · 𝑓'([𝑎, 𝑏])
1510
+ * where 𝑚 = (𝑎+𝑏)/2
1511
+ * This rule can be applied recursively. The number of step in this recursion process is controlled by taylorrecursions.
1512
+ *
1513
+ * Setting taylorrecursions to 0 makes Sollya use this rule only once; setting it to 1 makes Sollya
1514
+ * use the rule twice, and so on. In particular: the rule is always applied at least once.
1515
+ * @param n [Integer] the number of recursions
1516
+ * @return [Integer]
1517
+ * @see taylorrecursions
1518
+ */
1519
+ static VALUE sollyarb_set_taylorrecursions(VALUE self, VALUE n)
1520
+ {
1521
+ sollya_obj_t p = sollya_lib_constant_from_int(NUM2INT(n));
1522
+ sollya_lib_set_taylorrecursions(p);
1523
+ sollya_lib_clear_obj(p);
1524
+ return n;
1525
+ }
1526
+
1527
+
1528
+ /* Returns the number of recursion steps when applying L'Hopital's rule.
1529
+ * @return [Integer]
1530
+ * @see hopitalrecursions=
1531
+ */
1532
+ static VALUE sollyarb_get_hopitalrecursions(VALUE self)
1533
+ {
1534
+ sollya_obj_t p = sollya_lib_get_hopitalrecursions();
1535
+ int64_t i;
1536
+ int r = sollya_lib_get_constant_as_int64(&i, p);
1537
+ sollya_lib_clear_obj(p);
1538
+ if (!r) {
1539
+ rb_raise(rb_eRuntimeError, "Cannot get hopitalrecursions as integer");
1540
+ }
1541
+ return LL2NUM(i);
1542
+ }
1543
+
1544
+
1545
+ /* Set the number of steps of recursion that are tried when applying L'Hopital's rule.
1546
+ * This rule is applied by the interval evaluator present in
1547
+ * the core of Sollya (and particularly visible in commands like infnorm).
1548
+ *
1549
+ * If an expression of the form _𝑓/𝑔_ has to be evaluated by interval arithmetic on an interval _𝐼_ and if _𝑓_
1550
+ * and _𝑔_ have a common zero in _𝐼_, a direct evaluation leads to NaN. Sollya implements a safe heuristic
1551
+ * to avoid this, based on L'Hopital's rule: in such a case, it can be shown that _(𝑓/𝑔)(𝐼) ⊆ (𝑓'/𝑔')(𝐼)_.
1552
+ * Since the same problem may exist for _𝑓''/𝑔'_, the rule is applied recursively. The number of step in
1553
+ * this recursion process is controlled by _hopitalrecursions_.
1554
+ *
1555
+ * Setting hopitalrecursions to 0 makes Sollya use this rule only once; setting it to 1 makes Sollya
1556
+ * use the rule twice, and so on. In particular: the rule is always applied at least once, if necessary.
1557
+ * @param n [Integer] the number of recursions
1558
+ * @return [Integer]
1559
+ * @see hopitalrecursions
1560
+ */
1561
+ static VALUE sollyarb_set_hopitalrecursions(VALUE self, VALUE n)
1562
+ {
1563
+ sollya_obj_t p = sollya_lib_constant_from_int(NUM2INT(n));
1564
+ sollya_lib_set_hopitalrecursions(p);
1565
+ sollya_lib_clear_obj(p);
1566
+ return n;
1567
+ }
1568
+
1569
+
1570
+ /* @return [String]
1571
+ */
1572
+ static VALUE sollyarb_get_free_variable_name(VALUE self)
1573
+ {
1574
+ char *s = sollya_lib_get_free_variable_name();
1575
+ VALUE r = rb_str_new_cstr(s);
1576
+ sollya_lib_free(s);
1577
+ return r;
1578
+ }
1579
+
1580
+
1581
+ static VALUE sollyarb_set_free_variable_name(VALUE self, VALUE name)
1582
+ {
1583
+ sollya_lib_name_free_variable(rb_string_value_cstr(&name));
1584
+ return name;
1585
+ }
1586
+
1587
+
1588
+
1589
+ /* Plots one or several functions.
1590
+ *
1591
+ * This command plots one or several functions `f1`, ... ,`fn` on an interval `range`. Functions can be either
1592
+ * given as parameters of plot or as a list `f_list` which elements are functions. The functions are drawn
1593
+ * on the same plot with different colors.
1594
+ *
1595
+ * If `f_list` contains an element that is not a function (or a constant), an error occurs.
1596
+ *
1597
+ * Plot relies on the value of global variable {points}. Let _𝑛_ be the value of this variable. The algorithm
1598
+ * is the following: each function is evaluated at _𝑛_ evenly distributed points in `range`. At each point, the
1599
+ * computed value is a faithful rounding of the exact value with a sufficiently high precision. Each
1600
+ * point is finally plotted. This should avoid numerical artefacts such as critical cancellations.
1601
+ *
1602
+ * The plot can be saved either as a data file or as a postscript file.
1603
+ *
1604
+ * If you use argument `:file` with a string `name`, Sollya will save a data file called `name.dat` and
1605
+ * a gnuplot directives file called `name.p`. Invoking gnuplot on `name.p` will plot the data stored in
1606
+ * `name.dat`.
1607
+ *
1608
+ * If you use argument `:postscript` with a string `name`, Sollya will save a postscript file called
1609
+ * `name.eps` representing your plot.
1610
+ *
1611
+ * If you use argument `:postscriptfile` with a string `name`, Sollya will produce the corresponding
1612
+ * `name.dat`, `name.p` and `name.eps`.
1613
+ *
1614
+ * By default, this command uses _gnuplot_ to produce the final plot. If Sollya is run while the
1615
+ * environment variable `SOLLYA_GNUPLOT` is set, the content of that variable is used as the gnuplot
1616
+ * binary. If your terminal is not graphic (typically if you use Sollya through ssh without -X) gnuplot
1617
+ * should be able to detect that and produce an ASCII-art version on the standard output. If it is
1618
+ * not the case, you can either store the plot in a postscript file to view it locally, or use {asciiplot}
1619
+ * command.
1620
+ *
1621
+ * If every function is constant, plot will not plot them but just display their value.
1622
+ *
1623
+ * If the interval is reduced to a single point, plot will just display the value of the functions at this
1624
+ * point.
1625
+ *
1626
+ * @return [nil]
1627
+ * @overload plot(f1, ..., fn, range)
1628
+ * @param f1 [Function] functions to be plotted.
1629
+ * @param range [Range] the interval where the functions have to be plotted.
1630
+ * @overload plot(f1, ..., fn, range, mode, name)
1631
+ * @param f1 [Function] functions to be plotted.
1632
+ * @param range [Range] the interval where the functions have to be plotted.
1633
+ * @param mode [Symbol] `:file`, `:postscript` or `:postscriptfile`
1634
+ * @param name [String] name of a file
1635
+ * @overload plot(f_list, range)
1636
+ * @param f_list [List<Function>] a list of functions to be plotted.
1637
+ * @param range [Range] the interval where the functions have to be plotted.
1638
+ * @overload plot(f_list, range, mode, name)
1639
+ * @param f_list [List<Function>] a list of functions to be plotted.
1640
+ * @param range [Range] the interval where the functions have to be plotted.
1641
+ * @param mode [Symbol] `:file`, `:postscript` or `:postscriptfile`
1642
+ * @param name [String] name of a file
1643
+ */
1644
+ static VALUE sollyarb_plot(int argc, VALUE *argv, VALUE self)
1645
+ {
1646
+ SOLLYARB_FUNC_VA_2(sollya_lib_plot);
1647
+ }
1648
+
1649
+
1650
+ /* Plots a function in a range using ASCII characters.
1651
+ *
1652
+ * Plots the function `func` in range `range` using ASCII characters. On systems that
1653
+ * provide the necessary `TIOCGWINSZ ioctl`, Sollya determines the size of the terminal for the plot
1654
+ * size if connected to a terminal. If it is not connected to a terminal or if the test is not possible,
1655
+ * the plot is of fixed size 77 × 25 characters.
1656
+ *
1657
+ * The function is evaluated on a number of points equal
1658
+ * to the number of columns available. Its value is rounded to the next integer in the range of lines
1659
+ * available. A letter _x_ is written at this place. If zero is in the hull of the image domain of the
1660
+ * function, an x-axis is displayed. If zero is in range, a y-axis is displayed. If the function is constant
1661
+ * or if the range is reduced to one point, the function is evaluated to a constant and the constant is
1662
+ * displayed instead of a plot.
1663
+ *
1664
+ * @param func [Function]
1665
+ * @param range [Range]
1666
+ * @return [nil]
1667
+ */
1668
+ static VALUE sollyarb_asciiplot(VALUE self, VALUE func, VALUE range)
1669
+ {
1670
+ sollya_lib_asciiplot(SOLLYARB_TO_SOLLYA(func), SOLLYARB_TO_SOLLYA(range));
1671
+ return Qnil;
1672
+ }
1673
+
1674
+
1675
+ /* Prints a constant value as a hexadecimal double precision number.
1676
+ *
1677
+ * Prints a constant value as a hexadecimal number on 16 hexadecimal digits. The hexadecimal
1678
+ * number represents the integer equivalent to the 64 bit memory representation of the constant
1679
+ * considered as a double precision number.
1680
+ *
1681
+ * If the constant value does not hold on a double precision number, it is first rounded to the nearest
1682
+ * double precision number before displayed. A warning is displayed in this case.
1683
+ * @return [nil]
1684
+ */
1685
+ static VALUE sollyarb_printdouble(VALUE self, VALUE constant)
1686
+ {
1687
+ sollya_lib_printdouble(SOLLYARB_TO_SOLLYA(constant));
1688
+ return Qnil;
1689
+ }
1690
+
1691
+
1692
+ /* Prints a constant value as a hexadecimal single precision number.
1693
+ *
1694
+ * Prints a constant value as a hexadecimal number on 8 hexadecimal digits. The hexadecimal number
1695
+ * represents the integer equivalent to the 32 bit memory representation of the constant considered
1696
+ * as a single precision number.
1697
+ *
1698
+ * If the constant value does not hold on a single precision number, it is first rounded to the nearest
1699
+ * single precision number before it is displayed. A warning is displayed in this case.
1700
+ * @return [nil]
1701
+ */
1702
+ static VALUE sollyarb_printsingle(VALUE self, VALUE constant)
1703
+ {
1704
+ sollya_lib_printsingle(SOLLYARB_TO_SOLLYA(constant));
1705
+ return Qnil;
1706
+ }
1707
+
1708
+
1709
+ /* Prints a polynomial in Horner form with its coefficients written as a expansions of double precision numbers.
1710
+ *
1711
+ * The command printexpansion prints the polynomial `polynomial` in Horner form writing its coefficients
1712
+ * as expansions of double precision numbers. The double precision numbers themselves are
1713
+ * displayed in hexadecimal memory notation (see {printdouble}).
1714
+ *
1715
+ * If some of the coefficients of the polynomial `polynomial` are not floating-point constants but constant
1716
+ * expressions, they are evaluated to floating-point constants using the global precision {prec}. If a
1717
+ * rounding occurs in this evaluation, a warning is displayed.
1718
+ *
1719
+ * If the exponent range of double precision is not sufficient to display all the mantissa bits of a
1720
+ * coefficient, the coefficient is displayed rounded and a warning is displayed.
1721
+ *
1722
+ * If the argument `polynomial` does not represent a polynomial, nothing but a warning or a newline is displayed.
1723
+ * Constants can be displayed using printexpansion since they are polynomials of degree 0.
1724
+ *
1725
+ * @param polynomial [Function]
1726
+ * @return [nil]
1727
+ */
1728
+ static VALUE sollyarb_printexpansion(VALUE self, VALUE polynomial)
1729
+ {
1730
+ sollya_lib_printexpansion(SOLLYARB_TO_SOLLYA(polynomial));
1731
+ return Qnil;
1732
+ }
1733
+
1734
+
1735
+ /* Plots the error of an external code with regard to a function
1736
+ *
1737
+ * The command _externalplot_ plots the error of an external function evaluation code sequence
1738
+ * implemented in the object file named `filename` with regard to the function `function`. If `mode`
1739
+ * evaluates to `:absolute`, the difference of both functions is considered as an error function; if `mode`
1740
+ * evaluates to `:relative`, the difference is divided by the function `function`. The resulting error function
1741
+ * is plotted on all floating-point numbers with `precision` significant mantissa bits in the range `range`.
1742
+ *
1743
+ * If the sixth argument of the command externalplot is given and evaluates to `:perturb`, each of
1744
+ * the floating-point numbers the function is evaluated at gets perturbed by a random value that is
1745
+ * uniformly distributed in ±1 ulp around the original precision bit floating-point variable.
1746
+ *
1747
+ * If a sixth and seventh argument, respectively a seventh and eighth argument in the presence of
1748
+ * `perturb` as a sixth argument, are given that evaluate to a variable of type `:file`, `:postscript`, `:postscriptfile`
1749
+ * respectively to a character sequence of type string, externalplot will plot (additionally) to a file
1750
+ * in the same way as the command plot does. See {plot} for details.
1751
+ *
1752
+ * The external function evaluation code given in the object file name `filename` is supposed to define
1753
+ * a function name f as follows (here in C syntax): `void f(mpfr_t rop, mpfr_t op)`. This function
1754
+ * is supposed to evaluate op with an accuracy corresponding to the precision of rop and assign this
1755
+ * value to rop.
1756
+ *
1757
+ * Example:
1758
+ * ```ruby
1759
+ * system 'gcc -fPIC -c externalplotexample.c'
1760
+ * system 'gcc -shared -o externalplotexample externalplotexample.o -lgmp -lmpfr'
1761
+ * Sollya.externalplot('./externalplotexample', :relative, Sollya.parse 'exp(x)', -0.5 .. 0.5, 12, :perturb)
1762
+ * ```
1763
+ * @return [nil]
1764
+ * @overload externalplot(filename, mode, function, range, precision, perturb = nil, plot_mode = nil, res_filename = nil)
1765
+ * @param filename [String]
1766
+ * @param mode [Symbol] `:absolute` or `:relative`
1767
+ * @param function [Function]
1768
+ * @param range [Range]
1769
+ * @param precision [Integer]
1770
+ * @param perturb [Symbol,nil] `:perturb`
1771
+ * @param plot_mode [Symbol,nil] `:file`, `:postscript` or `:postscriptfile`
1772
+ * @param res_filename [String]
1773
+ */
1774
+ static VALUE sollyarb_externalplot(int argc, VALUE *argv, VALUE self)
1775
+ {
1776
+ SOLLYARB_FUNC_VA_5(sollya_lib_externalplot);
1777
+ }
1778
+
1779
+
1780
+ /* Executes the content of a file
1781
+ *
1782
+ * Opens the file indicated by filename, and executes the sequence of commands it contains.
1783
+ * This command is evaluated at execution time: this way you can modify the file filename (for
1784
+ * instance using bashexecute) and execute it just after.
1785
+ *
1786
+ * If filename contains a command _execute_, it will be executed recursively.
1787
+ *
1788
+ * If filename contains a call to _restart_, it will be neglected.
1789
+ *
1790
+ * If filename contains a call to _quit_, the commands following quit in filename will be neglected.
1791
+ * @param filename [String]
1792
+ * @return [nil]
1793
+ */
1794
+ static VALUE sollyarb_execute(VALUE self, VALUE filename)
1795
+ {
1796
+ sollya_lib_execute(SOLLYARB_TO_SOLLYA(filename));
1797
+ return Qnil;
1798
+ }
1799
+
1800
+
1801
+ /* Prints an expression as an MathML-Content-Tree.
1802
+ *
1803
+ * Prints the functional expression expr as a tree of MathML Content Definition Markups.
1804
+ *
1805
+ * @param expr [Function] a functional expression
1806
+ * @param expr [Function] represents a functional expression
1807
+ * @return [nil]
1808
+ */
1809
+ static VALUE sollyarb_printxml(VALUE self, VALUE expr)
1810
+ {
1811
+ sollya_lib_printxml(SOLLYARB_TO_SOLLYA(expr));
1812
+ return Qnil;
1813
+ }
1814
+
1815
+
1816
+ /* Prints an expression as an MathML-Content-Tree.
1817
+ *
1818
+ * Prints the functional expression expr as a tree of MathML Content Definition Markups.
1819
+ *
1820
+ * The MathML tree is not output on the standard output but in the file `filename` that get newly created or overwritten.
1821
+ *
1822
+ * @param expr [Function] a functional expression
1823
+ * @param filename [String]
1824
+ * @return [nil]
1825
+ */
1826
+ static VALUE sollyarb_printxml_newfile(VALUE self, VALUE expr, VALUE filename)
1827
+ {
1828
+ sollya_lib_printxml_newfile(SOLLYARB_TO_SOLLYA(expr), SOLLYARB_TO_SOLLYA(filename));
1829
+ return Qnil;
1830
+ }
1831
+
1832
+
1833
+ /* Prints an expression as an MathML-Content-Tree.
1834
+ *
1835
+ * Prints the functional expression expr as a tree of MathML Content Definition Markups.
1836
+ *
1837
+ * The MathML tree is not output on the standard output but will be appended to the file `filename`.
1838
+ *
1839
+ * @param expr [Function] a functional expression
1840
+ * @param filename [String]
1841
+ * @return [nil]
1842
+ */
1843
+ static VALUE sollyarb_printxml_appendfile(VALUE self, VALUE expr, VALUE filename)
1844
+ {
1845
+ sollya_lib_printxml_appendfile(SOLLYARB_TO_SOLLYA(expr), SOLLYARB_TO_SOLLYA(filename));
1846
+ return Qnil;
1847
+ }
1848
+
1849
+
1850
+ /* Searches for hard-to-round cases of a function.
1851
+ *
1852
+ * The _worstcase_ command is deprecated. It searches for hard-to-round cases of a function. The
1853
+ * command {searchgal} has a comparable functionality.
1854
+
1855
+ * @return [nil]
1856
+ * @overload worstcase(function, preimage_precision, preimage_exponent_range, image_precision, error_bound, filename = nil)
1857
+ * @param function [Function] the function to be considered
1858
+ * @param preimage_precision [Integer] the precision of the preimages
1859
+ * @param preimage_exponent_range [Range] the exponents in the preimage format
1860
+ * @param image_precision [Integer] the precision of the format the images are to be rounded to
1861
+ * @param error_bound [Constant] the upper bound for the search w.r.t. the relative rounding error
1862
+ * @param filename [String]
1863
+ */
1864
+ static VALUE sollyarb_worstcase(int argc, VALUE *argv, VALUE self)
1865
+ {
1866
+ SOLLYARB_FUNC_VA_5(sollya_lib_worstcase);
1867
+ }
1868
+
1869
+
1870
+ /* Print a list of Sollya objects on the standard output.
1871
+ * @return [nil]
1872
+ * @overload autoprint(obj, ...)
1873
+ * @param obj [#to_sollya]
1874
+ */
1875
+ static VALUE sollyarb_autoprint(int argc, VALUE *argv, VALUE self)
1876
+ {
1877
+ SOLLYARB_FUNC_VA_1(sollya_lib_autoprint);
1878
+ }
1879
+
1880
+
1881
+ /* Suppresses the displaying of messages with a certain number
1882
+ *
1883
+ * The _suppressmessage_ command allows particular warning and information messages to be suppressed
1884
+ * from message output, while maintaining global verbosity levels (see verbosity) high. Every
1885
+ * Sollya warning or information message (that is not fatal to the tool’s execution) has a message
1886
+ * number. When these message numbers msg num 1 thru msg num n are given to suppressmessage,
1887
+ * the corresponding message are no longer displayed. The {unsuppressmessage} command
1888
+ * reverts this suppression from output for a particular message.
1889
+ *
1890
+ * Instead of giving suppressmessage several message numbers msg num 1 thru msg num n or
1891
+ * calling suppressmessage several times, it is possible to give a whole list msg list of message
1892
+ * numbers to suppressmessage.
1893
+ *
1894
+ * The user should be aware that suppressmessage presents sticky behavior for the warning and
1895
+ * information messages suppressed from output. This means that even if subsequent calls to suppressmessage
1896
+ * occur, a message suppressed by a call to suppressmessage stays suppressed until
1897
+ * it is unsuppressed using {unsuppressmessage} or the tool is restarted. This behavior distinguishes
1898
+ * message suppression from other global states of the Sollya tool. The user may use {getsuppressedmessages}
1899
+ * to obtain a list of currently suppressed messages.
1900
+ *
1901
+ * When suppressmessage is used on message numbers that do not exist in the current version of
1902
+ * the tool, a warning is displayed. The call has no other effect though.
1903
+ *
1904
+ * @return [nil]
1905
+ * @overload supressmessage(msg_num_1, ..., msg_num_n)
1906
+ * @param msg_num_1 [Integer]
1907
+ */
1908
+ static VALUE sollyarb_suppressmessage(int argc, VALUE *argv, VALUE self)
1909
+ {
1910
+ SOLLYARB_FUNC_VA_1(sollya_lib_suppressmessage);
1911
+ }
1912
+
1913
+
1914
+ /* Unsuppresses the displaying of messages with a certain number
1915
+ *
1916
+ * The unsuppressmessage command allows particular warning and information messages that have
1917
+ * been suppressed from message output to be unsuppressed, i.e. activated for display again. Every
1918
+ * Sollya warning or information message (that is not fatal to the tool’s execution) has a message
1919
+ * number. When these message numbers `msg_num_1` thru `msg_num_n` are given to unsuppressmessage,
1920
+ * the corresponding message are displayed again, as they are by default at according verbosity
1921
+ * levels. Actually, the unsuppressmessage command just reverts the effects of the suppressmessage command.
1922
+ *
1923
+ * Instead of giving unsuppressmessage several message numbers `msg_num_1` thru `msg_num_n` or
1924
+ * calling unsuppressmessage several times, it is possible to give a whole list `msg_list` of message
1925
+ * numbers to unsuppressmessage.
1926
+ *
1927
+ * The user should be aware that unsuppressmessage presents sticky behavior for the warning and
1928
+ * information messages suppressed from output. In fact, unsuppressmessage just unsuppresses the
1929
+ * warning or information messages given in argument. All other suppressed messages stay suppressed
1930
+ * until they get unsuppressed by subsequent calls to unsuppressmessage or the Sollya tool is
1931
+ * restarted. This behavior distinguishes message suppression from other global states of the Sollya
1932
+ * tool. The user may use getsuppressedmessages to obtain a list of currently suppressed messages.
1933
+ * In particular, in order to unsuppressed all currently suppressed warning or information messages,
1934
+ * the user may feed the output of getsuppressedmessages (a list) into unsuppressmessage.
1935
+ *
1936
+ * The user should also note that unsuppressing warning or information messages with unsuppressmessage
1937
+ * just reverts the effects of the suppressmessage command but that other conditions
1938
+ * exist that affect the actual displaying of a message, such as global verbosity (see verbosity) and
1939
+ * modes like rounding warnings (see roundingwarnings). A message will not just get displayed
1940
+ * because it was unsuppressed with unsuppressmessage.
1941
+ *
1942
+ * When unsuppressmessage is used on message numbers that do not exist in the current version
1943
+ * of the tool, a warning is displayed. The call has no other effect though.
1944
+ *
1945
+ * @return [nil]
1946
+ * @overload unsupressmessage(msg_num_1, ..., msg_num_n)
1947
+ * @param msg_num_1 [Integer]
1948
+ * @overload unsupressmessage(msg_list)
1949
+ * @param msg_list [List<Integer>]
1950
+ */
1951
+ static VALUE sollyarb_unsuppressmessage(int argc, VALUE *argv, VALUE self)
1952
+ {
1953
+ SOLLYARB_FUNC_VA_1(sollya_lib_unsuppressmessage);
1954
+ }
1955
+
1956
+
1957
+ /* Implements a constant in arbitrary precision
1958
+ *
1959
+ * The command _implementconstant_ implements the constant expression `expr` in arbitrary precision.
1960
+ * More precisely, it generates the source code (written in C, and using MPFR) of a C function
1961
+ * const_something with the following signature:
1962
+ * `void const_something (mpfr_ptr y, mp_prec_t prec)`
1963
+ * Let us denote by 𝑐 the exact mathematical value of the constant defined by the expression `expr`.
1964
+ * When called with arguments 𝑦 and prec (where the variable 𝑦 is supposed to be already initialized),
1965
+ * the function mpfr_const_something sets the precision of 𝑦 to a suitable precision and stores in it
1966
+ * an approximate value of 𝑐 such that
1967
+ * |𝑦 − 𝑐| ≤ |𝑐| 21−prec .
1968
+ *
1969
+ * When no filename `filename` is given or if `:default` is given as `filename`, the source code produced by
1970
+ * implementconstant is printed on standard output. Otherwise, when `filename` is given as a string
1971
+ * of characters, the source code is output to a file named `filename`. If that file cannot be opened
1972
+ * and/or written to, implementconstant fails and has no other effect.
1973
+ * 121• When `functionname` is given as an argument to implementconstant and `functionname` evaluates
1974
+ * to a string of characters, the default name for the C function const_something is replaced by
1975
+ * `functionname`. When `:default` is given as `functionname`, the default name is used nevertheless, as
1976
+ * if no `functionname` argument were given. When choosing a character sequence for `functionname`,
1977
+ * the user should keep attention to the fact that `functionname` must be a valid C identifier in order
1978
+ * to enable error-free compilation of the produced code.
1979
+ *
1980
+ * If `expr` refers to a constant defined with libraryconstant, the produced code uses the external
1981
+ * code implementing this constant. The user should keep in mind that it is up to them to make sure
1982
+ * the symbol for that external code can get resolved when the newly generated code is to be loaded.
1983
+ *
1984
+ * If a subexpression of `expr` evaluates to 0, implementconstant will most likely fail with an error
1985
+ * message.
1986
+ *
1987
+ * implementconstant is unable to implement constant expressions `expr` that contain procedurebased
1988
+ * functions, i.e. functions created from Sollya procedures using the function construct. If
1989
+ * `expr` contains such a procedure-based function, implementconstant prints a warning and fails
1990
+ * silently. The reason for this lack of functionality is that the produced C source code, which is
1991
+ * supposed to be compiled, would have to call back to the Sollya interpreter in order to evaluate
1992
+ * the procedure-based function.
1993
+ *
1994
+ * Similarly, implementconstant is currently unable to implement constant expressions `expr` that
1995
+ * contain library-based functions, i.e. functions dynamically bound to Sollya using the library
1996
+ * construct. If `expr` contains such a library-based function, implementconstant prints a warning
1997
+ * and fails silently. Support for this feature is in principle feasible from a technical standpoint and
1998
+ * might be added in a future release of Sollya.
1999
+ *
2000
+ * Currently, non-differentiable functions such as {double}, {doubledouble}, {tripledouble}, {single},
2001
+ * {halfprecision}, {quad}, {doubleextended}, {floor}, {ceil}, {nearestint} are not supported by implementconstant.
2002
+ * If implementconstant encounters one of them, a warning message is displayed
2003
+ * and no code is produced. However, if {autosimplify} equals `true`, it is possible that Sollya silently
2004
+ * simplifies subexpressions of `expr` containing such functions and that implementconstant successfully
2005
+ * produces code for evaluating `expr`.
2006
+ *
2007
+ * While it produces an MPFR-based C source code for `expr`, implementconstant takes architectural
2008
+ * and system-dependent parameters into account. For example, it checks whether literal constants
2009
+ * figuring in `expr` can be represented on a C long int type or if they must be stored in a different
2010
+ * manner not to affect their accuracy. These tests, performed by Sollya during execution of implementconstant,
2011
+ * depend themselves on the architecture Sollya is running on. Users should keep
2012
+ * this matter in mind, especially when trying to compile source code on one machine whilst it has
2013
+ * been produced on another.
2014
+ *
2015
+ * @return [nil]
2016
+ * @overload implementconstant(expr, filename = nil, functionname = nil)
2017
+ * @param expr [Function]
2018
+ * @param filename [String, nil]
2019
+ * @param functionname [String, nil]
2020
+ */
2021
+ static VALUE sollyarb_implementconstant(int argc, VALUE *argv, VALUE self)
2022
+ {
2023
+ SOLLYARB_FUNC_VA_1(sollya_lib_implementconstant);
2024
+ }
2025
+
2026
+
2027
+ /* Computes a good polynomial approximation with fixed-point or floating-point coefficients
2028
+ *
2029
+ * _fpminimax_ uses a heuristic (but practically efficient) method to find a good polynomial approximation
2030
+ * of a function `f` on an interval `range`. It implements the method published in the article:
2031
+ * _Efficient polynomial 𝐿∞ -approximations, Nicolas Brisebarre and Sylvain Chevillard, Proceedings of the 18th IEEE Symposium on Computer Arithmetic (ARITH 18), pp. 169-176_.
2032
+ *
2033
+ * The basic usage of this command is `fpminimax(f, n, formats, range)`. It computes a polynomial
2034
+ * approximation of `𝑓` with degree at most `𝑛` on the interval `range`. `formats` is a list of integers or
2035
+ * format types (such as `:double`, `:doubledouble`, etc.). The polynomial returned by the command
2036
+ * has its coefficients that fit the formats indications. For instance, if formats[0] is 35, the coefficient
2037
+ * of degree 0 of the polynomial will fit a floating-point format of 35 bits. If formats[1] is `:double`, the
2038
+ * coefficient of degree 1 will be representable by a floating-point number with a precision of 53 bits
2039
+ * (which is not necessarily an IEEE 754 double precision number. See the remark below), etc.
2040
+ *
2041
+ * The second argument may be either an integer, a list of integers or a list of functions. An integer
2042
+ * indicates the degree of the desired polynomial approximation. A list of integers indicates the list of
2043
+ * desired monomials. For instance, the list `[0, 2, 4, 6]` indicates that the polynomial must be even
2044
+ * and of degree at most 6. Giving an integer 𝑛 as second argument is equivalent as giving [0, 1, ..., 𝑛].
2045
+ * Finally, a list of function _𝑔𝑘_ indicates that the desired approximation must be a linear combination of the _𝑔𝑘_.
2046
+ * The list of formats is interpreted with respect to the list of monomials. For instance, if the list of
2047
+ * monomials is [0, 2, 4, 6] and the list of formats is [161, 107, 53, 24], the coefficients of degree 0
2048
+ * is searched as a floating-point number with precision 161, the coefficient of degree 2 is searched as
2049
+ * a number of precision 107, and so on.
2050
+ *
2051
+ * The floating-point coefficients considered by fpminimax do not have an exponent range. In
2052
+ * particular, in the format list, `:double` is an exact synonym for 53. Currently, fpminimax only
2053
+ * ensures that the corresponding coefficient has at most 53 bits of mantissa. It does not imply that
2054
+ * it is an IEEE-754 double.
2055
+ *
2056
+ * By default, the list of formats is interpreted as a list of floating-point formats. This may be changed
2057
+ * by passing `:fixed` for `indic2`.
2058
+ * For example: `fpminimax(𝑓 , 2, [25, 18, 30], (0..10, :fixed)`. In this case, _fpminimax_ will search
2059
+ * for a polynomial of degree 2 with a constant coefficient of the form `𝑚/2^25` where _𝑚_ is an integer. In
2060
+ * other words, it is a fixed-point number with 25 bits after the point.
2061
+ *
2062
+ * For more documentation on fpminimax, see the official [Sollya documentation](https://www.sollya.org/sollya-8.0/help.php?name=fpminimax).
2063
+ *
2064
+ * @return [Function] polynomial approximation
2065
+ * @overload fpminimax(f, n | monomials, formats, range | lst, opterror = :relative, coefformat = :floating, indic3 = nil, p | lcoeffs = nil)
2066
+ * @param f [Function] the function to be approximated
2067
+ * @param n [Integer] the degree of the polynomial that must approximate _f_
2068
+ * @param monomials [List<Integer,Function>] a list of integers or a list of function. It indicates the basis for the approximation of _f_
2069
+ * @param formats [List<Integer,Constant>] a list indicating the formats that the coefficients of the polynomial must have
2070
+ * @param range [Range] the interval where the function must be approximated
2071
+ * @param lst [List] list of interpolation points used by the method
2072
+ * @param opterror [Symbol, nil] the error to be optimized, `:absolute` or `:relative`
2073
+ * @param coefformat [Symbol, nil] formats of the coefficients, `:fixed` or `:floating`
2074
+ * @param indic2 [Symbol, nil] `:absolute` or `:relative`
2075
+ * @param p [Function, nil] the minimax polynomial to be considered for solving the problem.
2076
+ * @param lcoeffs [List, nil] a list containing the coefficients of the minimax polynomial to be considered for solving the problem.
2077
+ * @see supnorm
2078
+ */
2079
+ static VALUE sollyarb_fpminimax(int argc, VALUE *argv, VALUE self)
2080
+ {
2081
+ SOLLYARB_PROC_VA_4(sollya_lib_fpminimax);
2082
+ }
2083
+
2084
+
2085
+ /* Computes an interval bounding the supremum norm of an approximation error (absolute or relative) between a given polynomial
2086
+ * and a function.
2087
+ *
2088
+ * `supnorm(p, f, I, errorType, accuracy)` tries to compute an interval bound r=[l,u] for the supremum norm of
2089
+ * the error function epsilon_absolute=p-f (when errorType evaluates to `:absolute`) or
2090
+ * epsilon_relative=p/f-1 (when errorType evaluates to `:relative`), over the interval I, such that
2091
+ * `sup{|epsilon(x)|, x in I} C r` and `0 < |u/l-1| < accuracy`.
2092
+ * If supnorm succeeds in computing a suitable interval _r_, which it returns, that interval is guaranteed to
2093
+ * contain the supremum norm value and to satisfy the required quality. Otherwise, supnorm evaluates to error,
2094
+ * displaying a corresponding error message.
2095
+ * These failure cases are rare and basically happen only for functions which are too complicated.
2096
+ *
2097
+ * Roughly speaking, supnorm is based on {taylorform} to obtain a higher degree polynomial approximation for _f_.
2098
+ * This process is coupled with an a posteriori validation of a potential supremum norm upper bound.
2099
+ * The validation is based on showing a certain polynomial the problem gets reduced to does not vanish.
2100
+ * In cases when this process alone does not succeed, for instance because taylorform is unable to compute a sufficiently
2101
+ * good approximation to f, supnorm falls back to bisecting the working interval until safe supremum norm bounds
2102
+ * can be computed with the required accuracy or until the width of the subintervals becomes less than {diam} times
2103
+ * the original interval I, in which case supnorm fails.
2104
+ *
2105
+ * The algorithm used for supnorm is quite complex, which makes it impossible to explain it here in further detail.
2106
+ * Please find a complete description in the following article:
2107
+ * _Sylvain Chevillard, John Harrison, Mioara Joldes, Christoph Lauter, Efficient and accurate computation of upper bounds of approximation errors, Journal of Theoretical Computer Science (TCS), 2010, LIP Research Report number RR LIP2010-2_,
2108
+ * <http://prunel.ccsd.cnrs.fr/ensl-00445343/fr/>
2109
+ *
2110
+ * In practical cases, supnorm should be able to automatically handle removable discontinuities that relative errors might have.
2111
+ * This means that usually, if f vanishes at a point x0 in the interval considered,
2112
+ * the approximation polynomial p is designed such that it also vanishes at the same point with a multiplicity large enough.
2113
+ * Hence, although f vanishes, epsilon_relative=p/f-1 may be defined by continuous extension at such points x0,
2114
+ * called removable discontinuities.
2115
+ *
2116
+ * For more documentation on fpminimax, see the official [Sollya documentation](https://www.sollya.org/sollya-8.0/help.php?name=supnorm).
2117
+ *
2118
+ * @param polynom [Function] a polynomial
2119
+ * @param func [Function] a function
2120
+ * @param itvl [Range] an interval
2121
+ * @param etype [Symbol] the type of error to be considered: `:absolute` or `:relative`
2122
+ * @param accuracy [Numeric] a constant that controls the relative tightness of the interval returned.
2123
+ * @return [Range]
2124
+ */
2125
+ static VALUE sollyarb_supnorm(VALUE self, VALUE polynom, VALUE func, VALUE itvl, VALUE etype, VALUE accuracy)
2126
+ {
2127
+ sollya_obj_t r = sollya_lib_supnorm(
2128
+ SOLLYARB_TO_SOLLYA(polynom),
2129
+ SOLLYARB_TO_SOLLYA(func),
2130
+ SOLLYARB_TO_SOLLYA(itvl),
2131
+ SOLLYARB_TO_SOLLYA(etype),
2132
+ SOLLYARB_TO_SOLLYA(accuracy));
2133
+ return sollyarb_autowrap_object(r);
2134
+ }
2135
+
2136
+
2137
+ static VALUE sollyarb_infnorm(int argc, VALUE *argv, VALUE self)
2138
+ {
2139
+ SOLLYARB_PROC_VA_2(sollya_lib_infnorm);
2140
+ }
2141
+
2142
+ static VALUE sollyarb_dirtyinfnorm(VALUE self, VALUE func, VALUE range)
2143
+ {
2144
+ return sollyarb_autowrap_object(sollya_lib_dirtyinfnorm(SOLLYARB_TO_SOLLYA(func), SOLLYARB_TO_SOLLYA(range)));
2145
+ }
2146
+
2147
+ static VALUE sollyarb_remez(int argc, VALUE *argv, VALUE self)
2148
+ {
2149
+ SOLLYARB_PROC_VA_3(sollya_lib_remez);
2150
+ }
2151
+
2152
+ static VALUE sollyarb_taylorform(int argc, VALUE *argv, VALUE self)
2153
+ {
2154
+ SOLLYARB_PROC_VA_3(sollya_lib_taylorform);
2155
+ }
2156
+
2157
+
2158
+ /* Universal name for the mathematical free variable.
2159
+ * Sollya manipulates mathematical functions of a single variable.
2160
+ * @return [Function]
2161
+ */
2162
+ static VALUE sollyarb_free_variable(VALUE self)
2163
+ {
2164
+ (void)self;
2165
+ return sollyarb_autowrap_object(sollya_lib_free_variable());
2166
+ }
2167
+
2168
+
2169
+ static VALUE sollyarb_object_and(VALUE self, VALUE other)
2170
+ {
2171
+ return sollyarb_autowrap_object(sollya_lib_and(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
2172
+ }
2173
+
2174
+
2175
+ static VALUE sollyarb_object_or(VALUE self, VALUE other)
2176
+ {
2177
+ return sollyarb_autowrap_object(sollya_lib_or(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
2178
+ }
2179
+
2180
+
2181
+ static VALUE sollyarb_object_negate(VALUE self)
2182
+ {
2183
+ return sollyarb_autowrap_object(sollya_lib_negate(sollyarb_object_rb2ref(self)));
2184
+ }
2185
+
2186
+
2187
+ static VALUE sollyarb_object_in(VALUE self, VALUE range)
2188
+ {
2189
+ return sollyarb_autowrap_object(sollya_lib_negate(sollyarb_object_rb2ref(self)));
2190
+ }
2191
+
2192
+
2193
+ static VALUE sollyarb_object_add(VALUE self, VALUE other)
2194
+ {
2195
+ return sollyarb_autowrap_object(sollya_lib_add(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
2196
+ }
2197
+
2198
+
2199
+ static VALUE sollyarb_object_sub(VALUE self, VALUE other)
2200
+ {
2201
+ return sollyarb_autowrap_object(sollya_lib_sub(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
2202
+ }
2203
+
2204
+
2205
+ static VALUE sollyarb_object_mul(VALUE self, VALUE other)
2206
+ {
2207
+ return sollyarb_autowrap_object(sollya_lib_mul(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
2208
+ }
2209
+
2210
+
2211
+ static VALUE sollyarb_object_div(VALUE self, VALUE other)
2212
+ {
2213
+ return sollyarb_autowrap_object(sollya_lib_div(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
2214
+ }
2215
+
2216
+
2217
+ static VALUE sollyarb_object_pow(VALUE self, VALUE other)
2218
+ {
2219
+ return sollyarb_autowrap_object(sollya_lib_pow(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
2220
+ }
2221
+
2222
+
2223
+ static VALUE sollyarb_object_neg(VALUE self)
2224
+ {
2225
+ return sollyarb_autowrap_object(sollya_lib_neg(sollyarb_object_rb2ref(self)));
2226
+ }
2227
+
2228
+
2229
+ /* @return [Sollya::Object]
2230
+ */
2231
+ static VALUE sollyarb_range_inf(VALUE self)
2232
+ {
2233
+ return sollyarb_autowrap_object(sollya_lib_inf(sollyarb_object_rb2ref(self)));
2234
+ }
2235
+
2236
+
2237
+ /* @return [Sollya::Object]
2238
+ */
2239
+ static VALUE sollyarb_range_sup(VALUE self)
2240
+ {
2241
+ return sollyarb_autowrap_object(sollya_lib_sup(sollyarb_object_rb2ref(self)));
2242
+ }
2243
+
2244
+
2245
+ static VALUE sollyarb_object_concat(VALUE self, VALUE other)
2246
+ {
2247
+ return sollyarb_autowrap_object(sollya_lib_concat(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
2248
+ }
2249
+
2250
+
2251
+ static VALUE sollyarb_list_append(VALUE self, VALUE other)
2252
+ {
2253
+ return sollyarb_autowrap_object(sollya_lib_append(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
2254
+ }
2255
+
2256
+
2257
+ static VALUE sollyarb_list_prepend(VALUE self, VALUE other)
2258
+ {
2259
+ return sollyarb_autowrap_object(sollya_lib_prepend(SOLLYARB_TO_SOLLYA(other), sollyarb_object_rb2ref(self)));
2260
+ }
2261
+
2262
+
2263
+ static VALUE sollyarb_exp(VALUE self, VALUE v) {
2264
+ return sollyarb_autowrap_object(sollya_lib_exp(SOLLYARB_TO_SOLLYA(v)));
2265
+ }
2266
+
2267
+ static VALUE sollyarb_log(VALUE self, VALUE v) {
2268
+ return sollyarb_autowrap_object(sollya_lib_log(SOLLYARB_TO_SOLLYA(v)));
2269
+ }
2270
+
2271
+ static VALUE sollyarb_log2(VALUE self, VALUE v) {
2272
+ return sollyarb_autowrap_object(sollya_lib_log2(SOLLYARB_TO_SOLLYA(v)));
2273
+ }
2274
+
2275
+ static VALUE sollyarb_log10(VALUE self, VALUE v) {
2276
+ return sollyarb_autowrap_object(sollya_lib_log10(SOLLYARB_TO_SOLLYA(v)));
2277
+ }
2278
+
2279
+ static VALUE sollyarb_sqrt(VALUE self, VALUE v) {
2280
+ return sollyarb_autowrap_object(sollya_lib_sqrt(SOLLYARB_TO_SOLLYA(v)));
2281
+ }
2282
+
2283
+ static VALUE sollyarb_sin(VALUE self, VALUE v) {
2284
+ return sollyarb_autowrap_object(sollya_lib_sin(SOLLYARB_TO_SOLLYA(v)));
2285
+ }
2286
+
2287
+ static VALUE sollyarb_cos(VALUE self, VALUE v) {
2288
+ return sollyarb_autowrap_object(sollya_lib_cos(SOLLYARB_TO_SOLLYA(v)));
2289
+ }
2290
+
2291
+ static VALUE sollyarb_tan(VALUE self, VALUE v) {
2292
+ return sollyarb_autowrap_object(sollya_lib_tan(SOLLYARB_TO_SOLLYA(v)));
2293
+ }
2294
+
2295
+ static VALUE sollyarb_asin(VALUE self, VALUE v) {
2296
+ return sollyarb_autowrap_object(sollya_lib_asin(SOLLYARB_TO_SOLLYA(v)));
2297
+ }
2298
+
2299
+ static VALUE sollyarb_acos(VALUE self, VALUE v) {
2300
+ return sollyarb_autowrap_object(sollya_lib_acos(SOLLYARB_TO_SOLLYA(v)));
2301
+ }
2302
+
2303
+ static VALUE sollyarb_atan(VALUE self, VALUE v) {
2304
+ return sollyarb_autowrap_object(sollya_lib_atan(SOLLYARB_TO_SOLLYA(v)));
2305
+ }
2306
+
2307
+ static VALUE sollyarb_sinh(VALUE self, VALUE v) {
2308
+ return sollyarb_autowrap_object(sollya_lib_sinh(SOLLYARB_TO_SOLLYA(v)));
2309
+ }
2310
+
2311
+ static VALUE sollyarb_cosh(VALUE self, VALUE v) {
2312
+ return sollyarb_autowrap_object(sollya_lib_cosh(SOLLYARB_TO_SOLLYA(v)));
2313
+ }
2314
+
2315
+ static VALUE sollyarb_tanh(VALUE self, VALUE v) {
2316
+ return sollyarb_autowrap_object(sollya_lib_tanh(SOLLYARB_TO_SOLLYA(v)));
2317
+ }
2318
+
2319
+ static VALUE sollyarb_asinh(VALUE self, VALUE v) {
2320
+ return sollyarb_autowrap_object(sollya_lib_asinh(SOLLYARB_TO_SOLLYA(v)));
2321
+ }
2322
+
2323
+ static VALUE sollyarb_acosh(VALUE self, VALUE v) {
2324
+ return sollyarb_autowrap_object(sollya_lib_acosh(SOLLYARB_TO_SOLLYA(v)));
2325
+ }
2326
+
2327
+ static VALUE sollyarb_atanh(VALUE self, VALUE v) {
2328
+ return sollyarb_autowrap_object(sollya_lib_atanh(SOLLYARB_TO_SOLLYA(v)));
2329
+ }
2330
+
2331
+ static VALUE sollyarb_abs(VALUE self, VALUE v) {
2332
+ return sollyarb_autowrap_object(sollya_lib_abs(SOLLYARB_TO_SOLLYA(v)));
2333
+ }
2334
+
2335
+ static VALUE sollyarb_erf(VALUE self, VALUE v) {
2336
+ return sollyarb_autowrap_object(sollya_lib_erf(SOLLYARB_TO_SOLLYA(v)));
2337
+ }
2338
+
2339
+ static VALUE sollyarb_erfc(VALUE self, VALUE v) {
2340
+ return sollyarb_autowrap_object(sollya_lib_erfc(SOLLYARB_TO_SOLLYA(v)));
2341
+ }
2342
+
2343
+ static VALUE sollyarb_log1p(VALUE self, VALUE v) {
2344
+ return sollyarb_autowrap_object(sollya_lib_log1p(SOLLYARB_TO_SOLLYA(v)));
2345
+ }
2346
+
2347
+ static VALUE sollyarb_expm1(VALUE self, VALUE v) {
2348
+ return sollyarb_autowrap_object(sollya_lib_expm1(SOLLYARB_TO_SOLLYA(v)));
2349
+ }
2350
+
2351
+ static VALUE sollyarb_double(VALUE self, VALUE v) {
2352
+ return sollyarb_autowrap_object(sollya_lib_double(SOLLYARB_TO_SOLLYA(v)));
2353
+ }
2354
+
2355
+ static VALUE sollyarb_single(VALUE self, VALUE v) {
2356
+ return sollyarb_autowrap_object(sollya_lib_single(SOLLYARB_TO_SOLLYA(v)));
2357
+ }
2358
+
2359
+ static VALUE sollyarb_quad(VALUE self, VALUE v) {
2360
+ return sollyarb_autowrap_object(sollya_lib_quad(SOLLYARB_TO_SOLLYA(v)));
2361
+ }
2362
+
2363
+ static VALUE sollyarb_halfprecision(VALUE self, VALUE v) {
2364
+ return sollyarb_autowrap_object(sollya_lib_halfprecision(SOLLYARB_TO_SOLLYA(v)));
2365
+ }
2366
+
2367
+ static VALUE sollyarb_double_double(VALUE self, VALUE v) {
2368
+ return sollyarb_autowrap_object(sollya_lib_double_double(SOLLYARB_TO_SOLLYA(v)));
2369
+ }
2370
+
2371
+ static VALUE sollyarb_triple_double(VALUE self, VALUE v) {
2372
+ return sollyarb_autowrap_object(sollya_lib_triple_double(SOLLYARB_TO_SOLLYA(v)));
2373
+ }
2374
+
2375
+ static VALUE sollyarb_doubleextended(VALUE self, VALUE v) {
2376
+ return sollyarb_autowrap_object(sollya_lib_doubleextended(SOLLYARB_TO_SOLLYA(v)));
2377
+ }
2378
+
2379
+ static VALUE sollyarb_ceil(VALUE self, VALUE v) {
2380
+ return sollyarb_autowrap_object(sollya_lib_ceil(SOLLYARB_TO_SOLLYA(v)));
2381
+ }
2382
+
2383
+ static VALUE sollyarb_floor(VALUE self, VALUE v) {
2384
+ return sollyarb_autowrap_object(sollya_lib_floor(SOLLYARB_TO_SOLLYA(v)));
2385
+ }
2386
+
2387
+ static VALUE sollyarb_nearestint(VALUE self, VALUE v) {
2388
+ return sollyarb_autowrap_object(sollya_lib_nearestint(SOLLYARB_TO_SOLLYA(v)));
2389
+ }
2390
+
2391
+
2392
+ static VALUE sollyarb_function_abs(VALUE self) {
2393
+ return sollyarb_autowrap_object(sollya_lib_abs(sollyarb_object_rb2ref(self)));
2394
+ }
2395
+
2396
+ static VALUE sollyarb_function_ceil(VALUE self) {
2397
+ return sollyarb_autowrap_object(sollya_lib_ceil(sollyarb_object_rb2ref(self)));
2398
+ }
2399
+
2400
+ static VALUE sollyarb_function_floor(VALUE self) {
2401
+ return sollyarb_autowrap_object(sollya_lib_floor(sollyarb_object_rb2ref(self)));
2402
+ }
2403
+
2404
+ static VALUE sollyarb_function_nearestint(VALUE self) {
2405
+ return sollyarb_autowrap_object(sollya_lib_nearestint(sollyarb_object_rb2ref(self)));
2406
+ }
2407
+
2408
+ static VALUE sollyarb_apply(int argc, VALUE *argv, VALUE self) {
2409
+ SOLLYARB_PROC_VA_1(sollya_lib_apply);
2410
+ }
2411
+
2412
+ /* Computes an interpolation polynomial.
2413
+ * @return [Function]
2414
+ */
2415
+ static VALUE sollyarb_interpolate(int argc, VALUE *argv, VALUE self) {
2416
+ SOLLYARB_PROC_VA_2(sollya_lib_interpolate);
2417
+ }
2418
+
2419
+ static VALUE sollyarb_getbacktrace(VALUE self) {
2420
+ return sollyarb_autowrap_object(sollya_lib_getbacktrace());
2421
+ }
2422
+
2423
+
2424
+ static VALUE sollyarb_function_numerator(VALUE self) {
2425
+ return sollyarb_autowrap_object(sollya_lib_numerator(sollyarb_object_rb2ref(self)));
2426
+ }
2427
+
2428
+ static VALUE sollyarb_function_denominator(VALUE self) {
2429
+ return sollyarb_autowrap_object(sollya_lib_denominator(sollyarb_object_rb2ref(self)));
2430
+ }
2431
+
2432
+ /* @overload apply_at(x, prec: prec)
2433
+ * @param x [MPFR, Float] point at which to evaluate the function
2434
+ * @param prec [Integer] precision
2435
+ * @return [MPFR]
2436
+ * @overload apply_at(x)
2437
+ * @param x [Sollya::Object]
2438
+ * @return [Sollya::Object]
2439
+ */
2440
+ static VALUE sollyarb_function_apply_at(int argc, VALUE *argv, VALUE self) {
2441
+ VALUE v;
2442
+ VALUE kw;
2443
+ const ID kwkeys[1] = {id_prec};
2444
+ VALUE kwvalues[1] = {Qundef};
2445
+ mpfr_prec_t prec = -1;
2446
+ rb_scan_args(argc, argv, "1:", &v, &kw);
2447
+ if (!NIL_P(kw)) {
2448
+ rb_get_kwargs(kw, kwkeys, 0, 1, kwvalues);
2449
+ if (kwvalues[0] != Qundef) {
2450
+ prec = NUM2LL(kwvalues[0]);
2451
+ }
2452
+ }
2453
+ if (prec <= 0) {
2454
+ sollya_obj_t p = sollya_lib_get_prec();
2455
+ sollya_lib_get_constant_as_int64(&prec, p);
2456
+ sollya_lib_clear_obj(p);
2457
+ }
2458
+
2459
+ if (RB_FLOAT_TYPE_P(v)) {
2460
+ mpfr_t mp;
2461
+ mpfr_init2(mp, 53);
2462
+ mpfr_set_d(mp, NUM2DBL(v), MPFR_RNDN);
2463
+
2464
+ VALUE rbres = mpfrrb_alloc(c_MPFR);
2465
+ mpfr_ptr mpr = mpfrrb_rb2ref_ext(rbres);
2466
+ mpfr_init2(mpr, prec);
2467
+
2468
+ sollya_lib_evaluate_function_at_point(mpr, sollyarb_object_rb2ref(self), mp, NULL);
2469
+
2470
+ mpfr_clear(mp);
2471
+ return rbres;
2472
+ } else if (rb_obj_is_kind_of(v, c_MPFR)) {
2473
+ mpfr_ptr mp = mpfrrb_rb2ref_ext(v);
2474
+
2475
+ VALUE rbres = mpfrrb_alloc(c_MPFR);
2476
+ mpfr_ptr mpr = mpfrrb_rb2ref_ext(rbres);
2477
+ mpfr_init2(mpr, prec);
2478
+
2479
+ sollya_lib_evaluate_function_at_point(mpr, sollyarb_object_rb2ref(self), mp, NULL);
2480
+
2481
+ return rbres;
2482
+ } else {
2483
+ return sollyarb_autowrap_object(sollya_lib_apply(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(v), NULL));
2484
+ }
2485
+ }
2486
+
2487
+ static VALUE sollyarb_approx(VALUE self, VALUE v) {
2488
+ return sollyarb_autowrap_object(sollya_lib_approx(SOLLYARB_TO_SOLLYA(v)));
2489
+ }
2490
+
2491
+ /* Returns the middle of _self_.
2492
+ * If the middle is not exactly representable at the current precision, the value is returned as an unevaluated expression.
2493
+ * @return [Sollya::Object]
2494
+ */
2495
+ static VALUE sollyarb_range_mid(VALUE self) {
2496
+ return sollyarb_autowrap_object(sollya_lib_mid(sollyarb_object_rb2ref(self)));
2497
+ }
2498
+
2499
+ /* Differentiation operator.
2500
+ * Returns the symbolic derivative of the function _self_ by the global free variable.
2501
+ * If _self_ represents a function symbol that is externally bound to some code by library, the
2502
+ * derivative is performed as a symbolic annotation to the returned expression tree.
2503
+ * @return [Function]
2504
+ */
2505
+ static VALUE sollyarb_function_diff(VALUE self) {
2506
+ return sollyarb_autowrap_object(sollya_lib_diff(sollyarb_object_rb2ref(self)));
2507
+ }
2508
+
2509
+ /* Brings all polynomial subexpressions of _self_ to Horner form.
2510
+ *
2511
+ * This method rewrites the expression representing the function _self_ in a way such that
2512
+ * all polynomial subexpressions (or the whole expression itself, if it is a polynomial) are written in
2513
+ * Horner form. The command horner does not endanger the safety of computations even in Sollya's
2514
+ * floating-point environment: the function returned is mathematically equal to _self_.
2515
+ * @return [Function]
2516
+ */
2517
+ static VALUE sollyarb_function_horner(VALUE self) {
2518
+ return sollyarb_autowrap_object(sollya_lib_horner(sollyarb_object_rb2ref(self)));
2519
+ }
2520
+
2521
+ /* Expands polynomial subexpressiosns.
2522
+ * Expands all polynomial subexpressions in function _self_ as far as possible.
2523
+ * Factors of sums are multiplied out, power operators with constant positive integer exponents are
2524
+ * replaced by multiplications.
2525
+ * @return [Function]
2526
+ */
2527
+ static VALUE sollyarb_function_expand(VALUE self) {
2528
+ return sollyarb_autowrap_object(sollya_lib_expand(sollyarb_object_rb2ref(self)));
2529
+ }
2530
+
2531
+ /* Simplifies an expression representing a function.
2532
+ * It does not endanger the safety of computations even in Sollya's
2533
+ * floating-point environment: the function returned is mathematically equal to _self_.
2534
+ * Remark that the simplification provided by simplify is not perfect: they may exist simpler equivalent
2535
+ * expressions for expressions returned by simplify.
2536
+ * @return [Function]
2537
+ */
2538
+ static VALUE sollyarb_function_simplify(VALUE self) {
2539
+ return sollyarb_autowrap_object(sollya_lib_simplify(sollyarb_object_rb2ref(self)));
2540
+ }
2541
+
2542
+ /* Simplifies constant subexpressions of _self_
2543
+ * Those constant subexpressions are evaluated using floating-point arithmetic with the global precision {prec}.
2544
+ * @return [Function]
2545
+ */
2546
+ static VALUE sollyarb_function_dirtysimplify(VALUE self)
2547
+ {
2548
+ return sollyarb_autowrap_object(sollya_lib_dirtysimplify(sollyarb_object_rb2ref(self)));
2549
+ }
2550
+
2551
+ /* Returns the degree of the polynomial _self_.
2552
+ * @return [Integer, nil]
2553
+ */
2554
+ static VALUE sollyarb_function_degree(VALUE self) {
2555
+ sollya_obj_t d = sollya_lib_degree(sollyarb_object_rb2ref(self));
2556
+ int r;
2557
+ int s = sollya_lib_get_constant_as_int(&r, d);
2558
+ sollya_lib_clear_obj(d);
2559
+ if (!s || r < 0) return Qnil;
2560
+ return INT2NUM(r);
2561
+ }
2562
+
2563
+ /* Return the Taylor expansion of _self_ in a point.
2564
+ * @param degree [Integer] degree of the expansion to be delivered
2565
+ * @param point [Constant] point in wich the function is to be developed
2566
+ * @return [Function]
2567
+ */
2568
+ static VALUE sollyarb_function_taylor(VALUE self, VALUE degree, VALUE point)
2569
+ {
2570
+ return sollyarb_autowrap_object(sollya_lib_taylor(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(degree), SOLLYARB_TO_SOLLYA(point)));
2571
+ }
2572
+
2573
+ /* Returns the coefficient of dgree `n` of a polynomial.
2574
+ * Returns 0 if _self_ is not a polynomial.
2575
+ * @param n [Integer] coefficient degree
2576
+ * @return [Sollya::Constant]
2577
+ */
2578
+ static VALUE sollyarb_function_coeff(VALUE self, VALUE n) {
2579
+ int i = NUM2INT(n);
2580
+ sollya_obj_t j = sollya_lib_constant_from_int(i);
2581
+ sollya_obj_t r = sollya_lib_coeff(sollyarb_object_rb2ref(self), j);
2582
+ sollya_lib_clear_obj(j);
2583
+ return sollyarb_autowrap_object(r);
2584
+ }
2585
+
2586
+ /* Computes an interval bounding the integral of a function on an interval.
2587
+ *
2588
+ * Returns an interval 𝐽 such that the exact value of the integral of _self_ on I lies in 𝐽.
2589
+ *
2590
+ * This command is safe but very inefficient. Use {dirtyintegral} if you just want an approximate
2591
+ * value.
2592
+ *
2593
+ * The result of this command depends on the global variable {diam}. The method used is the following:
2594
+ * I is cut into intervals of length not greater then 𝛿 · |𝐼| where 𝛿 is the value of global variable {diam}.
2595
+ * On each small interval J, an evaluation of _self_f by interval is performed. The result is multiplied by
2596
+ * the length of J. Finally all values are summed.
2597
+ * @param itvl [Sollya::Range]
2598
+ * @return [Sollya::Range] an interval bounding the integral
2599
+ */
2600
+ static VALUE sollyarb_function_integral(VALUE self, VALUE itvl)
2601
+ {
2602
+ return sollyarb_autowrap_object(sollya_lib_integral(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(itvl)));
2603
+ }
2604
+
2605
+ /* Computes a numerical approximation of the integral of _self_ on an interval.
2606
+ *
2607
+ * The interval must be bound. If the interval contains one of -Inf or +Inf, the result
2608
+ * is NaN, even if the integral has a meaning.
2609
+ *
2610
+ * The result of this command depends on the global variables {prec} and {points}. The method used
2611
+ * is the trapezium rule applied at _𝑛_ evenly distributed points in the interval, where _𝑛_ is the value of
2612
+ * global variable {points}.
2613
+ *
2614
+ * This command computes a numerical approximation of the exact value of the integral. It should
2615
+ * not be used if safety is critical. In this case, use command integral instead.
2616
+ *
2617
+ * Warning: this command is currently known to be unsatisfactory. If you really need to compute
2618
+ * integrals, think of using another tool.
2619
+ *
2620
+ * @param itvl [Sollya::Range]
2621
+ * @return [Sollya::Constant]
2622
+ */
2623
+ static VALUE sollyarb_function_dirtyintegral(VALUE self, VALUE itvl)
2624
+ {
2625
+ return sollyarb_autowrap_object(sollya_lib_dirtyintegral(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(itvl)));
2626
+ }
2627
+
2628
+ /* Computes the number of roots of a polynomial in a given range.
2629
+ *
2630
+ * Rigorously computes the number of roots of polynomial _self_ in the interval `itvl`. The
2631
+ * technique used is Sturm's algorithm. The value returned is not just a numerical estimation of the
2632
+ * number of roots of _self_ in `itvl`: it is the exact number of roots.
2633
+ *
2634
+ * The method {findzeros} computes safe enclosures of all the zeros of a function, without forgetting
2635
+ * any, but it is not guaranteed to separate them all in distinct intervals. _numberroots_ is more
2636
+ * accurate since it guarantees the exact number of roots. However, it does not compute them. It
2637
+ * may be used, for instance, to certify that {findzeros} did not put two distinct roots in the same
2638
+ * interval.
2639
+ *
2640
+ * Multiple roots are counted only once.
2641
+ *
2642
+ * The interval `itvl` must be bounded. The algorithm cannot handle unbounded intervals. Moreover,
2643
+ * the interval is considered as a closed interval: if one (or both) of the endpoints of `itvl` are roots of _self_,
2644
+ * they are counted.
2645
+ *
2646
+ * _self_ can be any expression, but if Sollya fails to prove that it is a polynomial an error
2647
+ * is produced. Also, please note that if the coefficients of _self_ or the endpoints of `itvl` are not exactly
2648
+ * representable, they are first numerically evaluated, before the algorithm is used. In that case, the
2649
+ * counted number of roots corresponds to the rounded polynomial on the rounded interval and not
2650
+ * to the exact parameters given by the user. A warning is displayed to inform the user.
2651
+ *
2652
+ * @param itvl [Sollya::Range]
2653
+ * @return [Integer, nil]
2654
+ */
2655
+ static VALUE sollyarb_function_numberroots(VALUE self, VALUE itvl)
2656
+ {
2657
+ sollya_obj_t r = sollya_lib_numberroots(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(itvl));
2658
+ int64_t i;
2659
+ int s = sollya_lib_get_constant_as_int64(&i, r);
2660
+ sollya_lib_clear_obj(r);
2661
+ if (!s) return Qnil;
2662
+ return LL2NUM(i);
2663
+ }
2664
+
2665
+ /* Returns a list of intervals containing all zeros of _self_ on an interval.
2666
+ *
2667
+ * Returns a list of intervals 𝐼1, ..., 𝐼𝑛 such that, for every zero 𝑧 of _self_ , there exists
2668
+ * some 𝑘 such that 𝑧 ∈ 𝐼𝑘 .
2669
+ *
2670
+ * The list may contain intervals 𝐼𝑘 that do not contain any zero of _self_. An interval Ik may contain
2671
+ * many zeros of _self_.
2672
+ *
2673
+ * This command is meant for cases when safety is critical. If you want to be sure not to forget
2674
+ * any zero, use findzeros. However, if you just want to know numerical values for the zeros of _self_,
2675
+ * dirtyfindzeros should be quite satisfactory and a lot faster.
2676
+ *
2677
+ * If 𝛿 denotes the value of global variable diam, the algorithm ensures that for each 𝑘, |𝐼𝑘| ≤ 𝛿·|𝐼|.
2678
+ *
2679
+ * The algorithm used is basically a bisection algorithm. It is the same algorithm that the one used
2680
+ * for infnorm. See the help page of this command for more details. In short, the behavior of the
2681
+ * algorithm depends on global variables prec, diam, taylorrecursions and hopitalrecursions.
2682
+ *
2683
+ * @param itvl [Sollya::Range]
2684
+ * @return [Sollya::List<Sollya::Range>]
2685
+ * @see dirtyfindzeros
2686
+ */
2687
+ static VALUE sollyarb_function_findzeros(VALUE self, VALUE itvl)
2688
+ {
2689
+ return sollyarb_autowrap_object(sollya_lib_findzeros(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(itvl)));
2690
+ }
2691
+
2692
+ /* Returns a list of numerical values listing the zeros of _self_ on an interval.
2693
+ * @param itvl [Sollya::Range]
2694
+ * @return [Sollya::List<Sollya::Range>]
2695
+ * @see findzeros
2696
+ */
2697
+ static VALUE sollyarb_function_dirtyfindzeros(VALUE self, VALUE itvl)
2698
+ {
2699
+ return sollyarb_autowrap_object(sollya_lib_dirtyfindzeros(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(itvl)));
2700
+ }
2701
+
2702
+ static VALUE sollyarb_function_chebyshevform(VALUE self, VALUE n, VALUE itvl)
2703
+ {
2704
+ return sollyarb_autowrap_object(sollya_lib_chebyshevform(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(n), SOLLYARB_TO_SOLLYA(itvl)));
2705
+ }
2706
+
2707
+ /* Computes the first 𝑛 derivatives of _self_ at a point or over an interval.
2708
+ * @param n [Integer] the order or differentiation
2709
+ * @param itvl [Constant, Range] point or interval over which _self_ is differentiated
2710
+ * @return [List<Function>]
2711
+ */
2712
+ static VALUE sollyarb_function_autodiff(VALUE self, VALUE n, VALUE itvl)
2713
+ {
2714
+ return sollyarb_autowrap_object(sollya_lib_autodiff(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(n), SOLLYARB_TO_SOLLYA(itvl)));
2715
+ }
2716
+
2717
+ /* Evaluates _self_ at a constant point or in a range
2718
+ * @param x [Constant, Range, Function] point or interval over which _self_ is evaluated
2719
+ * @return [Constant, Range, Function]
2720
+ */
2721
+ static VALUE sollyarb_function_evaluate(VALUE self, VALUE x)
2722
+ {
2723
+ return sollyarb_autowrap_object(sollya_lib_evaluate(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(x)));
2724
+ }
2725
+
2726
+ /* Replace the occurrences of the free variable in _self_.
2727
+ * @param g [Function, Constant]
2728
+ * @return [Function, Constant]
2729
+ */
2730
+ static VALUE sollyarb_function_substitute(VALUE self, VALUE g)
2731
+ {
2732
+ return sollyarb_autowrap_object(sollya_lib_substitute(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(g)));
2733
+ }
2734
+
2735
+
2736
+
2737
+
2738
+
2739
+
2740
+
2741
+
2742
+
2743
+ #if 0
2744
+ static int sollyarb_msg_callback(sollya_msg_t msg, void *data)
2745
+ {
2746
+ (void)data;
2747
+ int msg_id = sollya_lib_get_msg_id(msg);
2748
+ char *txt = sollya_lib_msg_to_text(msg);
2749
+ // fprintf(stderr, "\e[31;1m[Sollya]\e[0;91m %s\e[0m\n", txt);
2750
+ fprintf(stderr, "\e[91m[Sollya, %d] %s\e[0m\n", msg_id, txt);
2751
+ // rb_warning("\e[91m[Sollya, %d] %s\e[0m\n", msg_id, txt);
2752
+ // rb_warn("\e[91m[Sollya, %d] %s\e[0m\n", msg_id, txt);
2753
+ sollya_lib_free(txt);
2754
+ return 0;
2755
+ }
2756
+ #endif
2757
+
2758
+
2759
+ static VALUE sollyarb_help_str(VALUE self, VALUE topic_str)
2760
+ {
2761
+ (void)self;
2762
+ Check_Type(topic_str, T_STRING);
2763
+ char *tstr = rb_string_value_cstr(&topic_str);
2764
+ const char *h = sollya_lib_get_help_text(tstr);
2765
+ if (!h) {
2766
+ return Qnil;
2767
+ }
2768
+ return rb_str_new_cstr(h);
2769
+ }
2770
+
2771
+
2772
+ static VALUE sollyarb_help(VALUE self, VALUE topic_str)
2773
+ {
2774
+ (void)self;
2775
+ Check_Type(topic_str, T_STRING);
2776
+ char *tstr = rb_string_value_cstr(&topic_str);
2777
+ const char *h = sollya_lib_get_help_text(tstr);
2778
+ if (!h) {
2779
+ printf("No Sollya help found for topic %s\n", tstr);
2780
+ return Qfalse;
2781
+ }
2782
+ puts(h);
2783
+ return Qtrue;
2784
+ }
2785
+
2786
+
2787
+ static VALUE sollyarb_object_cmp_equal(VALUE self, VALUE other)
2788
+ {
2789
+ sollya_obj_t y = SOLLYARB_TO_SOLLYA(other);
2790
+ sollya_obj_t x = sollyarb_object_rb2ref(self);
2791
+ sollya_obj_t r = sollya_lib_cmp_equal(x, y);
2792
+ VALUE b;
2793
+ if (sollya_lib_is_true(r)) {
2794
+ b = Qtrue;
2795
+ } else if (sollya_lib_is_false(r)) {
2796
+ b = Qfalse;
2797
+ } else {
2798
+ b = Qnil;
2799
+ }
2800
+ sollya_lib_clear_obj(r);
2801
+ return b;
2802
+ }
2803
+
2804
+
2805
+ static VALUE sollyarb_object_cmp_not_equal(VALUE self, VALUE other)
2806
+ {
2807
+ sollya_obj_t y = SOLLYARB_TO_SOLLYA(other);
2808
+ sollya_obj_t x = sollyarb_object_rb2ref(self);
2809
+ sollya_obj_t r = sollya_lib_cmp_not_equal(x, y);
2810
+ VALUE b;
2811
+ if (sollya_lib_is_true(r)) {
2812
+ b = Qtrue;
2813
+ } else if (sollya_lib_is_false(r)) {
2814
+ b = Qfalse;
2815
+ } else {
2816
+ b = Qnil;
2817
+ }
2818
+ sollya_lib_clear_obj(r);
2819
+ return b;
2820
+ }
2821
+
2822
+
2823
+ static VALUE sollyarb_object_cmp_less(VALUE self, VALUE other)
2824
+ {
2825
+ sollya_obj_t y = SOLLYARB_TO_SOLLYA(other);
2826
+ sollya_obj_t x = sollyarb_object_rb2ref(self);
2827
+ sollya_obj_t r = sollya_lib_cmp_less(x, y);
2828
+ VALUE b;
2829
+ if (sollya_lib_is_true(r)) {
2830
+ b = Qtrue;
2831
+ } else if (sollya_lib_is_false(r)) {
2832
+ b = Qfalse;
2833
+ } else {
2834
+ b = Qnil;
2835
+ }
2836
+ sollya_lib_clear_obj(r);
2837
+ if (RB_NIL_P(b)) {
2838
+ rb_raise(rb_eArgError, "comparison of %s with %s failed", rb_obj_classname(self), rb_obj_classname(other));
2839
+ }
2840
+ return b;
2841
+ }
2842
+
2843
+
2844
+ static VALUE sollyarb_object_cmp_greater(VALUE self, VALUE other)
2845
+ {
2846
+ sollya_obj_t y = SOLLYARB_TO_SOLLYA(other);
2847
+ sollya_obj_t x = sollyarb_object_rb2ref(self);
2848
+ sollya_obj_t r = sollya_lib_cmp_greater(x, y);
2849
+ VALUE b;
2850
+ if (sollya_lib_is_true(r)) {
2851
+ b = Qtrue;
2852
+ } else if (sollya_lib_is_false(r)) {
2853
+ b = Qfalse;
2854
+ } else {
2855
+ b = Qnil;
2856
+ }
2857
+ sollya_lib_clear_obj(r);
2858
+ if (RB_NIL_P(b)) {
2859
+ rb_raise(rb_eArgError, "comparison of %s with %s failed", rb_obj_classname(self), rb_obj_classname(other));
2860
+ }
2861
+ return b;
2862
+ }
2863
+
2864
+
2865
+ static VALUE sollyarb_object_cmp_less_equal(VALUE self, VALUE other)
2866
+ {
2867
+ sollya_obj_t y = SOLLYARB_TO_SOLLYA(other);
2868
+ sollya_obj_t x = sollyarb_object_rb2ref(self);
2869
+ sollya_obj_t r = sollya_lib_cmp_less_equal(x, y);
2870
+ VALUE b;
2871
+ if (sollya_lib_is_true(r)) {
2872
+ b = Qtrue;
2873
+ } else if (sollya_lib_is_false(r)) {
2874
+ b = Qfalse;
2875
+ } else {
2876
+ b = Qnil;
2877
+ }
2878
+ sollya_lib_clear_obj(r);
2879
+ if (RB_NIL_P(b)) {
2880
+ rb_raise(rb_eArgError, "comparison of %s with %s failed", rb_obj_classname(self), rb_obj_classname(other));
2881
+ }
2882
+ return b;
2883
+ }
2884
+
2885
+
2886
+ static VALUE sollyarb_object_cmp_greater_equal(VALUE self, VALUE other)
2887
+ {
2888
+ sollya_obj_t y = SOLLYARB_TO_SOLLYA(other);
2889
+ sollya_obj_t x = sollyarb_object_rb2ref(self);
2890
+ sollya_obj_t r = sollya_lib_cmp_greater_equal(x, y);
2891
+ VALUE b;
2892
+ if (sollya_lib_is_true(r)) {
2893
+ b = Qtrue;
2894
+ } else if (sollya_lib_is_false(r)) {
2895
+ b = Qfalse;
2896
+ } else {
2897
+ b = Qnil;
2898
+ }
2899
+ sollya_lib_clear_obj(r);
2900
+ if (RB_NIL_P(b)) {
2901
+ rb_raise(rb_eArgError, "comparison of %s with %s failed", rb_obj_classname(self), rb_obj_classname(other));
2902
+ }
2903
+ return b;
2904
+ }
2905
+
2906
+
2907
+ static VALUE sollyarb_object_coerce(VALUE self, VALUE num)
2908
+ {
2909
+ return rb_ary_new_from_args(2, rb_funcallv(num, id_to_sollya, 0, NULL), self);
2910
+ }
2911
+
2912
+
2913
+ /* @return [Integer, nil]
2914
+ */
2915
+ static VALUE sollyarb_function_arity(VALUE self)
2916
+ {
2917
+ int arity = 0;
2918
+ if (!sollya_lib_get_function_arity(&arity, sollyarb_object_rb2ref(self)) || arity < 1) {
2919
+ return Qnil;
2920
+ }
2921
+ return INT2NUM(arity);
2922
+ }
2923
+
2924
+
2925
+ static VALUE sollyarb_unaryop_get_child(VALUE self)
2926
+ {
2927
+ sollya_obj_t c;
2928
+ if (!sollya_lib_get_nth_subfunction(&c, sollyarb_object_rb2ref(self), 1)) {
2929
+ return Qnil;
2930
+ }
2931
+ return sollyarb_autowrap_object(c);
2932
+ }
2933
+
2934
+ static VALUE sollyarb_binaryop_get_lhs(VALUE self)
2935
+ {
2936
+ sollya_obj_t c;
2937
+ if (!sollya_lib_get_nth_subfunction(&c, sollyarb_object_rb2ref(self), 1)) {
2938
+ return Qnil;
2939
+ }
2940
+ return sollyarb_autowrap_object(c);
2941
+ }
2942
+
2943
+ static VALUE sollyarb_binaryop_get_rhs(VALUE self)
2944
+ {
2945
+ sollya_obj_t c;
2946
+ if (!sollya_lib_get_nth_subfunction(&c, sollyarb_object_rb2ref(self), 2)) {
2947
+ return Qnil;
2948
+ }
2949
+ return sollyarb_autowrap_object(c);
2950
+ }
2951
+
2952
+ static VALUE sollyarb_function_get_nth_child(VALUE self, VALUE n)
2953
+ {
2954
+ int m = NUM2INT(n);
2955
+ sollya_obj_t c;
2956
+ if (!sollya_lib_get_nth_subfunction(&c, sollyarb_object_rb2ref(self), m - 1)) {
2957
+ return Qnil;
2958
+ }
2959
+ if (rb_class_of(self) == c_Freevariable) {
2960
+ return Qnil;
2961
+ }
2962
+ return sollyarb_autowrap_object(c);
2963
+ }
2964
+
2965
+ static VALUE sollyarb_function_get_children(VALUE self)
2966
+ {
2967
+ sollya_obj_t func = sollyarb_object_rb2ref(self);
2968
+ int arity = 1;
2969
+ sollya_lib_get_function_arity(&arity, func);
2970
+ VALUE ar = rb_ary_new_capa(arity);
2971
+ if (rb_class_of(self) == c_Freevariable) {
2972
+ return ar;
2973
+ }
2974
+ sollya_obj_t c;
2975
+ int m = 1;
2976
+ while (sollya_lib_get_nth_subfunction(&c, func, m++)) {
2977
+ rb_ary_push(ar, sollyarb_autowrap_object(c));
2978
+ }
2979
+ return ar;
2980
+ }
2981
+
2982
+
2983
+ /* @return [MPFR]
2984
+ */
2985
+ static VALUE sollyarb_constant_to_mpfr(VALUE self)
2986
+ {
2987
+ sollya_obj_t cst = sollyarb_object_rb2ref(self);
2988
+ mp_prec_t prec = 0;
2989
+ if (!sollya_lib_get_prec_of_constant(&prec, cst)) {
2990
+ sollya_obj_t p = sollya_lib_get_prec();
2991
+ sollya_lib_get_constant_as_int64(&prec, p);
2992
+ sollya_lib_clear_obj(p);
2993
+ }
2994
+ if (!prec) return Qnil;
2995
+ VALUE mprb = mpfrrb_alloc(c_MPFR);
2996
+ mpfr_ptr mp = mpfrrb_rb2ref_ext(mprb);
2997
+ mpfr_init2(mp, prec);
2998
+ if (!sollya_lib_get_constant(mp, cst)) {
2999
+ return Qnil;
3000
+ }
3001
+ return mprb;
3002
+ }
3003
+
3004
+
3005
+ /* @return [Float]
3006
+ */
3007
+ static VALUE sollyarb_constant_to_f(VALUE self)
3008
+ {
3009
+ sollya_obj_t cst = sollyarb_object_rb2ref(self);
3010
+ double d;
3011
+ if (!sollya_lib_get_constant_as_double(&d, cst))
3012
+ return Qnil;
3013
+ return DBL2NUM(d);
3014
+ }
3015
+
3016
+
3017
+ void Init_sollya(void)
3018
+ {
3019
+ Init_mpfr();
3020
+
3021
+ id_to_sollya = rb_intern("to_sollya");
3022
+ id_to_mpfr = rb_intern("to_mpfr");
3023
+ id_to_s = rb_intern("to_s");
3024
+ id_end_elliptic = rb_intern("end_elliptic");
3025
+ id_prec = rb_intern("prec");
3026
+ id_on = rb_intern("on");
3027
+ id_off = rb_intern("off");
3028
+ id_dyadic = rb_intern("dyadic");
3029
+ id_powers = rb_intern("powers");
3030
+ id_binary = rb_intern("binary");
3031
+ id_hexadecimal = rb_intern("hexadecimal");
3032
+ id_file = rb_intern("file");
3033
+ id_postscript = rb_intern("postscript");
3034
+ id_postscriptfile = rb_intern("postscriptfile");
3035
+ id_perturb = rb_intern("perturb");
3036
+ id_RD = rb_intern("RD");
3037
+ id_round_down = rb_intern("round_down");
3038
+ id_RU = rb_intern("RU");
3039
+ id_round_up = rb_intern("round_up");
3040
+ id_RZ = rb_intern("RZ");
3041
+ id_round_towards_zero = rb_intern("round_towards_zero");
3042
+ id_RN = rb_intern("RN");
3043
+ id_round_to_nearest = rb_intern("round_to_nearest");
3044
+ id_honorcoeffprec = rb_intern("honorcoeffprec");
3045
+ id_true = rb_intern("true");
3046
+ id_false = rb_intern("false");
3047
+ id_void = rb_intern("void");
3048
+ id_default = rb_intern("default");
3049
+ id_decimal = rb_intern("decimal");
3050
+ id_absolute = rb_intern("absolute");
3051
+ id_relative = rb_intern("relative");
3052
+ id_fixed = rb_intern("fixed");
3053
+ id_floating = rb_intern("floating");
3054
+ id_error = rb_intern("error");
3055
+ id_D = rb_intern("D");
3056
+ id_double = rb_intern("double");
3057
+ id_SG = rb_intern("SG");
3058
+ id_single = rb_intern("single");
3059
+ id_QD = rb_intern("QD");
3060
+ id_quad = rb_intern("quad");
3061
+ id_HP = rb_intern("HP");
3062
+ id_halfprecision = rb_intern("halfprecision");
3063
+ id_DE = rb_intern("DE");
3064
+ id_doubleextended = rb_intern("doubleextended");
3065
+ id_DD = rb_intern("DD");
3066
+ id_doubledouble = rb_intern("doubledouble");
3067
+ id_TD = rb_intern("TD");
3068
+ id_tripledouble = rb_intern("tripledouble");
3069
+
3070
+
3071
+ m_Sollya = rb_define_module("Sollya");
3072
+
3073
+ rb_define_module_function(m_Sollya, "parse", sollyarb_parse, 1);
3074
+ rb_define_module_function(m_Sollya, "help_str", sollyarb_help_str, 1);
3075
+ rb_define_module_function(m_Sollya, "help", sollyarb_help, 1);
3076
+
3077
+ /* Global variable getters and setters */
3078
+ rb_define_module_function(m_Sollya, "prec", sollyarb_get_prec, 0);
3079
+ rb_define_module_function(m_Sollya, "prec=", sollyarb_set_prec, 1);
3080
+ rb_define_module_function(m_Sollya, "points", sollyarb_get_points, 0);
3081
+ rb_define_module_function(m_Sollya, "points=", sollyarb_set_points, 1);
3082
+ rb_define_module_function(m_Sollya, "diam", sollyarb_get_diam, 0);
3083
+ rb_define_module_function(m_Sollya, "diam=", sollyarb_set_diam, 1);
3084
+ rb_define_module_function(m_Sollya, "display", sollyarb_get_display, 0);
3085
+ rb_define_module_function(m_Sollya, "display=", sollyarb_set_display, 1);
3086
+ rb_define_module_function(m_Sollya, "verbosity", sollyarb_get_verbosity, 0);
3087
+ rb_define_module_function(m_Sollya, "verbosity=", sollyarb_set_verbosity, 1);
3088
+ rb_define_module_function(m_Sollya, "roundingwarnings", sollyarb_get_roundingwarnings, 0);
3089
+ rb_define_module_function(m_Sollya, "roundingwarnings=", sollyarb_set_roundingwarnings, 1);
3090
+ rb_define_module_function(m_Sollya, "autosimplify", sollyarb_get_autosimplify, 0);
3091
+ rb_define_module_function(m_Sollya, "autosimplify=", sollyarb_set_autosimplify, 1);
3092
+ rb_define_module_function(m_Sollya, "fullparentheses", sollyarb_get_fullparentheses, 0);
3093
+ rb_define_module_function(m_Sollya, "fullparentheses=", sollyarb_set_fullparentheses, 1);
3094
+ rb_define_module_function(m_Sollya, "showmessagenumbers", sollyarb_get_showmessagenumbers, 0);
3095
+ rb_define_module_function(m_Sollya, "showmessagenumbers=", sollyarb_set_showmessagenumbers, 1);
3096
+ rb_define_module_function(m_Sollya, "midpointmode", sollyarb_get_midpointmode, 0);
3097
+ rb_define_module_function(m_Sollya, "midpointmode=", sollyarb_set_midpointmode, 1);
3098
+ rb_define_module_function(m_Sollya, "canonical", sollyarb_get_canonical, -1);
3099
+ rb_define_module_function(m_Sollya, "canonical=", sollyarb_set_canonical, 1);
3100
+ rb_define_module_function(m_Sollya, "rationalmode", sollyarb_get_rationalmode, 0);
3101
+ rb_define_module_function(m_Sollya, "rationalmode=", sollyarb_set_rationalmode, 1);
3102
+ rb_define_module_function(m_Sollya, "timing", sollyarb_get_timing, 0);
3103
+ rb_define_module_function(m_Sollya, "timing=", sollyarb_set_timing, 1);
3104
+ rb_define_module_function(m_Sollya, "taylorrecursions", sollyarb_get_taylorrecursions, 0);
3105
+ rb_define_module_function(m_Sollya, "taylorrecursions=", sollyarb_set_taylorrecursions, 1);
3106
+ rb_define_module_function(m_Sollya, "hopitalrecursions", sollyarb_get_hopitalrecursions, 0);
3107
+ rb_define_module_function(m_Sollya, "hopitalrecursions=", sollyarb_set_hopitalrecursions, 1);
3108
+ rb_define_module_function(m_Sollya, "free_variable_name", sollyarb_get_free_variable_name, 0);
3109
+ rb_define_module_function(m_Sollya, "free_variable_name=", sollyarb_set_free_variable_name, 1);
3110
+
3111
+ /* Functions corresponding to Sollya commands */
3112
+ rb_define_module_function(m_Sollya, "plot", sollyarb_plot, -1);
3113
+ rb_define_module_function(m_Sollya, "asciiplot", sollyarb_asciiplot, 2);
3114
+ rb_define_module_function(m_Sollya, "printdouble", sollyarb_printdouble, 1);
3115
+ rb_define_module_function(m_Sollya, "printsingle", sollyarb_printsingle, 1);
3116
+ rb_define_module_function(m_Sollya, "printprintexpansion", sollyarb_printexpansion, 1);
3117
+ rb_define_module_function(m_Sollya, "externalplot", sollyarb_externalplot, -1);
3118
+ rb_define_module_function(m_Sollya, "execute", sollyarb_execute, 1);
3119
+ rb_define_module_function(m_Sollya, "printxml", sollyarb_printxml, 1);
3120
+ rb_define_module_function(m_Sollya, "printxml_newfile", sollyarb_printxml_newfile, 2);
3121
+ rb_define_module_function(m_Sollya, "printxml_appendfile", sollyarb_printxml_appendfile, 2);
3122
+ rb_define_module_function(m_Sollya, "worstcase", sollyarb_worstcase, -1);
3123
+ rb_define_module_function(m_Sollya, "autoprint", sollyarb_autoprint, -1);
3124
+ rb_define_module_function(m_Sollya, "suppressmessage", sollyarb_suppressmessage, -1);
3125
+ rb_define_module_function(m_Sollya, "unsuppressmessage", sollyarb_unsuppressmessage, -1);
3126
+ rb_define_module_function(m_Sollya, "implementconstant", sollyarb_implementconstant, -1);
3127
+
3128
+ /* Functions corresponding to Sollya built-in procedures */
3129
+ rb_define_module_function(m_Sollya, "range", sollyarb_range, 2);
3130
+ rb_define_module_function(m_Sollya, "list", sollyarb_list, -1);
3131
+ rb_define_module_function(m_Sollya, "fpminimax", sollyarb_fpminimax, -1);
3132
+ rb_define_module_function(m_Sollya, "supnorm", sollyarb_supnorm, 5);
3133
+ rb_define_module_function(m_Sollya, "free_variable", sollyarb_free_variable, 0);
3134
+ rb_define_module_function(m_Sollya, "x", sollyarb_free_variable, 0);
3135
+ rb_define_module_function(m_Sollya, "exp", sollyarb_exp, 1);
3136
+ rb_define_module_function(m_Sollya, "log", sollyarb_log, 1);
3137
+ rb_define_module_function(m_Sollya, "log2", sollyarb_log2, 1);
3138
+ rb_define_module_function(m_Sollya, "log10", sollyarb_log10, 1);
3139
+ rb_define_module_function(m_Sollya, "sqrt", sollyarb_sqrt, 1);
3140
+ rb_define_module_function(m_Sollya, "sin", sollyarb_sin, 1);
3141
+ rb_define_module_function(m_Sollya, "cos", sollyarb_cos, 1);
3142
+ rb_define_module_function(m_Sollya, "tan", sollyarb_tan, 1);
3143
+ rb_define_module_function(m_Sollya, "asin", sollyarb_asin, 1);
3144
+ rb_define_module_function(m_Sollya, "acos", sollyarb_acos, 1);
3145
+ rb_define_module_function(m_Sollya, "atan", sollyarb_atan, 1);
3146
+ rb_define_module_function(m_Sollya, "sinh", sollyarb_sinh, 1);
3147
+ rb_define_module_function(m_Sollya, "cosh", sollyarb_cosh, 1);
3148
+ rb_define_module_function(m_Sollya, "tanh", sollyarb_tanh, 1);
3149
+ rb_define_module_function(m_Sollya, "asinh", sollyarb_asinh, 1);
3150
+ rb_define_module_function(m_Sollya, "acosh", sollyarb_acosh, 1);
3151
+ rb_define_module_function(m_Sollya, "atanh", sollyarb_atanh, 1);
3152
+ rb_define_module_function(m_Sollya, "abs", sollyarb_abs, 1);
3153
+ rb_define_module_function(m_Sollya, "erf", sollyarb_erf, 1);
3154
+ rb_define_module_function(m_Sollya, "erfc", sollyarb_erfc, 1);
3155
+ rb_define_module_function(m_Sollya, "log1p", sollyarb_log1p, 1);
3156
+ rb_define_module_function(m_Sollya, "expm1", sollyarb_expm1, 1);
3157
+ rb_define_module_function(m_Sollya, "double", sollyarb_double, 1);
3158
+ rb_define_module_function(m_Sollya, "single", sollyarb_single, 1);
3159
+ rb_define_module_function(m_Sollya, "quad", sollyarb_quad, 1);
3160
+ rb_define_module_function(m_Sollya, "halfprecision", sollyarb_halfprecision, 1);
3161
+ rb_define_module_function(m_Sollya, "double_double", sollyarb_double_double, 1);
3162
+ rb_define_module_function(m_Sollya, "triple_double", sollyarb_triple_double, 1);
3163
+ rb_define_module_function(m_Sollya, "doubleextended", sollyarb_doubleextended, 1);
3164
+ rb_define_module_function(m_Sollya, "ceil", sollyarb_ceil, 1);
3165
+ rb_define_module_function(m_Sollya, "floor", sollyarb_floor, 1);
3166
+ rb_define_module_function(m_Sollya, "nearestint", sollyarb_nearestint, 1);
3167
+ rb_define_module_function(m_Sollya, "apply", sollyarb_apply, -1);
3168
+ rb_define_module_function(m_Sollya, "approx", sollyarb_approx, 1);
3169
+ rb_define_module_function(m_Sollya, "infnorm", sollyarb_infnorm, -1);
3170
+ rb_define_module_function(m_Sollya, "dirtyinfnorm", sollyarb_dirtyinfnorm, 2);
3171
+ rb_define_module_function(m_Sollya, "remez", sollyarb_remez, -1);
3172
+ rb_define_module_function(m_Sollya, "taylorform", sollyarb_taylorform, -1);
3173
+ rb_define_module_function(m_Sollya, "interpolate", sollyarb_interpolate, -1);
3174
+ rb_define_module_function(m_Sollya, "getbacktrace", sollyarb_getbacktrace, 0);
3175
+ // rb_define_module_function(m_Sollya, "", sollyarb_, 1);
3176
+ // rb_define_module_function(m_Sollya, "", sollyarb_, 1);
3177
+
3178
+ // sollya_obj_t sollya_lib_annotatefunction(sollya_obj_t, sollya_obj_t, sollya_obj_t, sollya_obj_t, ...);
3179
+ // sollya_obj_t sollya_lib_min(sollya_obj_t, ...);
3180
+ // sollya_obj_t sollya_lib_max(sollya_obj_t, ...);
3181
+ // sollya_obj_t sollya_lib_composepolynomials(sollya_obj_t, sollya_obj_t);
3182
+ // sollya_obj_t sollya_lib_bezout(sollya_obj_t, sollya_obj_t);
3183
+ // sollya_obj_t sollya_lib_subpoly(sollya_obj_t, sollya_obj_t);
3184
+ // sollya_obj_t sollya_lib_roundcoefficients(sollya_obj_t, sollya_obj_t);
3185
+ // sollya_obj_t sollya_lib_rationalapprox(sollya_obj_t, sollya_obj_t);
3186
+ // sollya_obj_t sollya_lib_round(sollya_obj_t, sollya_obj_t, sollya_obj_t);
3187
+ // sollya_obj_t sollya_lib_parse(sollya_obj_t);
3188
+ // sollya_obj_t sollya_lib_readxml(sollya_obj_t);
3189
+ // sollya_obj_t sollya_lib_gcd(sollya_obj_t, sollya_obj_t);
3190
+ // sollya_obj_t sollya_lib_euclidian_div(sollya_obj_t, sollya_obj_t);
3191
+ // sollya_obj_t sollya_lib_euclidian_mod(sollya_obj_t, sollya_obj_t);
3192
+ // sollya_obj_t sollya_lib_implementpoly(sollya_obj_t, sollya_obj_t, sollya_obj_t, sollya_obj_t, sollya_obj_t, sollya_obj_t, ...);
3193
+ // sollya_obj_t sollya_lib_checkinfnorm(sollya_obj_t, sollya_obj_t, sollya_obj_t);
3194
+ // sollya_obj_t sollya_lib_searchgal(sollya_obj_t, sollya_obj_t, sollya_obj_t, sollya_obj_t, sollya_obj_t, sollya_obj_t);
3195
+ // sollya_obj_t sollya_lib_guessdegree(sollya_obj_t, sollya_obj_t, sollya_obj_t, ...);
3196
+ // sollya_obj_t sollya_lib_head(sollya_obj_t);
3197
+ // sollya_obj_t sollya_lib_roundcorrectly(sollya_obj_t);
3198
+ // sollya_obj_t sollya_lib_revert(sollya_obj_t);
3199
+ // sollya_obj_t sollya_lib_sort(sollya_obj_t);
3200
+ // sollya_obj_t sollya_lib_mantissa(sollya_obj_t);
3201
+ // sollya_obj_t sollya_lib_exponent(sollya_obj_t);
3202
+ // sollya_obj_t sollya_lib_precision(sollya_obj_t);
3203
+ // sollya_obj_t sollya_lib_tail(sollya_obj_t);
3204
+ // sollya_obj_t sollya_lib_length(sollya_obj_t);
3205
+ // sollya_obj_t sollya_lib_objectname(sollya_obj_t);
3206
+
3207
+
3208
+ c_SolObject = rb_define_class_under(m_Sollya, "Object", rb_cObject);
3209
+ rb_define_alloc_func(c_SolObject, sollyarb_object_alloc);
3210
+ rb_undef_method(rb_class_of(c_SolObject), "allocate");
3211
+ rb_undef_method(rb_class_of(c_SolObject), "new");
3212
+
3213
+ c_SolString = rb_define_class_under(m_Sollya, "String", c_SolObject);
3214
+ c_SolRange = rb_define_class_under(m_Sollya, "Range", c_SolObject);
3215
+ c_SolList = rb_define_class_under(m_Sollya, "List", c_SolObject);
3216
+ c_SolStructure = rb_define_class_under(m_Sollya, "Structure", c_SolObject);
3217
+ c_SolProcedure = rb_define_class_under(m_Sollya, "Procedure", c_SolObject);
3218
+ c_SolExternalProcedure = rb_define_class_under(m_Sollya, "ExternalProcedure", c_SolObject);
3219
+ c_SolExternalData = rb_define_class_under(m_Sollya, "ExternalData", c_SolObject);
3220
+ c_SolSpecial = rb_define_class_under(m_Sollya, "Special", c_SolObject);
3221
+ c_SolFunction = rb_define_class_under(m_Sollya, "Function", c_SolObject);
3222
+ c_UnaryOp = rb_define_class_under(m_Sollya, "UnaryOp", c_SolFunction);
3223
+ c_BinaryOp = rb_define_class_under(m_Sollya, "BinaryOp", c_SolFunction);
3224
+ c_Constant = rb_define_class_under(m_Sollya, "Constant", c_SolFunction);
3225
+ c_Abs = rb_define_class_under(m_Sollya, "Abs", c_UnaryOp);
3226
+ c_Acos = rb_define_class_under(m_Sollya, "Acos", c_UnaryOp);
3227
+ c_Acosh = rb_define_class_under(m_Sollya, "Acosh", c_UnaryOp);
3228
+ c_Add = rb_define_class_under(m_Sollya, "Add", c_BinaryOp);
3229
+ c_Asin = rb_define_class_under(m_Sollya, "Asin", c_UnaryOp);
3230
+ c_Asinh = rb_define_class_under(m_Sollya, "Asinh", c_UnaryOp);
3231
+ c_Atan = rb_define_class_under(m_Sollya, "Atan", c_UnaryOp);
3232
+ c_Atanh = rb_define_class_under(m_Sollya, "Atanh", c_UnaryOp);
3233
+ c_Ceil = rb_define_class_under(m_Sollya, "Ceil", c_UnaryOp);
3234
+ c_Cos = rb_define_class_under(m_Sollya, "Cos", c_UnaryOp);
3235
+ c_Cosh = rb_define_class_under(m_Sollya, "Cosh", c_UnaryOp);
3236
+ c_Div = rb_define_class_under(m_Sollya, "Div", c_BinaryOp);
3237
+ c_Double = rb_define_class_under(m_Sollya, "Double", c_UnaryOp);
3238
+ c_DoubleDouble = rb_define_class_under(m_Sollya, "DoubleDouble", c_UnaryOp);
3239
+ c_DoubleExtended = rb_define_class_under(m_Sollya, "DoubleExtended", c_UnaryOp);
3240
+ c_Erf = rb_define_class_under(m_Sollya, "Erf", c_UnaryOp);
3241
+ c_Erfc = rb_define_class_under(m_Sollya, "Erfc", c_UnaryOp);
3242
+ c_Exp = rb_define_class_under(m_Sollya, "Exp", c_UnaryOp);
3243
+ c_Expm1 = rb_define_class_under(m_Sollya, "Expm1", c_UnaryOp);
3244
+ c_Floor = rb_define_class_under(m_Sollya, "Floor", c_UnaryOp);
3245
+ c_Freevariable = rb_define_class_under(m_Sollya, "FreeVariable", c_SolFunction);
3246
+ c_Halfprecision = rb_define_class_under(m_Sollya, "HalfPrecision", c_UnaryOp);
3247
+ c_Libraryconstant = rb_define_class_under(m_Sollya, "LibraryConstant", c_Constant);
3248
+ c_Libraryfunction = rb_define_class_under(m_Sollya, "LibraryFunction", c_SolFunction);
3249
+ c_Log = rb_define_class_under(m_Sollya, "Log", c_UnaryOp);
3250
+ c_Log10 = rb_define_class_under(m_Sollya, "Log10", c_UnaryOp);
3251
+ c_Log1p = rb_define_class_under(m_Sollya, "Log1p", c_UnaryOp);
3252
+ c_Log2 = rb_define_class_under(m_Sollya, "Log2", c_UnaryOp);
3253
+ c_Mul = rb_define_class_under(m_Sollya, "Mul", c_BinaryOp);
3254
+ c_Nearestint = rb_define_class_under(m_Sollya, "NearestInt", c_UnaryOp);
3255
+ c_Neg = rb_define_class_under(m_Sollya, "Neg", c_UnaryOp);
3256
+ c_Pi = rb_define_class_under(m_Sollya, "Pi", c_Constant);
3257
+ c_Pow = rb_define_class_under(m_Sollya, "Pow", c_BinaryOp);
3258
+ c_Procedurefunction = rb_define_class_under(m_Sollya, "ProcedureFunction", c_SolFunction);
3259
+ c_Quad = rb_define_class_under(m_Sollya, "Quad", c_UnaryOp);
3260
+ c_Sin = rb_define_class_under(m_Sollya, "Sin", c_UnaryOp);
3261
+ c_Single = rb_define_class_under(m_Sollya, "Single", c_UnaryOp);
3262
+ c_Sinh = rb_define_class_under(m_Sollya, "Sinh", c_UnaryOp);
3263
+ c_Sqrt = rb_define_class_under(m_Sollya, "Sqrt", c_UnaryOp);
3264
+ c_Sub = rb_define_class_under(m_Sollya, "Sub", c_BinaryOp);
3265
+ c_Tan = rb_define_class_under(m_Sollya, "Tan", c_UnaryOp);
3266
+ c_Tanh = rb_define_class_under(m_Sollya, "Tanh", c_UnaryOp);
3267
+ c_Tripledouble = rb_define_class_under(m_Sollya, "TripleDouble", c_UnaryOp);
3268
+
3269
+
3270
+ rb_define_method(c_SolObject, "to_sollya", sollyarb_object_to_sollya, 0);
3271
+ rb_define_method(c_SolObject, "print", sollyarb_object_print, 0);
3272
+ rb_define_method(c_SolObject, "to_s", sollyarb_object_to_s, 0);
3273
+ rb_define_method(c_SolObject, "inspect", sollyarb_object_inspect, 0);
3274
+ rb_define_method(c_SolObject, "==", sollyarb_object_cmp_equal, 1);
3275
+ rb_define_method(c_SolObject, "!=", sollyarb_object_cmp_not_equal, 1);
3276
+ rb_define_method(c_SolObject, "&", sollyarb_object_and, 1);
3277
+ rb_define_method(c_SolObject, "|", sollyarb_object_or, 1);
3278
+ rb_define_method(c_SolObject, "~", sollyarb_object_negate, 0);
3279
+ rb_define_method(c_SolObject, "concat", sollyarb_object_concat, 1);
3280
+
3281
+ rb_define_method(c_SolFunction, "<", sollyarb_object_cmp_less, 1);
3282
+ rb_define_method(c_SolFunction, ">", sollyarb_object_cmp_greater, 1);
3283
+ rb_define_method(c_SolFunction, "<=", sollyarb_object_cmp_less_equal, 1);
3284
+ rb_define_method(c_SolFunction, ">=", sollyarb_object_cmp_greater_equal, 1);
3285
+ rb_define_method(c_SolFunction, "+", sollyarb_object_add, 1);
3286
+ rb_define_method(c_SolFunction, "-", sollyarb_object_sub, 1);
3287
+ rb_define_method(c_SolFunction, "*", sollyarb_object_mul, 1);
3288
+ rb_define_method(c_SolFunction, "/", sollyarb_object_div, 1);
3289
+ rb_define_method(c_SolFunction, "**", sollyarb_object_pow, 1);
3290
+ rb_define_method(c_SolFunction, "-@", sollyarb_object_neg, 0);
3291
+ rb_define_method(c_SolFunction, "coerce", sollyarb_object_coerce, 1);
3292
+ rb_define_method(c_SolFunction, "in", sollyarb_object_in, 1);
3293
+ rb_define_method(c_SolFunction, "abs", sollyarb_function_abs, 0);
3294
+ rb_define_method(c_SolFunction, "ceil", sollyarb_function_ceil, 0);
3295
+ rb_define_method(c_SolFunction, "floor", sollyarb_function_floor, 0);
3296
+ rb_define_method(c_SolFunction, "nearestint", sollyarb_function_nearestint, 0);
3297
+ rb_define_method(c_SolFunction, "apply_at", sollyarb_function_apply_at, -1);
3298
+ rb_define_method(c_SolFunction, "diff", sollyarb_function_diff, 0);
3299
+ rb_define_method(c_SolFunction, "horner", sollyarb_function_horner, 0);
3300
+ rb_define_method(c_SolFunction, "expand", sollyarb_function_expand, 0);
3301
+ rb_define_method(c_SolFunction, "simplify", sollyarb_function_simplify, 0);
3302
+ rb_define_method(c_SolFunction, "dirtysimplify", sollyarb_function_dirtysimplify, 0);
3303
+ rb_define_method(c_SolFunction, "degree", sollyarb_function_degree, 0);
3304
+ rb_define_method(c_SolFunction, "taylor", sollyarb_function_taylor, 2);
3305
+ rb_define_method(c_SolFunction, "coeff", sollyarb_function_coeff, 1);
3306
+ rb_define_method(c_SolFunction, "integral", sollyarb_function_integral, 1);
3307
+ rb_define_method(c_SolFunction, "dirtyintegral", sollyarb_function_dirtyintegral, 1);
3308
+ rb_define_method(c_SolFunction, "numberroots", sollyarb_function_numberroots, 1);
3309
+ rb_define_method(c_SolFunction, "findzeros", sollyarb_function_findzeros, 1);
3310
+ rb_define_method(c_SolFunction, "dirtyfindzeros",sollyarb_function_dirtyfindzeros, 1);
3311
+ rb_define_method(c_SolFunction, "chebyshevform", sollyarb_function_chebyshevform, 2);
3312
+ rb_define_method(c_SolFunction, "autodiff", sollyarb_function_autodiff, 2);
3313
+ rb_define_method(c_SolFunction, "evaluate", sollyarb_function_evaluate, 1);
3314
+ rb_define_method(c_SolFunction, "substitute", sollyarb_function_substitute, 1);
3315
+ rb_define_method(c_SolFunction, "numerator", sollyarb_function_numerator, 0);
3316
+ rb_define_method(c_SolFunction, "denominator", sollyarb_function_denominator, 0);
3317
+ rb_define_method(c_SolFunction, "arity", sollyarb_function_arity, 0);
3318
+
3319
+ rb_define_method(c_UnaryOp, "child", sollyarb_unaryop_get_child, 0);
3320
+ rb_define_method(c_BinaryOp, "lhs", sollyarb_binaryop_get_lhs, 0);
3321
+ rb_define_method(c_BinaryOp, "rhs", sollyarb_binaryop_get_rhs, 0);
3322
+ rb_define_method(c_SolFunction, "nth_child", sollyarb_function_get_nth_child, 1);
3323
+ rb_define_method(c_SolFunction, "children", sollyarb_function_get_children, 0);
3324
+
3325
+ rb_define_method(c_SolList, "end_elliptic?", sollyarb_list_is_end_elliptic, 0);
3326
+ rb_define_method(c_SolList, "append", sollyarb_list_append, 1);
3327
+ rb_define_method(c_SolList, "prepend", sollyarb_list_prepend, 1);
3328
+
3329
+ rb_define_method(c_SolRange, "lower_bound", sollyarb_range_lower_bound, 0);
3330
+ rb_define_method(c_SolRange, "upper_bound", sollyarb_range_upper_bound, 0);
3331
+ rb_define_method(c_SolRange, "inf", sollyarb_range_inf, 0);
3332
+ rb_define_method(c_SolRange, "sup", sollyarb_range_sup, 0);
3333
+ rb_define_method(c_SolRange, "mid", sollyarb_range_mid, 0);
3334
+
3335
+ rb_define_method(c_Constant, "to_mpfr", sollyarb_constant_to_mpfr, 0);
3336
+ rb_define_method(c_Constant, "to_f", sollyarb_constant_to_f, 0);
3337
+
3338
+ rb_define_method(rb_cFloat, "to_sollya", sollyarb_float_to_sollya, 0);
3339
+ rb_define_method(rb_cInteger, "to_sollya", sollyarb_integer_to_sollya, 0);
3340
+ rb_define_method(rb_cRational, "to_sollya", sollyarb_rational_to_sollya, 0);
3341
+ rb_define_method(c_MPFR, "to_sollya", sollyarb_MPFR_to_sollya, 0);
3342
+ rb_define_method(rb_cString, "to_sollya", sollyarb_string_to_sollya, 0);
3343
+ rb_define_method(rb_cTrueClass, "to_sollya", sollyarb_true_to_sollya, 0);
3344
+ rb_define_method(rb_cFalseClass,"to_sollya", sollyarb_false_to_sollya, 0);
3345
+ rb_define_method(rb_cRange, "to_sollya", sollyarb_range_to_sollya, 0);
3346
+ rb_define_method(rb_cSymbol, "to_sollya", sollyarb_symbol_to_sollya, 0);
3347
+ rb_define_method(rb_cArray, "to_sollya", sollyarb_array_to_sollya, 0);
3348
+
3349
+
3350
+ sollya_lib_init();
3351
+ // sollya_lib_install_msg_callback(sollyarb_msg_callback, NULL);
3352
+
3353
+ sollyarb_cst_ON = sollyarb_ref2rb(sollya_lib_on(), c_SolSpecial);
3354
+ sollyarb_cst_OFF = sollyarb_ref2rb(sollya_lib_off(), c_SolSpecial);
3355
+ sollyarb_cst_DYADIC = sollyarb_ref2rb(sollya_lib_dyadic(), c_SolSpecial);
3356
+ sollyarb_cst_POWERS = sollyarb_ref2rb(sollya_lib_powers(), c_SolSpecial);
3357
+ sollyarb_cst_BINARY = sollyarb_ref2rb(sollya_lib_binary(), c_SolSpecial);
3358
+ sollyarb_cst_HEXADECIMAL = sollyarb_ref2rb(sollya_lib_hexadecimal(), c_SolSpecial);
3359
+ sollyarb_cst_FILE = sollyarb_ref2rb(sollya_lib_file(), c_SolSpecial);
3360
+ sollyarb_cst_POSTSCRIPT = sollyarb_ref2rb(sollya_lib_postscript(), c_SolSpecial);
3361
+ sollyarb_cst_POSTSCRIPTFILE = sollyarb_ref2rb(sollya_lib_postscriptfile(), c_SolSpecial);
3362
+ sollyarb_cst_PERTURB = sollyarb_ref2rb(sollya_lib_perturb(), c_SolSpecial);
3363
+ sollyarb_cst_ROUND_DOWN = sollyarb_ref2rb(sollya_lib_round_down(), c_SolSpecial);
3364
+ sollyarb_cst_ROUND_UP = sollyarb_ref2rb(sollya_lib_round_up(), c_SolSpecial);
3365
+ sollyarb_cst_ROUND_TOWARDS_ZERO = sollyarb_ref2rb(sollya_lib_round_towards_zero(), c_SolSpecial);
3366
+ sollyarb_cst_ROUND_TO_NEAREST = sollyarb_ref2rb(sollya_lib_round_to_nearest(), c_SolSpecial);
3367
+ sollyarb_cst_HONORCOEFFPREC = sollyarb_ref2rb(sollya_lib_honorcoeffprec(), c_SolSpecial);
3368
+ sollyarb_cst_TRUE = sollyarb_ref2rb(sollya_lib_true(), c_SolSpecial);
3369
+ sollyarb_cst_FALSE = sollyarb_ref2rb(sollya_lib_false(), c_SolSpecial);
3370
+ sollyarb_cst_VOID = sollyarb_ref2rb(sollya_lib_void(), c_SolSpecial);
3371
+ sollyarb_cst_DEFAULT = sollyarb_ref2rb(sollya_lib_default(), c_SolSpecial);
3372
+ sollyarb_cst_DECIMAL = sollyarb_ref2rb(sollya_lib_decimal(), c_SolSpecial);
3373
+ sollyarb_cst_ABSOLUTE = sollyarb_ref2rb(sollya_lib_absolute(), c_SolSpecial);
3374
+ sollyarb_cst_RELATIVE = sollyarb_ref2rb(sollya_lib_relative(), c_SolSpecial);
3375
+ sollyarb_cst_FIXED = sollyarb_ref2rb(sollya_lib_fixed(), c_SolSpecial);
3376
+ sollyarb_cst_FLOATING = sollyarb_ref2rb(sollya_lib_floating(), c_SolSpecial);
3377
+ sollyarb_cst_ERROR = sollyarb_ref2rb(sollya_lib_error(), c_SolSpecial);
3378
+ sollyarb_cst_DOUBLE = sollyarb_ref2rb(sollya_lib_double_obj(), c_SolSpecial);
3379
+ sollyarb_cst_SINGLE = sollyarb_ref2rb(sollya_lib_single_obj(), c_SolSpecial);
3380
+ sollyarb_cst_QUAD = sollyarb_ref2rb(sollya_lib_quad_obj(), c_SolSpecial);
3381
+ sollyarb_cst_HALFPRECISION = sollyarb_ref2rb(sollya_lib_halfprecision_obj(), c_SolSpecial);
3382
+ sollyarb_cst_DOUBLEEXTENDED = sollyarb_ref2rb(sollya_lib_doubleextended_obj(), c_SolSpecial);
3383
+ sollyarb_cst_DOUBLE_DOUBLE = sollyarb_ref2rb(sollya_lib_double_double_obj(), c_SolSpecial);
3384
+ sollyarb_cst_TRIPLE_DOUBLE = sollyarb_ref2rb(sollya_lib_triple_double_obj(), c_SolSpecial);
3385
+ sollyarb_cst_PI = sollyarb_ref2rb(sollya_lib_pi(), c_Constant);
3386
+
3387
+ rb_define_const(m_Sollya, "ON", sollyarb_cst_ON);
3388
+ rb_define_const(m_Sollya, "OFF", sollyarb_cst_OFF);
3389
+ rb_define_const(m_Sollya, "DYADIC", sollyarb_cst_DYADIC);
3390
+ rb_define_const(m_Sollya, "POWERS", sollyarb_cst_POWERS);
3391
+ rb_define_const(m_Sollya, "BINARY", sollyarb_cst_BINARY);
3392
+ rb_define_const(m_Sollya, "HEXADECIMAL", sollyarb_cst_HEXADECIMAL);
3393
+ rb_define_const(m_Sollya, "FILE", sollyarb_cst_FILE);
3394
+ rb_define_const(m_Sollya, "POSTSCRIPT", sollyarb_cst_POSTSCRIPT);
3395
+ rb_define_const(m_Sollya, "POSTSCRIPTFILE", sollyarb_cst_POSTSCRIPTFILE);
3396
+ rb_define_const(m_Sollya, "PERTURB", sollyarb_cst_PERTURB);
3397
+ rb_define_const(m_Sollya, "ROUND_DOWN", sollyarb_cst_ROUND_DOWN);
3398
+ rb_define_const(m_Sollya, "ROUND_UP", sollyarb_cst_ROUND_UP);
3399
+ rb_define_const(m_Sollya, "ROUND_TOWARDS_ZERO", sollyarb_cst_ROUND_TOWARDS_ZERO);
3400
+ rb_define_const(m_Sollya, "ROUND_TO_NEAREST", sollyarb_cst_ROUND_TO_NEAREST);
3401
+ rb_define_const(m_Sollya, "HONORCOEFFPREC", sollyarb_cst_HONORCOEFFPREC);
3402
+ rb_define_const(m_Sollya, "TRUE", sollyarb_cst_TRUE);
3403
+ rb_define_const(m_Sollya, "FALSE", sollyarb_cst_FALSE);
3404
+ rb_define_const(m_Sollya, "VOID", sollyarb_cst_VOID);
3405
+ rb_define_const(m_Sollya, "DEFAULT", sollyarb_cst_DEFAULT);
3406
+ rb_define_const(m_Sollya, "DECIMAL", sollyarb_cst_DECIMAL);
3407
+ rb_define_const(m_Sollya, "ABSOLUTE", sollyarb_cst_ABSOLUTE);
3408
+ rb_define_const(m_Sollya, "RELATIVE", sollyarb_cst_RELATIVE);
3409
+ rb_define_const(m_Sollya, "FIXED", sollyarb_cst_FIXED);
3410
+ rb_define_const(m_Sollya, "FLOATING", sollyarb_cst_FLOATING);
3411
+ rb_define_const(m_Sollya, "ERROR", sollyarb_cst_ERROR);
3412
+ rb_define_const(m_Sollya, "DOUBLE", sollyarb_cst_DOUBLE);
3413
+ rb_define_const(m_Sollya, "SINGLE", sollyarb_cst_SINGLE);
3414
+ rb_define_const(m_Sollya, "QUAD", sollyarb_cst_QUAD);
3415
+ rb_define_const(m_Sollya, "HALFPRECISION", sollyarb_cst_HALFPRECISION);
3416
+ rb_define_const(m_Sollya, "DOUBLEEXTENDED", sollyarb_cst_DOUBLEEXTENDED);
3417
+ rb_define_const(m_Sollya, "DOUBLE_DOUBLE", sollyarb_cst_DOUBLE_DOUBLE);
3418
+ rb_define_const(m_Sollya, "TRIPLE_DOUBLE", sollyarb_cst_TRIPLE_DOUBLE);
3419
+ rb_define_const(m_Sollya, "PI", sollyarb_cst_PI);
3420
+ }
3421
+
3422
+ // sollya_lib_close();
3423
+