number 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }