Macaulay2 Engine
Loading...
Searching...
No Matches

◆ rawSetFareyApproximation()

void rawSetFareyApproximation ( mpq_ptr result,
gmp_RR x,
gmp_ZZ height )

Definition at line 83 of file random.cpp.

86{
87 int sgn;
88 mpfr_t fracpart, tmp1, tmp2;
89 mpz_t intpart, a, b, c, d, q, p;
90 mpq_t tmp3;
91
92 // get integer and fractional parts of |x|
93 sgn = mpfr_sgn(x);
94 mpfr_init2(fracpart, mpfr_get_prec(x));
95 mpfr_abs(fracpart, x, MPFR_RNDN);
96 mpz_init(intpart);
97 mpfr_get_z(intpart, fracpart, MPFR_RNDD);
98 mpfr_frac(fracpart, fracpart, MPFR_RNDN);
99
100 // goal: find nearest rational number to fracpart
101 // start w/ a/b = 0, p/q = 1/2, c/d = 1
102 mpfr_init2(tmp1, mpfr_get_prec(x));
103 mpfr_init2(tmp2, mpfr_get_prec(x));
104 mpz_init_set_ui(a, 0);
105 mpz_init_set_ui(b, 1);
106 mpz_init_set_ui(c, 1);
107 mpz_init_set_ui(d, 1);
108 mpz_init_set_ui(p, 1);
109 mpz_init_set_ui(q, 2);
110 mpq_init(tmp3);
111
112 // compute mediant p/q = (a+c)/(b+d) until q > height
113 while (mpz_cmp(q, height) <= 0) {
114 mpfr_mul_z(tmp1, fracpart, q, MPFR_RNDN);
115 // check if fracpart is to the left or right of p/q
116 // and update a/b or c/d accordingly
117 if (mpfr_cmp_z(tmp1, p) <= 0) {
118 mpz_set(c, p);
119 mpz_set(d, q);
120 } else {
121 mpz_set(a, p);
122 mpz_set(b, q);
123 }
124 mpz_add(p, a, c);
125 mpz_add(q, b, d);
126 }
127
128 // now check which endpoint is closest
129 // tmp1 = fracpart - a/b
130 mpfr_set_z(tmp1, a, MPFR_RNDN);
131 mpfr_neg(tmp1, tmp1, MPFR_RNDN);
132 mpfr_div_z(tmp1, tmp1, b, MPFR_RNDN);
133 mpfr_add(tmp1, tmp1, fracpart, MPFR_RNDN);
134
135 // tmp2 = c/d - fracpart
136 mpfr_set_z(tmp2, c, MPFR_RNDN);
137 mpfr_div_z(tmp2, tmp2, d, MPFR_RNDN);
138 mpfr_sub(tmp2, tmp2, fracpart, MPFR_RNDN);
139
140 if (mpfr_cmp(tmp1, tmp2) <= 0) {
141 mpq_set_z(result, a);
142 mpq_set_z(tmp3, b);
143 } else {
144 mpq_set_z(result, c);
145 mpq_set_z(tmp3, d);
146 }
147
148 // finally, add back intpart and negate if x < 0
149 mpq_div(result, result, tmp3);
150 mpq_set_z(tmp3, intpart);
151 mpq_add(result, result, tmp3);
152 mpq_set_si(tmp3, sgn, 1);
153 mpq_mul(result, result, tmp3);
154 mpq_canonicalize(result);
155
156 mpz_clears(intpart, a, b, c, d, p, q, nullptr);
157 mpfr_clears(fracpart, tmp1, tmp2, nullptr);
158 mpq_clear(tmp3);
159}
int p
VALGRIND_MAKE_MEM_DEFINED & result(result)
int sgn(const mpreal &op)
Definition mpreal.h:2781
volatile int x

References p, result(), and x.

Referenced by rawFareyApproximation().