void check_consistency (void) { mpf_t x; unsigned long i, a, b; mpf_init (x); for (i = 1; i < 2000; i++) { mpf_set_prec (x, i); a = mpf_get_prec (x); mpf_set_prec (x, a); b = mpf_get_prec (x); if (a != b) { printf ("mpf_get_prec / mpf_set_prec inconsistent\n"); printf (" set %lu gives %lu, but then set %lu gives %lu\n", i, a, a, b); abort (); } } mpf_clear (x); }
/* Don't want to change the precision of w, can only do an actual swap when w and x have the same precision. */ static void e_mpf_set_or_swap (mpf_ptr w, mpf_ptr x) { if (mpf_get_prec (w) == mpf_get_prec (x)) mpf_swap (w, x); else mpf_set (w, x); }
/** * @brief Print a float to stdout (or whatever the output stream is * atm) respecting the given options, and only with the significant * digits. * * @param s A pointer to the current mps_context. * @param f The float approximation that should be printed. * @param rad The current inclusion radius for that approximation. * @param out_digit The number of output digits required. * @param sign The sign of the approximation. */ MPS_PRIVATE void mps_outfloat (mps_context * s, mpf_t f, rdpe_t rad, long out_digit, mps_boolean sign) { mpf_t t; rdpe_t r, ro; double d; long l, digit, true_digit; if (s->output_config->format == MPS_OUTPUT_FORMAT_FULL) { mpf_init2 (t, mpf_get_prec (f)); mpf_set (t, f); mpf_out_str (s->outstr, 10, 0, t); mpf_clear (t); return; } mpf_init2 (t, s->output_config->prec); mpf_get_rdpe (ro, f); if (s->output_config->format == MPS_OUTPUT_FORMAT_GNUPLOT || s->output_config->format == MPS_OUTPUT_FORMAT_GNUPLOT_FULL) rdpe_out_str_u (s->outstr, ro); else { rdpe_abs_eq (ro); if (rdpe_ne (ro, rdpe_zero)) rdpe_div (r, rad, ro); else rdpe_set_d (r, 1.0e-10); digit = (long)(-rdpe_log10 (r) - 0.5); if (digit <= 0) { rdpe_get_dl (&d, &l, ro); fprintf (s->outstr, "0.e%ld", l); } else { true_digit = (long)(LOG10_2 * mpf_get_prec (f)); true_digit = MIN (digit, true_digit); true_digit = MIN (true_digit, out_digit); if (sign) mpf_set (t, f); else mpf_abs (t, f); mpf_out_str (s->outstr, 10, true_digit, t); } } mpf_clear (t); }
static void mps_context_init (mps_context * s) { mpf_t test; /* Set default streams */ s->instr = stdin; s->outstr = stdout; s->logstr = stdout; /* Allocate space for the configurations */ s->input_config = (mps_input_configuration*)mps_malloc (sizeof(mps_input_configuration)); s->output_config = (mps_output_configuration*)mps_malloc (sizeof(mps_output_configuration)); mps_set_default_values (s); /* Find minimum GMP supported precision */ mpf_init2 (test, 1); s->minimum_gmp_precision = mpf_get_prec (test); mpf_clear (test); /* Set standard precision */ s->output_config->prec = (int)(0.9 * DBL_DIG * LOG2_10); MPS_DEBUG (s, "Setting prec_out to %ld digits", s->output_config->prec); mps_mp_set_prec (s, DBL_DIG * LOG2_10 + 1); s->initialized = false; s->exit_required = false; }
void coords_set_precision(coords* c, mpfr_prec_t precision) { mpf_t test; if (precision < DEFAULT_PRECISION) precision = DEFAULT_PRECISION; mpf_init2(test, precision); c->gmp_precision = mpf_get_prec(test); if ((unsigned long)c->gmp_precision > (unsigned long)precision) precision = c->gmp_precision; precision_change(c->xmin, precision); precision_change(c->xmax, precision); precision_change(c->ymin, precision); precision_change(c->ymax, precision); precision_change(c->cx, precision); precision_change(c->cy, precision); precision_change(c->width, precision); precision_change(c->height, precision); precision_change(c->_size, precision); c->precision = precision; c->size = (c->aspect > 1.0) ? &c->width : &c->height; mpf_clear(test); }
void extrapolate(index_t num_samples, mpf_t *samples, mpf_t ans) { // The Richardson extrapolation recursive formula is // // A_n+1(x) = (2^n A_n(2x) - A_n(x)) / (2^n - 1) mpf_t mult; // mult = 2^n mpf_init_set_d(mult, 1); mpf_t denom; // denom = 1 / (mult - 1) mp_bitcnt_t precision = mpf_get_prec(ans); mpf_init2(denom, precision); mpf_t *end = samples + num_samples; for (mpf_t *lim = samples; lim < end; lim++) { // lim - samples = n mpf_mul_ui(mult, mult, 2); mpf_set(denom, mult); mpf_sub_ui(denom, denom, 1); mpf_ui_div(denom, 1, denom); // evaluate all extrapolations for (mpf_t *ptr = end; --ptr > lim; ) { // A_n+1(x) = (mult A_n(2x) - A_n(x)) * denom mpf_mul(*ptr, *ptr, mult); mpf_sub(*ptr, *ptr, *(ptr - 1)); mpf_mul(*ptr, *ptr, denom); } } mpf_set(ans, *(end - 1)); // move to ans // Clean mpf_clear(mult); mpf_clear(denom); }
/* r = sqrt(x) */ void my_sqrt_ui(mpf_t r, unsigned long x) { unsigned long prec, bits, prec0; prec0 = mpf_get_prec(r); if (prec0<=DOUBLE_PREC) { mpf_set_d(r, sqrt(x)); return; } bits = 0; for (prec=prec0; prec>DOUBLE_PREC;) { int bit = prec&1; prec = (prec+bit)/2; bits = bits*2+bit; } mpf_set_prec_raw(t1, DOUBLE_PREC); mpf_set_d(t1, 1/sqrt(x)); while (prec<prec0) { prec *=2; if (prec<prec0) { /* t1 = t1+t1*(1-x*t1*t1)/2; */ mpf_set_prec_raw(t2, prec); mpf_mul(t2, t1, t1); /* half x half -> full */ mpf_mul_ui(t2, t2, x); mpf_ui_sub(t2, 1, t2); mpf_set_prec_raw(t2, prec/2); mpf_div_2exp(t2, t2, 1); mpf_mul(t2, t2, t1); /* half x half -> half */ mpf_set_prec_raw(t1, prec); mpf_add(t1, t1, t2); } else { break; } prec -= (bits&1); bits /=2; } /* t2=x*t1, t1 = t2+t1*(x-t2*t2)/2; */ mpf_set_prec_raw(t2, prec0/2); mpf_mul_ui(t2, t1, x); mpf_mul(r, t2, t2); /* half x half -> full */ mpf_ui_sub(r, x, r); mpf_mul(t1, t1, r); /* half x half -> half */ mpf_div_2exp(t1, t1, 1); mpf_add(r, t1, t2); }
// r = sqrt(x) void my_sqrt(mpf_t r, mpf_t x) { unsigned prec, bits, prec0; prec0 = mpf_get_prec(r); if (prec0 <= DOUBLE_PREC) { mpf_set_d(r, sqrt(mpf_get_d(x))); return; } bits = 0; for (prec = prec0; prec > DOUBLE_PREC;) { int bit = prec & 1; prec = (prec + bit) / 2; bits = bits * 2 + bit; } mpf_set_prec_raw(t1, DOUBLE_PREC); mpf_set_d(t1, 1 / sqrt(mpf_get_d(x))); while (prec < prec0) { prec *= 2; /*printf("prec=%d, prec0=%d\n", prec, prec0); */ if (prec < prec0) { /* t1 = t1+t1*(1-x*t1*t1)/2; */ mpf_set_prec_raw(t2, prec); mpf_mul(t2, t1, t1); mpf_set_prec_raw(x, prec/2); mpf_mul(t2, t2, x); mpf_ui_sub(t2, 1, t2); mpf_set_prec_raw(t2, prec/2); mpf_div_2exp(t2, t2, 1); mpf_mul(t2, t2, t1); mpf_set_prec_raw(t1, prec); mpf_add(t1, t1, t2); } else { prec = prec0; /* t2=x*t1, t1 = t2+t1*(x-t2*t2)/2; */ mpf_set_prec_raw(t2, prec/2); mpf_set_prec_raw(x, prec/2); mpf_mul(t2, t1, x); mpf_mul(r, t2, t2); mpf_set_prec_raw(x, prec); mpf_sub(r, x, r); mpf_mul(t1, t1, r); mpf_div_2exp(t1, t1, 1); mpf_add(r, t1, t2); break; } prec -= (bits & 1); bits /= 2; } }
libmaus2::math::GmpFloat libmaus2::math::operator/( libmaus2::math::GmpFloat const & #if defined(LIBMAUS2_HAVE_GMP) A #endif , libmaus2::math::GmpFloat const & #if defined(LIBMAUS2_HAVE_GMP) B #endif ) { unsigned int const outprec = #if defined(LIBMAUS2_HAVE_GMP) std::max(mpf_get_prec(decode(A.v)),mpf_get_prec(decode(B.v))); #else 0; #endif libmaus2::math::GmpFloat R(0,outprec); #if defined(LIBMAUS2_HAVE_GMP) mpf_div(decode(R.v),decode(A.v),decode(B.v)); #endif return R; }
void check_one (mpf_srcptr src, mpf_srcptr trunc, mpf_srcptr ceil, mpf_srcptr floor) { mpf_t got; mpf_init2 (got, mpf_get_prec (trunc)); ASSERT_ALWAYS (PREC(got) == PREC(trunc)); ASSERT_ALWAYS (PREC(got) == PREC(ceil)); ASSERT_ALWAYS (PREC(got) == PREC(floor)); #define CHECK_SEP(name, fun, want) \ mpf_set_ui (got, 54321L); /* initial junk */ \ fun (got, src); \ MPF_CHECK_FORMAT (got); \ if (mpf_cmp (got, want) != 0) \ { \ printf ("%s wrong\n", name); \ check_print (src, got, want); \ abort (); \ } CHECK_SEP ("mpf_trunc", mpf_trunc, trunc); CHECK_SEP ("mpf_ceil", mpf_ceil, ceil); CHECK_SEP ("mpf_floor", mpf_floor, floor); #define CHECK_INPLACE(name, fun, want) \ mpf_set (got, src); \ fun (got, got); \ MPF_CHECK_FORMAT (got); \ if (mpf_cmp (got, want) != 0) \ { \ printf ("%s wrong\n", name); \ check_print (src, got, want); \ abort (); \ } CHECK_INPLACE ("mpf_trunc", mpf_trunc, trunc); /* Can't do these unconditionally in case truncation by mpf_set strips some low non-zero limbs which would have rounded the result. */ if (ABSIZ(src) <= PREC(trunc)+1) { CHECK_INPLACE ("mpf_ceil", mpf_ceil, ceil); CHECK_INPLACE ("mpf_floor", mpf_floor, floor); } mpf_clear (got); }
// r = y/x WARNING: r cannot be the same as y. void my_div(mpf_t r, mpf_t y, mpf_t x) { unsigned long prec, bits, prec0; prec0 = mpf_get_prec(r); if (prec0<=DOUBLE_PREC) { mpf_set_d(r, mpf_get_d(y)/mpf_get_d(x)); return; } bits = 0; for (prec=prec0; prec>DOUBLE_PREC;) { int bit = prec&1; prec = (prec+bit)/2; bits = bits*2+bit; } mpf_set_prec_raw(t1, DOUBLE_PREC); mpf_ui_div(t1, 1, x); while (prec<prec0) { prec *=2; if (prec<prec0) { /* t1 = t1+t1*(1-x*t1); */ mpf_set_prec_raw(t2, prec); mpf_mul(t2, x, t1); // full x half -> full mpf_ui_sub(t2, 1, t2); mpf_set_prec_raw(t2, prec/2); mpf_mul(t2, t2, t1); // half x half -> half mpf_set_prec_raw(t1, prec); mpf_add(t1, t1, t2); } else { prec = prec0; /* t2=y*t1, t1 = t2+t1*(y-x*t2); */ mpf_set_prec_raw(t2, prec/2); mpf_mul(t2, t1, y); // half x half -> half mpf_mul(r, x, t2); // full x half -> full mpf_sub(r, y, r); mpf_mul(t1, t1, r); // half x half -> half mpf_add(r, t1, t2); break; } prec -= (bits&1); bits /=2; } }
libmaus2::math::GmpFloat & libmaus2::math::GmpFloat::operator=( GmpFloat const & #if defined(LIBMAUS2_HAVE_GMP) o #endif ) { #if defined(LIBMAUS2_HAVE_GMP) if ( this != &o ) { mpf_set_prec(decode(v),mpf_get_prec(decode(o.v))); mpf_set(decode(v),decode(o.v)); } #endif return *this; }
void extrapolate(index_t num_samples, index_t start_index, SequenceFunc f, mpf_t ans) { // Calculate the desired samples, then pass to the other extrapolate // function. mpf_t *samples = (mpf_t*)malloc(sizeof(mpf_t) * num_samples); mpf_t *lim = samples + num_samples; mp_bitcnt_t precision = mpf_get_prec(ans); for (mpf_t *ptr = samples; ptr < lim; ptr++, start_index <<= 1) { mpf_init2(*ptr, precision); f(start_index, *ptr); } extrapolate(num_samples, samples, ans); // Clean for (mpf_t *ptr = samples; ptr < lim; ptr++) mpf_clear(*ptr); free(samples); }
int mpf_expr (mpf_ptr res, int base, const char *e, ...) { mpf_srcptr var[MPEXPR_VARIABLES]; va_list ap; int ret; va_start (ap, e); TRACE (printf ("mpf_expr(): base %d, %s\n", base, e)); ret = mpexpr_va_to_var ((void **) var, ap); va_end (ap); if (ret != MPEXPR_RESULT_OK) return ret; return mpf_expr_a (mpf_expr_standard_table, res, base, mpf_get_prec (res), e, strlen(e), var); }
static void mpf_normalize(mpf_t op) { Py_ssize_t size, prec, toclear, temp, i; mp_limb_t bit1, rem, carry; prec = mpf_get_prec(op); size = mpf_size(op); toclear = size - ((prec / GMP_NUMB_BITS) + 1); if(toclear>0) { bit1 = (op->_mp_d[toclear-1] & ((mp_limb_t)1 << (GMP_NUMB_BITS - 1))) ? 1 : 0; rem = (op->_mp_d[toclear-1] & (((mp_limb_t)1 << (GMP_NUMB_BITS - 1)) - 1)) ? 1 : 0; carry = bit1 && ((op->_mp_d[toclear] & 1) || rem); } else { carry = 0; } if(options.debug) { fprintf(stderr, "prec %ld size %ld toclear %ld carry %ld\n", prec, size, toclear, carry); for(i=0; i<size; i++) fprintf(stderr,"[%zd]=%lx\n", i, op->_mp_d[i]); } temp = toclear; if(temp>0) { op->_mp_d[--temp] = 0; } if(carry) { if(options.debug) { fprintf(stderr, "adding carry bit\n"); } carry = mpn_add_1(op->_mp_d + toclear, op->_mp_d + toclear, size-toclear, carry); if(carry) { if(options.debug) { fprintf(stderr, "carry bit extended\n"); } op->_mp_d[size-1] = 1; op->_mp_exp++; } } if(options.debug) { for(i=0; i<size; i++) fprintf(stderr,"[%zd]=%lx\n", i, op->_mp_d[i]); } }
void mpf_pow_ui (mpf_ptr r, mpf_srcptr b, unsigned long int e) { mpf_t b2; mpf_init2 (b2, mpf_get_prec (r)); mpf_set (b2, b); if ((e & 1) != 0) mpf_set (r, b); else mpf_set_ui (r, 1); while (e >>= 1) { mpf_mul (b2, b2, b2); if ((e & 1) != 0) mpf_mul (r, r, b2); } mpf_clear (b2); }
void mpf_pow_ui (mpf_ptr r, mpf_srcptr b, unsigned long int e) { mpf_t b2; unsigned long int e2; mpf_init2 (b2, mpf_get_prec (r)); mpf_set (b2, b); mpf_set_ui (r, 1); if ((e & 1) != 0) mpf_set (r, b2); for (e2 = e >> 1; e2 != 0; e2 >>= 1) { mpf_mul (b2, b2, b2); if ((e2 & 1) != 0) mpf_mul (r, r, b2); } mpf_clear (b2); }
void keyboard(uint8_t key, int32_t x, int32_t y) { FILE *file; int32_t base = 10; switch (key) { case 27: // ESC stopThreads(); exit(0); break; case 105: // i maxIterations+=iterDelta; printf("Iterationen: %u\n",maxIterations); restart(); break; case 111: // o maxIterations-=iterDelta; if (maxIterations <= 0) { maxIterations+=iterDelta; } printf("Iterationen: %u\n",maxIterations); restart(); break; case 115: // s printf("Speichere Position\n"); file = fopen("minRe.val", "w"); mpf_out_str(file, base, 0, mandelRange.minRe); fclose(file); file = fopen("maxRe.val", "w"); mpf_out_str(file, base, 0, mandelRange.maxRe); fclose(file); file = fopen("minIm.val", "w"); mpf_out_str(file, base, 0, mandelRange.minIm); fclose(file); file = fopen("iter.val", "wb"); fwrite(&maxIterations, sizeof(maxIterations), 1, file); fclose(file); file = fopen("bits.val", "wb"); fwrite(&gmpBit, sizeof(gmpBit), 1, file); fclose(file); printf("Position gespeichert\n"); break; case 108: // l loadPosition(); restart(); break; case 98: //b gmpBit+=1; printf("Bit: %i\n",gmpBit); setBits(gmpBit); restart(); break; case 99: // c printf("aktuelle Bits: %lu\n",mpf_get_prec(mandelRange.minRe)); break; // case 103: // g // useGMP = useGMP ? 0 : 1; // printf("benutze GMP: %i\n",useGMP); // break; default: printf("%i\n",key); break; } }
uint mpfc_getdigits(mpfc_ptr x) { return (uint)(mpf_get_prec(x->Im)/3.3219280948873623478703194294894); }
int main(int argc, char** argv) { // Computation parameters int maxiter, maxIterStart, maxIterEnd; int iterStep; int flag; int comm_sz, my_rank; time_t t1, t2; double delta, maxTime; int i; int *iterations; // Video parameters unsigned long int width, height; int frames, curframe; int startframe, endframe; int fps, vidLen; float zoomx, zoomy; mpf_t framezoomx, framezoomy; // File name variables char *filename; char filenum [10]; char *fileext = ".bmp"; char *image = ""; // GMP Floats mpf_t cr, ci; mpf_init(cr); mpf_init(ci); mpf_t xcent, ycent; mpf_init(xcent); mpf_init(ycent); mpf_t xrInit, yrInit, xrFin, yrFin; mpf_init(xrInit); mpf_init(yrInit); mpf_init(xrFin); mpf_init(yrFin); // Get and parse the program parameters and set GMP precision getParams(argv, &flag, &cr, &ci, &xcent, &ycent, &xrInit, &yrInit, &xrFin, &yrFin, &width, &height, &maxIterStart, &maxIterEnd, &filename, &fps, &vidLen, &startframe, &endframe); mpf_set_default_prec(mpf_get_prec(cr)); // Calculate number of frames in the video frames = fps * vidLen; // Calculate number of iterations to add per frame iterStep = ceil((2*(double)maxIterEnd - 2*(double)maxIterStart) / (double)frames); // Calculate zoom rate based on the number of frames; since the first frame is not zoomed // in on, we calculate zoom with frame count (totalframes - 1) // x and y zoom are calculated separately to avoid stretching images zoomx = pow((float)mpf_get_d(xrInit) / (float)mpf_get_d(xrFin), 1.0/((float)frames - 1)); mpf_init(framezoomx); mpf_set_d(framezoomx, (double)zoomx); zoomy = pow((float)mpf_get_d(yrInit) / (float)mpf_get_d(yrFin), 1.0/((float)frames - 1)); mpf_init(framezoomy); mpf_set_d(framezoomy, (double)zoomy); /* Start MPI */ MPI_Init(NULL, NULL); MPI_Comm_size(MPI_COMM_WORLD, &comm_sz); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); // Debugging output int n = 35; if (my_rank == 0) { gmp_printf ("x = %+.*Ff\n", n, xcent); gmp_printf ("xr Init = %+.*Ff\n", n, xrInit); gmp_printf ("xr Fin = %+.*Ff\n\n", n, xrFin); gmp_printf ("y = %+.*Ff\n", n, ycent); gmp_printf ("yr Init = %+.*Ff\n", n, yrInit); gmp_printf ("yr Fin = %+.*Ff\n\n", n, yrFin); printf("Height = %ld\t", height); printf("Width = %ld\n", width); printf("maxiterStart = %d\t", maxIterStart); printf("maxiterEnd = %d\t", maxIterEnd); printf("iterStep = %d\n\n", iterStep); gmp_printf ("Zoom x (GMP) = %+.*Ff\n", n, framezoomx); gmp_printf ("Zoom y (GMP) = %+.*Ff\n", n, framezoomy); printf("frames = %d\n\n", frames); } // Divide frames among processes startframe = startframe - 1; // Offset frame divisions endframe = endframe - 1; frames = endframe - startframe + 1; // Total frames + 1 to include end bound int totalframes = frames / comm_sz; if (my_rank < (frames % comm_sz)) totalframes++; printf("Process %d processess %d frames\n", my_rank, totalframes); // Start timer time(&t1); /* Start OpenMP */ #pragma omp parallel shared(width, height, xcent, ycent, xrInit, yrInit, maxIterStart, iterStep, framezoomx, framezoomy) private(i, iterations, filenum, image, curframe, maxiter) { /* Variables and memory declared in this section are private to each thread */ // Allocate space for the image iterations = (int*)calloc( width * height, sizeof(int) ); assert(iterations != NULL); // Allocate space for the filenames image = malloc(strlen(filename) + 5 + strlen(fileext)); // GMP variables to stored distance from center point in mpf_t xmin, xmax, ymin, ymax; mpf_init(xmin); mpf_init(xmax); mpf_init(ymin); mpf_init(ymax); /* Start OpenMP parallel FOR */ #pragma omp for for ( i = 0; i < totalframes; i++ ) { curframe = my_rank + (i * comm_sz) + startframe; maxiter = maxIterStart + (iterStep * curframe); printf("Process %d working on frame %d with thread %d\n", my_rank, curframe + 1, omp_get_thread_num()); // xmin, xmax, ymin and ymax if (curframe == 0) { // Do not zoom for the first image mpf_sub(xmin, xcent, xrInit); mpf_add(xmax, xcent, xrInit); mpf_sub(ymin, ycent, yrInit); mpf_add(ymax, ycent, yrInit); } else { // Radius is calculated as r = rinit / (zoom^frame#) mpf_pow_ui(xmax, framezoomx, (unsigned long int)curframe); mpf_div(xmax, xrInit, xmax); mpf_pow_ui(ymax, framezoomy, (unsigned long int)curframe); mpf_div(ymax, yrInit, ymax); mpf_sub(xmin, xcent, xmax); mpf_add(xmax, xcent, xmax); mpf_sub(ymin, ycent, ymax); mpf_add(ymax, ycent, ymax); } /* Compute Julia set */ GMPJulia(xmin, xmax, width, width, 0, ymin, ymax, height, height, 0, cr, ci, flag, maxiter, iterations); /* Save image as a bitmap (.bmp) */ sprintf(filenum, "%05d", curframe + 1); strcpy(image, filename); strcat(image, filenum); strcat(image, fileext); printf("\nProcess %d creating frame %d on thread %d...", my_rank, curframe + 1, omp_get_thread_num()); saveBMP(image, iterations, width, height); } // Free thread-reserved memory free(iterations); free(image); mpf_clear(xmin); mpf_clear(xmax); mpf_clear(ymin); mpf_clear(ymax); } // Stop timer and calculate elapsed time time(&t2); delta = difftime(t2, t1); MPI_Reduce(&delta, &maxTime, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); if (my_rank == 0) printf("Computation time = %lf\n", maxTime); // Close MPI environment MPI_Finalize(); // Free reserved memory //mpf_clears(cr, ci, x, y, xr, yr, xmin, xmax, ymin, ymax, (mpf_t *) 0); mpf_clear(cr); mpf_clear(ci); mpf_clear(xcent); mpf_clear(ycent); mpf_clear(xrInit); mpf_clear(yrInit); mpf_clear(xrFin); mpf_clear(yrFin); mpf_clear(framezoomx); mpf_clear(framezoomy); return 0; }