number 0.9.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/complex.c ADDED
@@ -0,0 +1,674 @@
1
+ #include "number.h"
2
+
3
+ /*
4
+ * Sets the value of num to the complex value represented by re and im.
5
+ */
6
+ void mpc_init_set_r_r (mpc_t num, Real* re, Real* im)
7
+ {
8
+ char buf[10000];
9
+ char tmp_re_buf[10000];
10
+ char tmp_im_buf[10000];
11
+ char re_buf[10000];
12
+ char im_buf[10000];
13
+
14
+ if (REAL(re))
15
+ {
16
+ gmp_sprintf(tmp_re_buf, "%+Zd", re->num);
17
+ sprintf(re_buf, "%c0.%se%ld", *tmp_re_buf, tmp_re_buf + 1, re->exp);
18
+ }
19
+ else
20
+ {
21
+ sprintf(re_buf, "%s", NaN(re) ? "@nan@" : POS_INF(re) ? "@inf@" : "-@inf@");
22
+ }
23
+
24
+ if (REAL(im))
25
+ {
26
+ gmp_sprintf(tmp_im_buf, "%+Zd", im->num);
27
+ sprintf(im_buf, "%c0.%se%ld", *tmp_im_buf, tmp_im_buf + 1, im->exp);
28
+ }
29
+ else
30
+ {
31
+ sprintf(im_buf, "%s", NaN(im) ? "@nan@" : POS_INF(im) ? "@inf@" : "-@inf@");
32
+ }
33
+
34
+ sprintf(buf, "(%s %s)", re_buf, im_buf);
35
+
36
+ mpc_init2(num, PREC);
37
+ mpc_set_str(num, buf, 10, MPC_RNDNN);
38
+ }
39
+
40
+ /*
41
+ * Sets the value of num to the floating point value represented by real.
42
+ */
43
+ void mpfr_init_set_r (mpfr_t num, Real* real)
44
+ {
45
+ char sign;
46
+ char buf[10000];
47
+ char real_buf[10000];
48
+
49
+ if (REAL(real))
50
+ {
51
+ gmp_sprintf(real_buf, "%+Zd", real->num);
52
+ sprintf(buf, "%c0.%se%ld", *real_buf, real_buf + 1, real->exp);
53
+ }
54
+ else
55
+ {
56
+ sprintf(buf, "%s", NaN(real) ? "@nan@" : POS_INF(real) ? "@inf@" : "-@inf@");
57
+ }
58
+
59
+ mpfr_init2(num, PREC);
60
+ mpfr_set_str(num, buf, 10, MPFR_RNDN);
61
+ }
62
+
63
+ /*
64
+ * Frees the memory block pointed to by complex.
65
+ */
66
+ void complex_free (Complex* complex)
67
+ {
68
+ if (complex)
69
+ {
70
+ if (complex->re)
71
+ {
72
+ interval_free(complex->re);
73
+ }
74
+
75
+ if (complex->im)
76
+ {
77
+ interval_free(complex->im);
78
+ }
79
+
80
+ free(complex);
81
+ complex = NULL;
82
+ }
83
+ }
84
+
85
+ /*
86
+ * Returns the maximum size of the string representation of complex as a long.
87
+ */
88
+ long complex_strlen (Complex* complex)
89
+ {
90
+ return interval_strlen(complex->re) + interval_strlen(complex->im) + 10;
91
+ }
92
+
93
+ /*
94
+ * Puts a string representation of complex into the string pointed to by buf.
95
+ *
96
+ * complex: ({1:1 < 2:1 < 3:1},{0:1 ≤ 0:1 ≤ 0:1}) => str: "{1:1 < 2:1 < 3:1}, {0:1 ≤ 0:1 ≤ 0:1}i"
97
+ */
98
+ void complex_print (char* buf, Complex* complex)
99
+ {
100
+ char rbuf[interval_strlen(complex->re)];
101
+ char ibuf[interval_strlen(complex->im)];
102
+
103
+ if (interval_zero_p(complex->im))
104
+ {
105
+ interval_print(rbuf, complex->re);
106
+ sprintf(buf, "%s", rbuf);
107
+ }
108
+ else
109
+ {
110
+ interval_print(rbuf, complex->re);
111
+ interval_print(ibuf, complex->im);
112
+
113
+ sprintf(buf, "%s+%si", rbuf, ibuf);
114
+ }
115
+ }
116
+
117
+ /*
118
+ * Returns a pointer to a newly allocated Complex with the given value. The
119
+ * given intervals will be referenced by the new complex and must be freed only
120
+ * when this complex is freed.
121
+ *
122
+ * re: {1:1 < 2:1 < 3:1}, im: {0:1 ≤ 0:1 ≤ 0:1} => complex: {1:1 < 2:1 < 3:1}, {0:1 ≤ 0:1 ≤ 0:1}
123
+ */
124
+ Complex* complex_new (Interval* re, Interval* im)
125
+ {
126
+ Complex* complex;
127
+ complex = (Complex*)malloc(sizeof(Complex));
128
+
129
+ if (complex == NULL)
130
+ {
131
+ return NULL;
132
+ }
133
+
134
+ memset(complex, 0, sizeof(Complex));
135
+ complex->re = (Interval*)re;
136
+ complex->im = (Interval*)im;
137
+
138
+ return complex;
139
+ }
140
+
141
+ /*
142
+ * Returns a pointer to a newly allocated Complex with the given real as its
143
+ * real part and 0 as its imaginary part. The given real is duplicated before
144
+ * being stored, and therefore must be freed separately.
145
+ */
146
+ Complex* complex_from_real (Real* real)
147
+ {
148
+ return complex_new((Interval*)interval_from_real(real), (Interval*)interval_zero());
149
+ }
150
+
151
+ /*
152
+ * Returns a pointer to a newly allocated Complex with the integer represented
153
+ * by str as its real part.
154
+ */
155
+ Complex* complex_from_int_str (char* buf)
156
+ {
157
+ Real* real;
158
+ Complex* result;
159
+
160
+ real = (Real*)real_from_str(buf, strlen(buf) - (*buf == '-'));
161
+ result = (Complex*)complex_from_real(real);
162
+
163
+ real_free(real);
164
+
165
+ return result;
166
+ }
167
+
168
+ /*
169
+ * Returns a pointer to a newly allocated Complex with the float represented by
170
+ * str as its real part.
171
+ */
172
+ Complex* complex_from_float_str (char* buf)
173
+ {
174
+ mpfr_t num;
175
+ Real* real;
176
+ Complex* result;
177
+
178
+ mpfr_init2(num, PREC);
179
+ mpfr_set_str(num, buf, 10, MPFR_RNDN);
180
+
181
+ real = (Real*)real_from_mpfr(num, ROUND_NEAREST);
182
+ result = (Complex*)complex_from_real(real);
183
+
184
+ mpfr_clear(num);
185
+ real_free(real);
186
+
187
+ return result;
188
+ }
189
+
190
+ /*
191
+ * Returns a pointer to a newly allocated Complex containing a NaN value.
192
+ */
193
+ Complex* complex_nan ()
194
+ {
195
+ return complex_new((Interval*)interval_nan(), (Interval*)interval_zero());
196
+ }
197
+
198
+ /*
199
+ * Returns a pointer to a newly allocated Complex containing only +∞.
200
+ */
201
+ Complex* complex_pos_inf ()
202
+ {
203
+ return complex_new((Interval*)interval_pos_inf(), (Interval*)interval_zero());
204
+ }
205
+
206
+ /*
207
+ * Returns a pointer to a newly allocated Complex containing only -∞.
208
+ */
209
+ Complex* complex_neg_inf ()
210
+ {
211
+ return complex_new((Interval*)interval_neg_inf(), (Interval*)interval_zero());
212
+ }
213
+
214
+ /*
215
+ * Returns a pointer to a newly allocated Complex containing only 0.
216
+ */
217
+ Complex* complex_zero ()
218
+ {
219
+ return complex_new((Interval*)interval_zero(), (Interval*)interval_zero());
220
+ }
221
+
222
+ /*
223
+ * Returns a pointer to a newly allocated Complex containing only 1.
224
+ */
225
+ Complex* complex_one ()
226
+ {
227
+ return complex_new((Interval*)interval_one(), (Interval*)interval_zero());
228
+ }
229
+
230
+ /*
231
+ * Returns a pointer to a newly allocated Complex containing π, accurate to
232
+ * digs digits.
233
+ */
234
+ Complex* complex_pi ()
235
+ {
236
+ return complex_new((Interval*)interval_pi(), (Interval*)interval_zero());
237
+ }
238
+
239
+ /*
240
+ * Returns a pointer to a newly allocated Complex containing e, accurate to
241
+ * digs digits.
242
+ */
243
+ Complex* complex_e ()
244
+ {
245
+ return complex_new((Interval*)interval_e(), (Interval*)interval_zero());
246
+ }
247
+
248
+ /*
249
+ * Returns a pointer to a newly allocated Complex containing only i.
250
+ */
251
+ Complex* complex_i ()
252
+ {
253
+ return complex_new((Interval*)interval_zero(), (Interval*)interval_one());
254
+ }
255
+
256
+ /*
257
+ * Returns a pointer to a newly allocated Complex with the same value as the
258
+ * given complex.
259
+ */
260
+ Complex* complex_dup (Complex* complex)
261
+ {
262
+ return complex_new((Interval*)interval_dup(complex->re), (Interval*)interval_dup(complex->im));
263
+ }
264
+
265
+ /*
266
+ * Returns a pointer to a newly allocated Complex containing a + b.
267
+ */
268
+ Complex* complex_add (Complex* a, Complex* b)
269
+ {
270
+ Interval* re;
271
+ Interval* im;
272
+
273
+ re = (Interval*)interval_add(a->re, b->re);
274
+ im = (Interval*)interval_add(a->im, b->im);
275
+
276
+ return complex_new(re, im);
277
+ }
278
+
279
+ /*
280
+ * Returns a pointer to a newly allocated Complex containing a - b.
281
+ */
282
+ Complex* complex_subtract (Complex* a, Complex* b)
283
+ {
284
+ Interval* re;
285
+ Interval* im;
286
+
287
+ re = (Interval*)interval_subtract(a->re, b->re);
288
+ im = (Interval*)interval_subtract(a->im, b->im);
289
+
290
+ return complex_new(re, im);
291
+ }
292
+
293
+ /*
294
+ * Returns a pointer to a newly allocated Complex containing a * b.
295
+ */
296
+ Complex* complex_multiply (Complex* a, Complex* b)
297
+ {
298
+ Interval* re_re;
299
+ Interval* re_im;
300
+ Interval* im_re;
301
+ Interval* im_im;
302
+ Interval* re;
303
+ Interval* im;
304
+
305
+ re_re = (Interval*)interval_multiply(a->re, b->re);
306
+ re_im = (Interval*)interval_multiply(a->re, b->im);
307
+ im_re = (Interval*)interval_multiply(a->im, b->re);
308
+ im_im = (Interval*)interval_multiply(a->im, b->im);
309
+
310
+ re = (Interval*)interval_subtract(re_re, im_im);
311
+ im = (Interval*)interval_add(re_im, im_re);
312
+
313
+ interval_free(re_re);
314
+ interval_free(re_im);
315
+ interval_free(im_re);
316
+ interval_free(im_im);
317
+
318
+ return (Complex*)complex_new(re, im);
319
+ }
320
+
321
+ /*
322
+ * Returns a pointer to a newly allocated Complex containing a / b.
323
+ */
324
+ Complex* complex_divide (Complex* a, Complex* b)
325
+ {
326
+ mpc_t num_numerator;
327
+ mpc_t num_denominator;
328
+ mpc_t num_quotient;
329
+ mpfr_t num_re;
330
+ mpfr_t num_im;
331
+ Interval* denominator_re;
332
+ Interval* denominator_im;
333
+ Interval* denominator;
334
+ Interval* numerator_re;
335
+ Interval* numerator_im;
336
+ Interval* re_re;
337
+ Interval* re_im;
338
+ Interval* im_re;
339
+ Interval* im_im;
340
+ Interval* re;
341
+ Interval* im;
342
+
343
+ denominator_re = (Interval*)interval_multiply(b->re, b->re);
344
+ denominator_im = (Interval*)interval_multiply(b->im, b->im);
345
+ denominator = (Interval*)interval_add(denominator_re, denominator_im);
346
+
347
+ if (real_zero_p(denominator->l) || real_zero_p(denominator->u) || interval_span_zero_p(denominator))
348
+ {
349
+ mpfr_init2(num_re, PREC);
350
+ mpfr_init2(num_im, PREC);
351
+
352
+ mpc_init2(num_quotient, PREC);
353
+ mpc_init_set_r_r(num_numerator, a->re->n, a->im->n);
354
+ mpc_init_set_r_r(num_denominator, b->re->n, b->im->n);
355
+
356
+ mpc_div(num_quotient, num_numerator, num_denominator, MPC_RNDNN);
357
+
358
+ mpc_real(num_re, num_quotient, MPFR_RNDN);
359
+ mpc_imag(num_im, num_quotient, MPFR_RNDN);
360
+
361
+ re = (Interval*)interval_new((Real*)real_neg_inf(), true, (Real*)real_from_mpfr(num_re, ROUND_NEAREST), true, (Real*)real_pos_inf());
362
+ im = (Interval*)interval_new((Real*)real_neg_inf(), true, (Real*)real_from_mpfr(num_im, ROUND_NEAREST), true, (Real*)real_pos_inf());
363
+
364
+ mpc_clear(num_numerator);
365
+ mpc_clear(num_denominator);
366
+ mpc_clear(num_quotient);
367
+ mpfr_clear(num_re);
368
+ mpfr_clear(num_im);
369
+ }
370
+ else
371
+ {
372
+ re_re = (Interval*)interval_multiply(a->re, b->re);
373
+ re_im = (Interval*)interval_multiply(a->re, b->im);
374
+ im_re = (Interval*)interval_multiply(a->im, b->re);
375
+ im_im = (Interval*)interval_multiply(a->im, b->im);
376
+
377
+ numerator_re = (Interval*)interval_add(re_re, im_im);
378
+ numerator_im = (Interval*)interval_subtract(im_re, re_im);
379
+
380
+ re = (Interval*)interval_divide(numerator_re, denominator);
381
+ im = (Interval*)interval_divide(numerator_im, denominator);
382
+
383
+ interval_free(re_re);
384
+ interval_free(re_im);
385
+ interval_free(im_re);
386
+ interval_free(im_im);
387
+ interval_free(numerator_re);
388
+ interval_free(numerator_im);
389
+ }
390
+
391
+ interval_free(denominator_re);
392
+ interval_free(denominator_im);
393
+ interval_free(denominator);
394
+
395
+ return (Complex*)complex_new(re, im);
396
+ }
397
+
398
+ /*
399
+ * Returns a pointer to a newly allocated Complex containing a % b.
400
+ */
401
+ Complex* complex_modulo (Complex* a, Complex* b)
402
+ {
403
+ Interval* re;
404
+ Interval* im;
405
+
406
+ re = (Interval*)interval_zero();
407
+ im = (Interval*)interval_zero();
408
+
409
+ return (Complex*)complex_new(re, im);
410
+ }
411
+
412
+ /*
413
+ * Returns a pointer to a newly allocated Complex containing the absolute value
414
+ * of complex.
415
+ */
416
+ Complex* complex_abs (Complex* complex)
417
+ {
418
+ mpfr_t num_n_re;
419
+ mpfr_t num_ll_re;
420
+ mpfr_t num_lu_re;
421
+ mpfr_t num_ul_re;
422
+ mpfr_t num_uu_re;
423
+ mpfr_t num_re_abs;
424
+ mpfr_t num_im_abs;
425
+ mpc_t num_n;
426
+ mpc_t num_ll;
427
+ mpc_t num_lu;
428
+ mpc_t num_ul;
429
+ mpc_t num_uu;
430
+ Real* re_l_abs;
431
+ Real* re_u_abs;
432
+ Real* im_l_abs;
433
+ Real* im_u_abs;
434
+
435
+ Bounds* bounds;
436
+ Interval* re;
437
+
438
+ mpfr_init2(num_n_re, PREC);
439
+ mpfr_init2(num_ll_re, PREC);
440
+ mpfr_init2(num_lu_re, PREC);
441
+ mpfr_init2(num_ul_re, PREC);
442
+ mpfr_init2(num_uu_re, PREC);
443
+
444
+ mpc_init_set_r_r(num_n, complex->re->n, complex->im->n);
445
+ mpc_abs(num_n_re, num_n, MPC_RNDNN);
446
+
447
+ mpc_init_set_r_r(num_ll, complex->re->l, complex->im->l);
448
+ mpc_init_set_r_r(num_lu, complex->re->l, complex->im->u);
449
+ mpc_init_set_r_r(num_ul, complex->re->u, complex->im->l);
450
+ mpc_init_set_r_r(num_uu, complex->re->u, complex->im->u);
451
+
452
+ mpc_abs(num_ll_re, num_ll, MPC_RNDDD);
453
+ mpc_abs(num_lu_re, num_lu, MPC_RNDDU);
454
+ mpc_abs(num_ul_re, num_ul, MPC_RNDUD);
455
+ mpc_abs(num_uu_re, num_uu, MPC_RNDUU);
456
+
457
+ mpc_clear(num_n);
458
+ mpc_clear(num_ll);
459
+ mpc_clear(num_lu);
460
+ mpc_clear(num_ul);
461
+ mpc_clear(num_uu);
462
+
463
+ bounds = (Bounds*)bounds_new();
464
+ bounds_update_re(bounds, num_ll_re, complex->re->L);
465
+ bounds_update_re(bounds, num_lu_re, complex->re->L);
466
+ bounds_update_re(bounds, num_ul_re, complex->re->R);
467
+ bounds_update_re(bounds, num_uu_re, complex->re->R);
468
+
469
+ if (interval_span_zero_p(complex->im))
470
+ {
471
+ re_l_abs = (Real*)real_abs(complex->re->l);
472
+ re_u_abs = (Real*)real_abs(complex->re->u);
473
+
474
+ mpfr_init_set_r(num_re_abs, real_lt_p(re_l_abs, re_u_abs) ? re_l_abs : re_u_abs);
475
+ bounds_update_re(bounds, num_re_abs, true);
476
+
477
+ real_free(re_l_abs);
478
+ real_free(re_u_abs);
479
+
480
+ mpfr_clear(num_re_abs);
481
+ }
482
+
483
+ if (interval_span_zero_p(complex->re))
484
+ {
485
+ im_l_abs = (Real*)real_abs(complex->im->l);
486
+ im_u_abs = (Real*)real_abs(complex->im->u);
487
+
488
+ mpfr_init_set_r(num_im_abs, real_lt_p(im_l_abs, im_u_abs) ? im_l_abs : im_u_abs);
489
+ bounds_update_re(bounds, num_im_abs, true);
490
+
491
+ real_free(im_l_abs);
492
+ real_free(im_u_abs);
493
+
494
+ mpfr_clear(num_im_abs);
495
+ }
496
+
497
+ if (interval_span_zero_p(complex->re) && interval_span_zero_p(complex->im))
498
+ {
499
+ mpfr_set_zero(num_ll_re, 1);
500
+ bounds_update_re(bounds, num_ll_re, true);
501
+ }
502
+
503
+ re = (Interval*)interval_new(real_from_mpfr(bounds->re_min, ROUND_DOWN), bounds->re_min_closed, real_from_mpfr(num_n_re, ROUND_NEAREST), bounds->re_max_closed, real_from_mpfr(bounds->re_max, ROUND_UP1));
504
+
505
+ bounds_free(bounds);
506
+
507
+ mpfr_clear(num_n_re);
508
+ mpfr_clear(num_ll_re);
509
+ mpfr_clear(num_lu_re);
510
+ mpfr_clear(num_ul_re);
511
+ mpfr_clear(num_uu_re);
512
+
513
+ return complex_new(re, (Interval*)interval_zero());
514
+ }
515
+
516
+ /*
517
+ * Returns a pointer to a newly allocated Complex containing the area of the
518
+ * region in the complex plane enclosed by complex.
519
+ */
520
+ Complex* complex_area (Complex* complex)
521
+ {
522
+ Real* re_width;
523
+ Real* im_width;
524
+ Real* area;
525
+ Complex* result;
526
+
527
+ re_width = (Real*)real_subtract(complex->re->u, complex->re->l);
528
+ im_width = (Real*)real_subtract(complex->im->u, complex->im->l);
529
+ area = (Real*)real_multiply(re_width, im_width);
530
+ result = (Complex*)complex_from_real(area);
531
+
532
+ real_free(re_width);
533
+ real_free(im_width);
534
+ real_free(area);
535
+
536
+ return result;
537
+ }
538
+
539
+ /*
540
+ * Returns a pointer to a newly allocated Complex containing the length of the
541
+ * diagonal of the region in the complex plane enclosed by complex.
542
+ */
543
+ Complex* complex_diagonal (Complex* complex)
544
+ {
545
+ mpfr_t num_diag;
546
+ Real* re_width;
547
+ Real* im_width;
548
+ Real* re_width2;
549
+ Real* im_width2;
550
+ Real* diag2;
551
+ Interval* re;
552
+ Complex* result;
553
+
554
+ re_width = (Real*)real_subtract(complex->re->u, complex->re->l);
555
+ im_width = (Real*)real_subtract(complex->im->u, complex->im->l);
556
+
557
+ re_width2 = (Real*)real_multiply(re_width, re_width);
558
+ im_width2 = (Real*)real_multiply(im_width, im_width);
559
+
560
+ diag2 = (Real*)real_add(re_width2, im_width2);
561
+
562
+ mpfr_init_set_r(num_diag, diag2);
563
+ mpfr_sqrt(num_diag, num_diag, MPFR_RNDN);
564
+
565
+ re = (Interval*)interval_new((Real*)real_from_mpfr(num_diag, ROUND_DOWN), true, (Real*)real_from_mpfr(num_diag, ROUND_NEAREST), true, (Real*)real_from_mpfr(num_diag, ROUND_UP1));
566
+
567
+ real_free(re_width);
568
+ real_free(im_width);
569
+ real_free(re_width2);
570
+ real_free(im_width2);
571
+ real_free(diag2);
572
+
573
+ mpfr_clear(num_diag);
574
+
575
+ return (Complex*)complex_new(re, (Interval*)interval_zero());
576
+ }
577
+
578
+ /*
579
+ * Returns a pointer to a newly allocated Complex containing the conjugate of
580
+ * complex.
581
+ */
582
+ Complex* complex_conjugate (Complex* complex)
583
+ {
584
+ return complex_new((Interval*)interval_dup(complex->re), (Interval*)interval_negate(complex->im));
585
+ }
586
+
587
+ /*
588
+ * Returns a pointer to a newly allocated Complex containing -complex.
589
+ */
590
+ Complex* complex_negate (Complex* complex)
591
+ {
592
+ return complex_new((Interval*)interval_negate(complex->re), (Interval*)interval_negate(complex->im));
593
+ }
594
+
595
+ /*
596
+ * Returns a pointer to a newly allocated Complex containing the reflection of
597
+ * complex over the line re == im.
598
+ */
599
+ Complex* complex_reflect (Complex* complex)
600
+ {
601
+ return complex_new((Interval*)interval_dup(complex->im), (Interval*)interval_dup(complex->re));
602
+ }
603
+
604
+ /*
605
+ * Returns a pointer to a newly allocated Complex containing √complex.
606
+ */
607
+ Complex* complex_sqrt (Complex* complex)
608
+ {
609
+ mpfr_t num_n_re;
610
+ mpfr_t num_n_im;
611
+ mpc_t num_n;
612
+ mpc_t num_ll;
613
+ mpc_t num_lu;
614
+ mpc_t num_ul;
615
+ mpc_t num_uu;
616
+ mpc_t num_re_sqrt;
617
+ Real* zero;
618
+ Bounds* bounds;
619
+ Interval* re;
620
+ Interval* im;
621
+
622
+ mpfr_init2(num_n_re, PREC);
623
+ mpfr_init2(num_n_im, PREC);
624
+
625
+ mpc_init_set_r_r(num_n, complex->re->n, complex->im->n);
626
+ mpc_sqrt(num_n, num_n, MPC_RNDNN);
627
+ mpc_real(num_n_re, num_n, MPFR_RNDN);
628
+ mpc_imag(num_n_im, num_n, MPFR_RNDN);
629
+
630
+ mpc_init_set_r_r(num_ll, complex->re->l, complex->im->l);
631
+ mpc_init_set_r_r(num_lu, complex->re->l, complex->im->u);
632
+ mpc_init_set_r_r(num_ul, complex->re->u, complex->im->l);
633
+ mpc_init_set_r_r(num_uu, complex->re->u, complex->im->u);
634
+
635
+ mpc_sqrt(num_ll, num_ll, MPC_RNDDD);
636
+ mpc_sqrt(num_lu, num_lu, MPC_RNDDU);
637
+ mpc_sqrt(num_ul, num_ul, MPC_RNDUD);
638
+ mpc_sqrt(num_uu, num_uu, MPC_RNDUU);
639
+
640
+ bounds = (Bounds*)bounds_new();
641
+ bounds_update(bounds, num_ll, complex->re->L, complex->im->L);
642
+ bounds_update(bounds, num_lu, complex->re->L, complex->im->R);
643
+ bounds_update(bounds, num_ul, complex->re->R, complex->im->L);
644
+ bounds_update(bounds, num_uu, complex->re->R, complex->im->R);
645
+
646
+ if (interval_span_zero_p(complex->im))
647
+ {
648
+ zero = (Real*)real_zero();
649
+
650
+ mpc_init_set_r_r(num_re_sqrt, complex->re->l, zero);
651
+ mpc_sqrt(num_re_sqrt, num_re_sqrt, MPC_RNDDD);
652
+
653
+ bounds_update(bounds, num_re_sqrt, complex->re->L);
654
+
655
+ real_free(zero);
656
+ mpc_clear(num_re_sqrt);
657
+ }
658
+
659
+ re = (Interval*)interval_new(real_from_mpfr(bounds->re_min, ROUND_DOWN), bounds->re_min_closed, real_from_mpfr(num_n_re, ROUND_NEAREST), bounds->re_max_closed, real_from_mpfr(bounds->re_max, ROUND_UP1));
660
+ im = (Interval*)interval_new(real_from_mpfr(bounds->im_min, ROUND_DOWN), bounds->im_min_closed, real_from_mpfr(num_n_im, ROUND_NEAREST), bounds->im_max_closed, real_from_mpfr(bounds->im_max, ROUND_UP1));
661
+
662
+ bounds_free(bounds);
663
+
664
+ mpfr_clear(num_n_re);
665
+ mpfr_clear(num_n_im);
666
+
667
+ mpc_clear(num_n);
668
+ mpc_clear(num_ll);
669
+ mpc_clear(num_lu);
670
+ mpc_clear(num_ul);
671
+ mpc_clear(num_uu);
672
+
673
+ return complex_new(re, im);
674
+ }