1 /*
2 * This file is part of MPSolve 3.2.1
3 *
4 * Copyright (C) 2001-2020, Dipartimento di Matematica "L. Tonelli", Pisa.
5 * License: http://www.gnu.org/licenses/gpl.html GPL version 3 or higher
6 *
7 * Authors:
8 * Dario Andrea Bini <bini@dm.unipi.it>
9 * Giuseppe Fiorentino <fiorent@dm.unipi.it>
10 * Leonardo Robol <leonardo.robol@unipi.it>
11 */
12
13 #include <stdlib.h>
14 #include <mps/mps.h>
15
16 #define MPS_MPF_TEMP_SIZE 6
17
18 struct mps_tls {
19 pthread_t thread;
20 mpf_t *data;
21 long int precision;
22 struct mps_tls *next;
23 };
24
25 typedef struct mps_tls mps_tls;
26
27 static pthread_once_t once_key_created = PTHREAD_ONCE_INIT;
28 static pthread_key_t key;
29
30 static void
mps_mpc_cache_cleanup(void * pointer)31 mps_mpc_cache_cleanup (void * pointer)
32 {
33 mps_tls *ptr = pointer;
34 int i;
35
36 for (i = 0; i < MPS_MPF_TEMP_SIZE; i++)
37 mpf_clear (ptr->data[i]);
38
39 free(ptr->data);
40 free (ptr);
41 }
42
43 static mps_tls *
create_new_mps_tls(long int precision_needed)44 create_new_mps_tls (long int precision_needed)
45 {
46 mps_tls *ptr;
47 int i;
48
49 ptr = mps_new (mps_tls);
50
51 ptr->data = mps_newv (mpf_t, MPS_MPF_TEMP_SIZE);
52 ptr->precision = precision_needed;
53
54 for (i = 0; i < MPS_MPF_TEMP_SIZE; i++)
55 mpf_init2 (ptr->data[i], precision_needed);
56
57 /* Set up a destructor for this data in case the thread exits */
58 pthread_setspecific (key, ptr);
59
60 return ptr;
61 }
62
63 static void
adjust_mps_tls_precision(mps_tls * ptr,long int precision_needed)64 adjust_mps_tls_precision (mps_tls *ptr, long int precision_needed)
65 {
66 int i;
67
68 for (i = 0; i < MPS_MPF_TEMP_SIZE; i++)
69 mpf_set_prec (ptr->data[i], precision_needed);
70
71 ptr->precision = precision_needed;
72 }
73
74 static void
create_key(void)75 create_key (void)
76 {
77 pthread_key_create (&key, mps_mpc_cache_cleanup);
78 }
79
80 static mpf_t*
init(long int precision_needed)81 init (long int precision_needed)
82 {
83 pthread_once (&once_key_created, create_key);
84 mps_tls *ptr = pthread_getspecific (key);
85
86 /* This means that we have to create a new entry */
87 if (ptr == NULL)
88 {
89 ptr = create_new_mps_tls (precision_needed);
90 }
91 else if (ptr->precision < precision_needed || precision_needed < .25 * ptr->precision)
92 {
93 adjust_mps_tls_precision (ptr, precision_needed);
94 }
95
96 return ptr->data;
97 }
98
99
100 /***********************************************************
101 ** functions for mpc_t **
102 ***********************************************************/
103
104 /* constructors / destructors */
105 void
mpc_init(mpc_t c)106 mpc_init (mpc_t c)
107 {
108 printf ("mpc_init () called\n");
109 abort ();
110 mpf_init (mpc_Re (c));
111 mpf_init (mpc_Im (c));
112 }
113
114 void
mpc_init2(mpc_t c,unsigned long int prec)115 mpc_init2 (mpc_t c, unsigned long int prec)
116 {
117 prec = (prec <= 2) ? 53 : prec;
118 mpf_init2 (mpc_Re (c), prec);
119 mpf_init2 (mpc_Im (c), prec);
120 }
121
122 void
mpc_clear(mpc_t c)123 mpc_clear (mpc_t c)
124 {
125 mpf_clear (mpc_Re (c));
126 mpf_clear (mpc_Im (c));
127 }
128
129 /* precision related functions */
130 void
mpc_set_prec(mpc_t c,unsigned long int prec)131 mpc_set_prec (mpc_t c, unsigned long int prec)
132 {
133 prec = (prec <= 2) ? 53 : prec;
134 if (mpf_get_prec (mpc_Re (c)) < prec)
135 {
136 mpf_set_prec (mpc_Re (c), prec);
137 mpf_set_prec (mpc_Im (c), prec);
138 }
139 else
140 {
141 mpf_set_prec (mpc_Re (c), prec);
142 mpf_set_prec (mpc_Im (c), prec);
143 }
144 }
145
146 unsigned long int
mpc_get_prec(const mpc_t c)147 mpc_get_prec (const mpc_t c)
148 {
149 return mpf_get_prec (mpc_Re (c));
150 }
151
152 void
mpc_set_prec_raw(mpc_t c,unsigned long int prec)153 mpc_set_prec_raw (mpc_t c, unsigned long int prec)
154 {
155 mpf_set_prec_raw (mpc_Re (c), prec);
156 mpf_set_prec_raw (mpc_Im (c), prec);
157 }
158
159 /* assignment functions */
160 void
mpc_swap(mpc_t c1,mpc_t c2)161 mpc_swap (mpc_t c1, mpc_t c2)
162 /* c1 <-> c2 */
163 {
164 mpc_t t;
165
166 mpc_Move (t, c1);
167 mpc_Move (c1, c2);
168 mpc_Move (c2, t);
169 }
170
171 void
mpc_set(mpc_t rc,const mpc_t c)172 mpc_set (mpc_t rc, const mpc_t c)
173 {
174 mpf_set (mpc_Re (rc), mpc_Re (c));
175 mpf_set (mpc_Im (rc), mpc_Im (c));
176 }
177
178 void
mpc_set_ui(mpc_t c,unsigned long int ir,unsigned long int ii)179 mpc_set_ui (mpc_t c, unsigned long int ir, unsigned long int ii)
180 {
181 mpf_set_ui (mpc_Re (c), ir);
182 mpf_set_ui (mpc_Im (c), ii);
183 }
184
185 void
mpc_set_si(mpc_t c,signed long int ir,signed long int ii)186 mpc_set_si (mpc_t c, signed long int ir, signed long int ii)
187 {
188 mpf_set_si (mpc_Re (c), ir);
189 mpf_set_si (mpc_Im (c), ii);
190 }
191
192 void
mpc_set_d(mpc_t c,double dr,double di)193 mpc_set_d (mpc_t c, double dr, double di)
194 {
195 mpf_set_d (mpc_Re (c), dr);
196 mpf_set_d (mpc_Im (c), di);
197 }
198
199 void
mpc_set_z(mpc_t c,mpz_t zr,mpz_t zi)200 mpc_set_z (mpc_t c, mpz_t zr, mpz_t zi)
201 {
202 mpf_set_z (mpc_Re (c), zr);
203 mpf_set_z (mpc_Im (c), zi);
204 }
205
206 void
mpc_set_q(mpc_t c,mpq_t qr,mpq_t qi)207 mpc_set_q (mpc_t c, mpq_t qr, mpq_t qi)
208 {
209 mpf_set_q (mpc_Re (c), qr);
210 mpf_set_q (mpc_Im (c), qi);
211 }
212
213 void
mpc_set_f(mpc_t c,mpf_t fr,mpf_t fi)214 mpc_set_f (mpc_t c, mpf_t fr, mpf_t fi)
215 {
216 mpf_set (mpc_Re (c), fr);
217 mpf_set (mpc_Im (c), fi);
218 }
219
220 int
mpc_set_str(mpc_t c,char * sr,char * si,int base)221 mpc_set_str (mpc_t c, char *sr, char *si, int base)
222 {
223 if (mpf_set_str (mpc_Re (c), sr, base) != 0)
224 return -1;
225 return mpf_set_str (mpc_Im (c), si, base);
226 }
227
228 void
mpc_init_set(mpc_t rc,mpc_t c)229 mpc_init_set (mpc_t rc, mpc_t c)
230 {
231 mpf_init_set (mpc_Re (rc), mpc_Re (c));
232 mpf_init_set (mpc_Im (rc), mpc_Im (c));
233 }
234
235 void
mpc_init_set_ui(mpc_t c,unsigned long int ir,unsigned long int ii)236 mpc_init_set_ui (mpc_t c, unsigned long int ir, unsigned long int ii)
237 {
238 mpf_init_set_ui (mpc_Re (c), ir);
239 mpf_init_set_ui (mpc_Im (c), ii);
240 }
241
242 void
mpc_init_set_si(mpc_t c,signed long int ir,signed long int ii)243 mpc_init_set_si (mpc_t c, signed long int ir, signed long int ii)
244 {
245 mpf_init_set_si (mpc_Re (c), ir);
246 mpf_init_set_si (mpc_Im (c), ii);
247 }
248
249 void
mpc_init_set_d(mpc_t c,double dr,double di)250 mpc_init_set_d (mpc_t c, double dr, double di)
251 {
252 mpf_init_set_d (mpc_Re (c), dr);
253 mpf_init_set_d (mpc_Im (c), di);
254 }
255
256 void
mpc_init_set_f(mpc_t c,mpf_t fr,mpf_t fi)257 mpc_init_set_f (mpc_t c, mpf_t fr, mpf_t fi)
258 {
259 mpf_init_set (mpc_Re (c), fr);
260 mpf_init_set (mpc_Im (c), fi);
261 }
262
263 int
mpc_init_set_str(mpc_t c,char * sr,char * si,int base)264 mpc_init_set_str (mpc_t c, char *sr, char *si, int base)
265 {
266 if (!mpf_init_set_str (mpc_Re (c), sr, base))
267 return -1;
268 return mpf_init_set_str (mpc_Im (c), si, base);
269 }
270
271 /* unary functions */
272 void
mpc_neg(mpc_t rc,mpc_t c)273 mpc_neg (mpc_t rc, mpc_t c)
274 {
275 mpf_neg (mpc_Re (rc), mpc_Re (c));
276 mpf_neg (mpc_Im (rc), mpc_Im (c));
277 }
278
279 void
mpc_smod(mpf_t f,mpc_t c)280 mpc_smod (mpf_t f, mpc_t c)
281 {
282 mpf_t *t = init (mpf_get_prec (f));
283
284 mpf_mul (f, mpc_Re (c), mpc_Re (c));
285 mpf_mul (*t, mpc_Im (c), mpc_Im (c));
286 mpf_add (f, f, *t);
287 }
288
289 void
mpc_rmod(rdpe_t r,mpc_t c)290 mpc_rmod (rdpe_t r, mpc_t c)
291 {
292 cdpe_t cdtmp;
293
294 mpc_get_cdpe (cdtmp, c);
295 cdpe_mod (r, cdtmp);
296 }
297
298 void
mpc_mod(mpf_t f,mpc_t c)299 mpc_mod (mpf_t f, mpc_t c)
300 {
301 mpf_t *t = init (mpf_get_prec (f));
302
303 mpf_mul (f, mpc_Re (c), mpc_Re (c));
304 mpf_mul (*t, mpc_Im (c), mpc_Im (c));
305 mpf_add (f, f, *t);
306 mpf_sqrt (f, f);
307 }
308
309 void
mpc_con(mpc_t rc,mpc_t c)310 mpc_con (mpc_t rc, mpc_t c)
311 {
312 mpc_set (rc, c);
313 mpf_neg (mpc_Im (rc), mpc_Im (rc));
314 }
315
316 void
mpc_inv(mpc_t rc,mpc_t c)317 mpc_inv (mpc_t rc, mpc_t c)
318 {
319 mpf_t *f = init (mpf_get_prec (mpc_Re (rc))) + 5;
320
321 mpc_smod (*f, c);
322 mpc_con (rc, c);
323 mpf_div (mpc_Re (rc), mpc_Re (rc), *f);
324 mpf_div (mpc_Im (rc), mpc_Im (rc), *f);
325 }
326
327 void
mpc_inv2(mpc_t rc,mpc_t c)328 mpc_inv2 (mpc_t rc, mpc_t c)
329 {
330 mpf_t *f = init (mpf_get_prec (mpc_Re (rc))) + 5;
331
332 mpc_smod (*f, c);
333 mpf_ui_div (*f, 1L, *f);
334 mpc_con (rc, c);
335 mpf_mul (mpc_Re (rc), mpc_Re (rc), *f);
336 mpf_mul (mpc_Im (rc), mpc_Im (rc), *f);
337 }
338
339 void
mpc_sqr(mpc_t rc,mpc_t c)340 mpc_sqr (mpc_t rc, mpc_t c)
341 {
342 mpf_t *f = init (mpf_get_prec (mpc_Re (rc)));
343
344 mpf_mul (*f, mpc_Re (c), mpc_Im (c));
345 mpf_mul (mpc_Re (rc), mpc_Re (c), mpc_Re (c));
346 mpf_mul (mpc_Im (rc), mpc_Im (c), mpc_Im (c));
347
348 mpf_sub (mpc_Re (rc), mpc_Re (rc), mpc_Im (rc));
349 mpf_mul_2exp (mpc_Im (rc), *f, 1);
350 }
351
352 void
mpc_rot(mpc_t rc,mpc_t c)353 mpc_rot (mpc_t rc, mpc_t c)
354 {
355 mpf_t *f = init (mpf_get_prec (mpc_Re (rc)));
356
357 mpf_set (*f, mpc_Re (c));
358 mpf_set (mpc_Re (rc), mpc_Im (c));
359 mpf_set (mpc_Im (rc), *f);
360 mpf_neg (mpc_Re (rc), mpc_Re (rc));
361 }
362
363 void
mpc_flip(mpc_t rc,mpc_t c)364 mpc_flip (mpc_t rc, mpc_t c)
365 {
366 mpf_t f;
367
368 mpf_init2 (f, mpf_get_prec (mpc_Re (rc)));
369
370 mpf_set (f, mpc_Re (c));
371 mpf_set (mpc_Re (rc), mpc_Im (c));
372 mpf_set (mpc_Im (rc), f);
373
374 mpf_clear (f);
375 }
376
377 /* binary functions */
378 void
mpc_add(mpc_t rc,mpc_t c1,mpc_t c2)379 mpc_add (mpc_t rc, mpc_t c1, mpc_t c2)
380 {
381 mpf_add (mpc_Re (rc), mpc_Re (c1), mpc_Re (c2));
382 mpf_add (mpc_Im (rc), mpc_Im (c1), mpc_Im (c2));
383 }
384
385 void
mpc_add_f(mpc_t rc,mpc_t c,mpf_t f)386 mpc_add_f (mpc_t rc, mpc_t c, mpf_t f)
387 {
388 mpf_add (mpc_Re (rc), mpc_Re (c), f);
389 }
390
391 void
mpc_add_ui(mpc_t rc,mpc_t c,unsigned long int r,unsigned long int i)392 mpc_add_ui (mpc_t rc, mpc_t c, unsigned long int r, unsigned long int i)
393 {
394 mpf_add_ui (mpc_Re (rc), mpc_Re (c), r);
395 mpf_add_ui (mpc_Im (rc), mpc_Im (c), i);
396 }
397
398 void
mpc_sub(mpc_t rc,mpc_t c1,mpc_t c2)399 mpc_sub (mpc_t rc, mpc_t c1, mpc_t c2)
400 {
401 mpf_sub (mpc_Re (rc), mpc_Re (c1), mpc_Re (c2));
402 mpf_sub (mpc_Im (rc), mpc_Im (c1), mpc_Im (c2));
403 }
404
405 void
mpc_sub_f(mpc_t rc,mpc_t c,mpf_t f)406 mpc_sub_f (mpc_t rc, mpc_t c, mpf_t f)
407 {
408 mpf_sub (mpc_Re (rc), mpc_Re (c), f);
409 }
410
411 void
mpc_f_sub(mpc_t rc,mpf_t f,mpc_t c)412 mpc_f_sub (mpc_t rc, mpf_t f, mpc_t c)
413 {
414 mpf_sub (mpc_Re (rc), f, mpc_Re (c));
415 }
416
417 void
mpc_sub_ui(mpc_t rc,mpc_t c,unsigned long int r,unsigned long int i)418 mpc_sub_ui (mpc_t rc, mpc_t c, unsigned long int r, unsigned long int i)
419 {
420 mpf_sub_ui (mpc_Re (rc), mpc_Re (c), r);
421 mpf_sub_ui (mpc_Im (rc), mpc_Im (c), i);
422 }
423
424 void
mpc_ui_sub(mpc_t rc,unsigned long int r,unsigned long int i,mpc_t c)425 mpc_ui_sub (mpc_t rc, unsigned long int r, unsigned long int i, mpc_t c)
426 {
427 mpf_ui_sub (mpc_Re (rc), r, mpc_Re (c));
428 mpf_ui_sub (mpc_Im (rc), i, mpc_Im (c));
429 }
430
431 void
mpc_mul(mpc_t rc,mpc_t c1,mpc_t c2)432 mpc_mul (mpc_t rc, mpc_t c1, mpc_t c2)
433 {
434 mpf_t *s1, *s2, *s3;
435
436 s1 = init (mpf_get_prec (mpc_Re (rc)));
437 s2 = s1 + 1;
438 s3 = s2 + 1;
439
440 mpf_sub (*s1, mpc_Re (c1), mpc_Im (c1));
441 mpf_add (*s2, mpc_Re (c2), mpc_Im (c2));
442 mpf_mul (*s1, *s1, *s2);
443 mpf_mul (*s2, mpc_Re (c1), mpc_Im (c2));
444 mpf_mul (*s3, mpc_Im (c1), mpc_Re (c2));
445 mpf_sub (mpc_Re (rc), *s1, *s2);
446 mpf_add (mpc_Re (rc), mpc_Re (rc), *s3);
447 mpf_add (mpc_Im (rc), *s2, *s3);
448 }
449
450 void
mpc_mul_f(mpc_t rc,mpc_t c,mpf_t f)451 mpc_mul_f (mpc_t rc, mpc_t c, mpf_t f)
452 {
453 mpf_mul (mpc_Re (rc), mpc_Re (c), f);
454 mpf_mul (mpc_Im (rc), mpc_Im (c), f);
455 }
456
457 void
mpc_mul_ui(mpc_t rc,mpc_t c,unsigned long int i)458 mpc_mul_ui (mpc_t rc, mpc_t c, unsigned long int i)
459 {
460 mpf_mul_ui (mpc_Re (rc), mpc_Re (c), i);
461 mpf_mul_ui (mpc_Im (rc), mpc_Im (c), i);
462 }
463
464 void
mpc_mul_2exp(mpc_t rc,mpc_t c,unsigned long int i)465 mpc_mul_2exp (mpc_t rc, mpc_t c, unsigned long int i)
466 {
467 mpf_mul_2exp (mpc_Re (rc), mpc_Re (c), i);
468 mpf_mul_2exp (mpc_Im (rc), mpc_Im (c), i);
469 }
470
471 void
mpc_div(mpc_t rc,mpc_t c1,mpc_t c2)472 mpc_div (mpc_t rc, mpc_t c1, mpc_t c2)
473 {
474 /* Find a good offset so that we don't pollute mul and inv registers */
475 mpc_t t;
476
477 mpc_init2 (t, mpf_get_prec (mpc_Re (rc)));
478
479 mpc_inv (t, c2);
480 mpc_mul (rc, c1, t);
481 mpc_clear (t);
482 }
483
484 void
mpc_div_f(mpc_t rc,mpc_t c,mpf_t f)485 mpc_div_f (mpc_t rc, mpc_t c, mpf_t f)
486 {
487 mpf_div (mpc_Re (rc), mpc_Re (c), f);
488 mpf_div (mpc_Im (rc), mpc_Im (c), f);
489 }
490
491 void
mpc_f_div(mpc_t rc,mpf_t f,mpc_t c)492 mpc_f_div (mpc_t rc, mpf_t f, mpc_t c)
493 {
494 mpc_t t;
495
496 mpc_init2 (t, mpf_get_prec (mpc_Re (rc)));
497
498 mpc_inv (t, c);
499 mpc_mul_f (rc, t, f);
500
501 mpc_clear (t);
502 }
503
504 void
mpc_div_ui(mpc_t rc,mpc_t c,unsigned long int i)505 mpc_div_ui (mpc_t rc, mpc_t c, unsigned long int i)
506 {
507 mpf_div_ui (mpc_Re (rc), mpc_Re (c), i);
508 mpf_div_ui (mpc_Im (rc), mpc_Im (c), i);
509 }
510
511 void
mpc_ui_div(mpc_t rc,unsigned long int i,mpc_t c)512 mpc_ui_div (mpc_t rc, unsigned long int i, mpc_t c)
513 {
514 mpc_set_ui(rc, i, 0L);
515 mpc_div_eq(rc, c);
516 }
517
518 void
mpc_div_2exp(mpc_t rc,mpc_t c,unsigned long int i)519 mpc_div_2exp (mpc_t rc, mpc_t c, unsigned long int i)
520 {
521 mpf_div_2exp (mpc_Re (rc), mpc_Re (c), i);
522 mpf_div_2exp (mpc_Im (rc), mpc_Im (c), i);
523 }
524
525 void
mpc_pow_si(mpc_t rc,mpc_t c,register signed long int i)526 mpc_pow_si (mpc_t rc, mpc_t c, register signed long int i)
527 /* rc = c^i, i integer */
528 {
529 mpc_t t;
530
531 mpc_init2 (t, mpf_get_prec (mpc_Re (rc)));
532
533 mpc_set (t, c);
534 if (i < 0)
535 {
536 mpc_inv_eq (t);
537 i = -i;
538 }
539 if (i & 1)
540 mpc_set (rc, t);
541 else
542 mpc_set_ui (rc, 1, 0);
543 i >>= 1; /* divide i by 2 */
544
545 while (i)
546 {
547 mpc_sqr_eq (t);
548 if (i & 1)
549 mpc_mul_eq (rc, t);
550 i >>= 1; /* divide i by 2 */
551 }
552
553 mpc_clear (t);
554 }
555
556 /* op= style functions */
557 void
mpc_smod_eq(mpc_t c)558 mpc_smod_eq (mpc_t c)
559 {
560 mpf_mul (mpc_Re (c), mpc_Re (c), mpc_Re (c));
561 mpf_mul (mpc_Im (c), mpc_Im (c), mpc_Im (c));
562 mpf_add (mpc_Re (c), mpc_Re (c), mpc_Im (c));
563 mpf_set_ui (mpc_Im (c), 0);
564 }
565
566 void
mpc_mod_eq(mpc_t c)567 mpc_mod_eq (mpc_t c)
568 {
569 mpf_mul (mpc_Re (c), mpc_Re (c), mpc_Re (c));
570 mpf_mul (mpc_Im (c), mpc_Im (c), mpc_Im (c));
571 mpf_add (mpc_Re (c), mpc_Re (c), mpc_Im (c));
572 mpf_sqrt (mpc_Re (c), mpc_Re (c));
573 mpf_set_ui (mpc_Im (c), 0);
574 }
575
576 void
mpc_rot_eq(mpc_t c)577 mpc_rot_eq (mpc_t c)
578 {
579 mpf_t f;
580
581 mpf_Move (f, mpc_Re (c));
582 mpf_Move (mpc_Re (c), mpc_Im (c));
583 mpf_Move (mpc_Im (c), f);
584 mpf_neg (mpc_Re (c), mpc_Re (c));
585 }
586
587 void
mpc_flip_eq(mpc_t c)588 mpc_flip_eq (mpc_t c)
589 {
590 mpf_t f;
591
592 mpf_Move (f, mpc_Re (c));
593 mpf_Move (mpc_Re (c), mpc_Im (c));
594 mpf_Move (mpc_Im (c), f);
595 }
596
597 /* comparison functions */
598 int
mpc_eq(mpc_t c1,mpc_t c2,unsigned long int i)599 mpc_eq (mpc_t c1, mpc_t c2, unsigned long int i)
600 {
601 if (!mpf_eq (mpc_Re (c1), mpc_Re (c2), i))
602 return -1;
603 return mpf_eq (mpc_Im (c1), mpc_Im (c2), i);
604 }
605
606 int
mpc_eq_zero(mpc_t c)607 mpc_eq_zero (mpc_t c)
608 {
609 if (mpf_sgn (mpc_Re (c)) || mpf_sgn (mpc_Im (c)))
610 return 0;
611 else
612 return 1;
613 }
614
615 int
mpc_eq_one(mpc_t c)616 mpc_eq_one (mpc_t c)
617 {
618 if (mpf_sgn (mpc_Im (c)) || mpf_cmp_ui (mpc_Re (c), 1))
619 return 0;
620 else
621 return 1;
622 }
623
624 /* I/O functions */
625 size_t
mpc_out_str_2u(FILE * f,int base,size_t n_digits_r,size_t n_digits_i,mpc_t c)626 mpc_out_str_2u (FILE * f, int base, size_t n_digits_r,
627 size_t n_digits_i, mpc_t c)
628 /* unformatted output */
629 {
630 if (f == NULL)
631 f = stdout;
632 if (!mpf_out_str (f, base, n_digits_r, mpc_Re (c)))
633 return 0;
634 if (fprintf (f, " ") < 0)
635 return 0;
636 if (!mpf_out_str (f, base, n_digits_i, mpc_Im (c)))
637 return 0;
638 else
639 return 1;
640 }
641
642 size_t
mpc_out_str_2(FILE * f,int base,size_t n_digits_r,size_t n_digits_i,mpc_t c)643 mpc_out_str_2 (FILE * f, int base, size_t n_digits_r,
644 size_t n_digits_i, mpc_t c)
645 /* formatted output */
646 {
647 if (f == NULL)
648 f = stdout;
649 if (fprintf (f, "(") < 0)
650 return 0;
651 if (!mpf_out_str (f, base, n_digits_r, mpc_Re (c)))
652 return 0;
653 if (fprintf (f, ", ") < 0)
654 return 0;
655 if (!mpf_out_str (f, base, n_digits_i, mpc_Im (c)))
656 return 0;
657 if (fprintf (f, ")") < 0)
658 return 0;
659 else
660 return 1;
661 }
662
663 size_t
mpc_inp_str_u(mpc_t c,FILE * f,int base)664 mpc_inp_str_u (mpc_t c, FILE * f, int base)
665 /* unformatted input */
666 {
667 if (f == NULL)
668 f = stdin;
669 if (!mpf_inp_str (mpc_Re (c), f, base))
670 return 0;
671 if (fscanf (f, " ") < 0)
672 return 0;
673 if (!mpf_inp_str (mpc_Im (c), f, base))
674 return 0;
675 else
676 return 1;
677 }
678
679 size_t
mpc_inp_str(mpc_t c,FILE * f,int base)680 mpc_inp_str (mpc_t c, FILE * f, int base)
681 /* formatted input */
682 {
683 if (f == NULL)
684 f = stdin;
685 if (fscanf (f, "(") < 0)
686 return 0;
687 if (!mpf_inp_str (mpc_Re (c), f, base))
688 return 0;
689 if (fscanf (f, ", ") < 0)
690 return 0;
691 if (!mpf_inp_str (mpc_Im (c), f, base))
692 return 0;
693 if (fscanf (f, ")") < 0)
694 return 0;
695 else
696 return 1;
697 }
698
699 /* vector functions */
700 void
mpc_vinit(mpc_t v[],long size)701 mpc_vinit (mpc_t v[], long size)
702 {
703 long i;
704
705 for (i = 0; i < size; i++)
706 mpc_init (v[i]);
707 }
708
709 void
mpc_vinit2(mpc_t v[],long size,long prec)710 mpc_vinit2 (mpc_t v[], long size, long prec)
711 {
712 long i;
713
714 for (i = 0; i < size; i++)
715 mpc_init2 (v[i], prec);
716 }
717
718 void
mpc_vclear(mpc_t v[],long size)719 mpc_vclear (mpc_t v[], long size)
720 {
721 long i;
722
723 for (i = 0; i < size; i++)
724 mpc_clear (v[i]);
725 /* free(v); */
726 }
727
728 /***********************************************************
729 ** **
730 ***********************************************************/
731