void solve_vertex(amath_float a, amath_float b, amath_float c) { //Side work amath_float b2 = b / a; b2 /= 2; amath_float cs = aexp(b2, 2); //New c value //End side work amath_float neg_cs = anegate(cs); amath_float vtx_y = c + neg_cs; //Balance equation amath_float vtx_x = sqrt(cs); //Complete the square if (b < 0) vtx_x = anegate(vtx_x); //"Drop" minus sign if b is negative cout << "VERTEX FORM: y = (x + " << static_cast<string>(vtx_x) << ")² + " << static_cast<string>(vtx_y) << endl; amath_float neg_vtx_x = anegate(vtx_x); cout << "VERTEX: (" << static_cast<string>(neg_vtx_x) << ", " << static_cast<string>(vtx_y) << ")" << endl; amath_float neg_b = anegate(b); amath_float a2 = a * 2; amath_float vtx_x_verify = neg_b / a2; if (vtx_x_verify == neg_vtx_x) cout << "VERIFIED - Good vertex." << endl; else { cout << "NOT VERIFIED - Bad vertex. If you can manually verify this vertex (-b / 2a = vertex x) then please report this error on the GitHub repository." << endl; cout << a2 << endl << neg_b << endl << neg_vtx_x << endl; } }
double gen_beta(const gen_beta_param *gen) { /* The following temporaries are recomputed on each iteration, * or restored from gen->param array. */ double c,r,s,t,u1,u2,v,w,z,lambda; double logv, logw, log_sum; double a = gen->a; double b = gen->b; double min_ab = gen->min_ab; double max_ab = gen->max_ab; double sum_ab = gen->sum_ab; if (max_ab<0.5) { /* Use Joehnk's algorithm. * Use logv and logw, rather than v and w, to avoid * floating-point underflow with very small a or b values. */ do { u1 = DRAND(); u2 = DRAND(); logv = log(u1)/a; logw = log(u2)/b; log_sum = logv>logw? logv + log(1+ exp(logw-logv)) : logw + log(1+ exp(logv-logw)); } while (log_sum>0.0); assert(logv<=log_sum); return exp(logv - log_sum); } if (min_ab > 1.0) { /* use Algorithm BB */ lambda = gen->param[0]; c = gen->param[1]; do { u1 = DRAND(); u2 = DRAND(); v = lambda*log(u1/(1.0-u1)); w = aexp(min_ab,v); z = u1*u1*u2; r = c*v-1.38629436112; s = min_ab+r-w; if(s+2.609438 >= 5.0*z) break; t = log(z); } while ( /* s<=t && */ r+sum_ab*log(sum_ab/(max_ab+w)) < t); return ret(a,min_ab, max_ab, w); } if (max_ab>= 1.0) { /* use Atkinson's switching method, as * described in Dagpunar's book * p=min_ab, q=max_ab * t stored as gen->param[0], r as gen->param[1] */ t = gen->param[0]; r = gen->param[1]; for(;;) { u1 = DRAND(); u2 = DRAND(); if (u1 < r) { w = t*pow(u1/r, 1/min_ab); if (log(u2) < (max_ab -1)*log(1-w)) break; } else { w = 1- (1-t)*pow((1-u1)/(1-r), 1/max_ab); if (log(u2) < (min_ab -1) * log(w/t)) break; } } return (a==min_ab)? w : 1-w; } else { /* use Atkinson's Algorithm */ t = gen->param[0]; r = gen->param[1]; for(;;) { u1 = DRAND(); u2 = DRAND(); if (u1 < r) { w = t*pow(u1/r, 1/min_ab); if (log(u2) < (max_ab -1)*log((1-w)/(1-t))) break; } else { w = 1- (1-t)*pow((1-u1)/(1-r), 1/max_ab); if (log(u2) < (min_ab -1) * log(w/t)) break; } } return (a==min_ab)? w : 1-w; } }