void _acb_poly_revert_series_lagrange_fast(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong n, slong prec) { slong i, j, k, m; acb_ptr R, S, T, tmp; acb_t t; if (n <= 2) { if (n >= 1) acb_zero(Qinv); if (n == 2) acb_inv(Qinv + 1, Q + 1, prec); return; } m = n_sqrt(n); acb_init(t); R = _acb_vec_init((n - 1) * m); S = _acb_vec_init(n - 1); T = _acb_vec_init(n - 1); acb_zero(Qinv); acb_inv(Qinv + 1, Q + 1, prec); _acb_poly_inv_series(Ri(1), Q + 1, FLINT_MIN(Qlen, n) - 1, n - 1, prec); for (i = 2; i <= m; i++) _acb_poly_mullow(Ri(i), Ri((i + 1) / 2), n - 1, Ri(i / 2), n - 1, n - 1, prec); for (i = 2; i < m; i++) acb_div_ui(Qinv + i, Ri(i) + i - 1, i, prec); _acb_vec_set(S, Ri(m), n - 1); for (i = m; i < n; i += m) { acb_div_ui(Qinv + i, S + i - 1, i, prec); for (j = 1; j < m && i + j < n; j++) { acb_mul(t, S + 0, Ri(j) + i + j - 1, prec); for (k = 1; k <= i + j - 1; k++) acb_addmul(t, S + k, Ri(j) + i + j - 1 - k, prec); acb_div_ui(Qinv + i + j, t, i + j, prec); } if (i + 1 < n) { _acb_poly_mullow(T, S, n - 1, Ri(m), n - 1, n - 1, prec); tmp = S; S = T; T = tmp; } } acb_clear(t); _acb_vec_clear(R, (n - 1) * m); _acb_vec_clear(S, n - 1); _acb_vec_clear(T, n - 1); }
void _acb_poly_evaluate_rectangular(acb_t y, acb_srcptr poly, slong len, const acb_t x, slong prec) { slong i, j, m, r; acb_ptr xs; acb_t s, t, c; if (len < 3) { if (len == 0) { acb_zero(y); } else if (len == 1) { acb_set_round(y, poly + 0, prec); } else if (len == 2) { acb_mul(y, x, poly + 1, prec); acb_add(y, y, poly + 0, prec); } return; } m = n_sqrt(len) + 1; r = (len + m - 1) / m; xs = _acb_vec_init(m + 1); acb_init(s); acb_init(t); acb_init(c); _acb_vec_set_powers(xs, x, m + 1, prec); acb_set(y, poly + (r - 1) * m); for (j = 1; (r - 1) * m + j < len; j++) acb_addmul(y, xs + j, poly + (r - 1) * m + j, prec); for (i = r - 2; i >= 0; i--) { acb_set(s, poly + i * m); for (j = 1; j < m; j++) acb_addmul(s, xs + j, poly + i * m + j, prec); acb_mul(y, y, xs + m, prec); acb_add(y, y, s, prec); } _acb_vec_clear(xs, m + 1); acb_clear(s); acb_clear(t); acb_clear(c); }
void _acb_poly_compose_series_brent_kung(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long n, long prec) { acb_mat_t A, B, C; acb_ptr t, h; long i, m; if (n == 1) { acb_set(res, poly1); return; } m = n_sqrt(n) + 1; acb_mat_init(A, m, n); acb_mat_init(B, m, m); acb_mat_init(C, m, n); h = _acb_vec_init(n); t = _acb_vec_init(n); /* Set rows of B to the segments of poly1 */ for (i = 0; i < len1 / m; i++) _acb_vec_set(B->rows[i], poly1 + i*m, m); _acb_vec_set(B->rows[i], poly1 + i*m, len1 % m); /* Set rows of A to powers of poly2 */ acb_set_ui(A->rows[0] + 0, 1UL); _acb_vec_set(A->rows[1], poly2, len2); for (i = 2; i < m; i++) _acb_poly_mullow(A->rows[i], A->rows[(i + 1) / 2], n, A->rows[i / 2], n, n, prec); acb_mat_mul(C, B, A, prec); /* Evaluate block composition using the Horner scheme */ _acb_vec_set(res, C->rows[m - 1], n); _acb_poly_mullow(h, A->rows[m - 1], n, poly2, len2, n, prec); for (i = m - 2; i >= 0; i--) { _acb_poly_mullow(t, res, n, h, n, n, prec); _acb_poly_add(res, t, n, C->rows[i], n, prec); } _acb_vec_clear(h, n); _acb_vec_clear(t, n); acb_mat_clear(A); acb_mat_clear(B); acb_mat_clear(C); }
int main(void) { int i, j, result; flint_rand_t state; flint_randinit(state); printf("factor_trial_partial...."); fflush(stdout); for (i = 0; i < 10000; i++) /* Test random numbers */ { mp_limb_t n1, n2, prod, limit; n_factor_t factors; n_factor_init(&factors); n1 = n_randtest_not_zero(state); limit = n_sqrt(n1); n2 = n_factor_trial_partial(&factors, n1, &prod, 10000UL, limit); if (n1 != n2*prod) { printf("FAIL:\n"); printf("n1 = %lu, n2 = %lu, prod = %lu\n", n1, n2, prod); abort(); } for (j = 0; j < factors.num; j++) { n2 *= n_pow(factors.p[j], factors.exp[j]); } result = (n1 == n2); if (!result) { printf("FAIL:\n"); printf("n1 = %lu, n2 = %lu\n", n1, n2); abort(); } } flint_randclear(state); printf("PASS\n"); return 0; }
bool CSensorVision::SenseStimulus(CActor* pActor, CStimulus* pStimulus) const { if (pStimulus->Intensity <= 0.f) OK; // Cast to stimulus visible //!!!take size/radius into account:! //!!!FOV & size! check pos before as faster check, if ok check bounds by FOV? //???check visible shape, not only position point? or get radius of stimulus and check against cylinder? //y can be projected (clamped by cylinder top & bottom) vector3 DirToStimulus = pStimulus->Position - pActor->Position; float SqDist = DirToStimulus.lensquared(); if (SqDist <= Radius * Radius) { float Confidence = pStimulus->Intensity; //!!!calc by formula, use distance! bool IsInFOV = FOV < -0.999f; // For 360 degrees vision if (!IsInFOV) { DirToStimulus /= n_sqrt(SqDist); IsInFOV = pActor->LookatDir.dot(DirToStimulus) >= FOV; //!!!adjust confidence by peripheral vision! } if (IsInFOV) { //!!!occlusion & line of sight! other objects can occlude this! //partial occlusion can reduce confidence if (Confidence > 0.f) { nArray<PPerceptor>::iterator ItPerceptor; for (ItPerceptor = Perceptors.Begin(); ItPerceptor != Perceptors.End(); ItPerceptor++) (*ItPerceptor)->ProcessStimulus(pActor, pStimulus, Confidence); } } } //???!!!if time-sliced, fail?! OK; }
EExecStatus CSensorVision::ValidateFact(CActor* pActor, const CMemFact& Fact) const { const CMemFactObstacle& Obstacle = (const CMemFactObstacle&)Fact; if (Fact.LastUpdateTime == Fact.LastPerceptionTime && (!Obstacle.pSourceStimulus || !Obstacle.pSourceStimulus->IsActive() || Obstacle.pSourceStimulus->Intensity <= 0.f)) return Failure; //!!!CODE DUPLICATION! vector3 DirToFact = Obstacle.Position - pActor->Position; float SqDist = DirToFact.lensquared(); if (SqDist <= Radius * Radius) { bool IsInFOV = FOV < -0.999f; // For 360 degrees vision if (!IsInFOV) { DirToFact /= n_sqrt(SqDist); IsInFOV = pActor->LookatDir.dot(DirToFact) >= FOV; //!!!if peripheral vision reduces confidence to 0, skip! } if (IsInFOV) { //!!!occlusion & line of sight! other objects can occlude this! //take into account only complete occlusion //if (Confidence > 0.f) return Failure; } } // We didn't see source stimulus this frame, so we don't know is fact relevant return Running; }
void _fmpq_poly_revert_series_lagrange_fast(fmpz * Qinv, fmpz_t den, const fmpz * Q, const fmpz_t Qden, slong n) { slong i, j, k, m; fmpz *R, *Rden, *S, *T, *dens, *tmp; fmpz_t Sden, Tden, t; if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1)) { _fmpz_poly_revert_series(Qinv, Q, n); fmpz_one(den); return; } if (n <= 2) { fmpz_zero(Qinv); if (n == 2) { fmpz_set(Qinv + 1, Qden); fmpz_set(den, Q + 1); _fmpq_poly_canonicalise(Qinv, den, 2); } return; } m = n_sqrt(n); fmpz_init(t); dens = _fmpz_vec_init(n); R = _fmpz_vec_init((n - 1) * m); S = _fmpz_vec_init(n - 1); T = _fmpz_vec_init(n - 1); Rden = _fmpz_vec_init(m); fmpz_init(Sden); fmpz_init(Tden); fmpz_zero(Qinv); fmpz_one(dens); _fmpq_poly_inv_series(Ri(1), Rdeni(1), Q + 1, Qden, n - 1); _fmpq_poly_canonicalise(Ri(1), Rdeni(1), n - 1); for (i = 2; i <= m; i++) { _fmpq_poly_mullow(Ri(i), Rdeni(i), Ri(i-1), Rdeni(i-1), n - 1, Ri(1), Rdeni(1), n - 1, n - 1); _fmpq_poly_canonicalise(Ri(i), Rdeni(i), n - 1); } for (i = 1; i < m; i++) { fmpz_set(Qinv + i, Ri(i) + i - 1); fmpz_mul_ui(dens + i, Rdeni(i), i); } _fmpz_vec_set(S, Ri(m), n - 1); fmpz_set(Sden, Rdeni(m)); for (i = m; i < n; i += m) { fmpz_set(Qinv + i, S + i - 1); fmpz_mul_ui(dens + i, Sden, i); for (j = 1; j < m && i + j < n; j++) { fmpz_mul(t, S + 0, Ri(j) + i + j - 1); for (k = 1; k <= i + j - 1; k++) fmpz_addmul(t, S + k, Ri(j) + i + j - 1 - k); fmpz_set(Qinv + i + j, t); fmpz_mul(dens + i + j, Sden, Rdeni(j)); fmpz_mul_ui(dens + i + j, dens + i + j, i + j); } if (i + 1 < n) { _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, Ri(m), Rdeni(m), n - 1, n - 1); _fmpq_poly_canonicalise(T, Tden, n - 1); fmpz_swap(Tden, Sden); tmp = S; S = T; T = tmp; } } _set_vec(Qinv, den, Qinv, dens, n); _fmpq_poly_canonicalise(Qinv, den, n); fmpz_clear(t); _fmpz_vec_clear(dens, n); _fmpz_vec_clear(R, (n - 1) * m); _fmpz_vec_clear(S, n - 1); _fmpz_vec_clear(T, n - 1); _fmpz_vec_clear(Rden, m); fmpz_clear(Sden); fmpz_clear(Tden); }
void acb_hypgeom_pfq_sum_fme(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) { acb_poly_t A, B, C; acb_ptr ks, As, Bs, Cs; acb_t u, v; acb_ptr * tree; slong i, k, m, w; /* we compute to n-1 instead of n to avoid dividing by 0 in the denominator when computing a hypergeometric polynomial that terminates right before a pole */ if (n > 4) { m = n_sqrt(n - 1) / 4; /* tuning parameter */ w = (n - 1) / FLINT_MAX(m, 1); } else { m = w = 0; } if (m < 1 || w < 1 || p > 3 || q > 3) { acb_hypgeom_pfq_sum_forward(s, t, a, p, b, q, z, n, prec); return; } acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(u); acb_init(v); ks = _acb_vec_init(w); As = _acb_vec_init(w); Bs = _acb_vec_init(w); Cs = _acb_vec_init(w); bsplit(A, B, C, a, p, b, q, z, 0, m, prec); for (i = 0; i < w; i++) acb_set_ui(ks + i, i * m); tree = _acb_poly_tree_alloc(w); _acb_poly_tree_build(tree, ks, w, prec); _acb_poly_evaluate_vec_fast_precomp(As, A->coeffs, A->length, tree, w, prec); _acb_poly_evaluate_vec_fast_precomp(Bs, B->coeffs, B->length, tree, w, prec); _acb_poly_evaluate_vec_fast_precomp(Cs, C->coeffs, C->length, tree, w, prec); _acb_poly_tree_free(tree, w); /* todo: use binary splitting here for improved numerical stability */ for (i = 1; i < w; i++) { acb_mul(Cs, Cs, Bs + i, prec); acb_addmul(Cs, As, Cs + i, prec); acb_mul(As, As, As + i, prec); acb_mul(Bs, Bs, Bs + i, prec); } acb_div(s, Cs, Bs, prec); acb_div(t, As, Bs, prec); for (k = w * m; k < n && !acb_is_zero(t); k++) { acb_add(s, s, t, prec); if (p > 0) { acb_add_ui(u, a, k, prec); for (i = 1; i < p; i++) { acb_add_ui(v, a + i, k, prec); acb_mul(u, u, v, prec); } acb_mul(t, t, u, prec); } if (q > 0) { acb_add_ui(u, b, k, prec); for (i = 1; i < q; i++) { acb_add_ui(v, b + i, k, prec); acb_mul(u, u, v, prec); } acb_div(t, t, u, prec); } acb_mul(t, t, z, prec); } acb_clear(u); acb_clear(v); _acb_vec_clear(ks, w); _acb_vec_clear(As, w); _acb_vec_clear(Bs, w); _acb_vec_clear(Cs, w); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); }
void CCharEntity::OnStepBefore() { if (IsCollisionEnabled() && !IsRagdollActive()) { CEnvInfo EnvInfo; vector3 Pos = GetTransform().pos_component(); Pos.y += Height; float DistanceToGround; if (EnvQueryMgr->GetEnvInfoAt(Pos, EnvInfo, Height + 0.1f, GetUniqueID())) { DistanceToGround = Pos.y - Height - EnvInfo.WorldHeight; GroundMtl = EnvInfo.Material; } else { DistanceToGround = FLT_MAX; GroundMtl = InvalidMaterial; } CRigidBody* pMasterBody = Composite->GetMasterBody(); bool BodyIsEnabled = IsEnabled(); vector3 AngularVel = pMasterBody->GetAngularVelocity(); vector3 LinearVel = pMasterBody->GetLinearVelocity(); vector3 DesiredLVelChange = DesiredLinearVel - LinearVel; if (DistanceToGround <= 0.f) { // No torques now, angular velocity changes by impulse immediately to desired value bool Actuated = DesiredAngularVel != AngularVel.y; if (Actuated) { if (!BodyIsEnabled) SetEnabled(true); pMasterBody->SetAngularVelocity(vector3(0.f, DesiredAngularVel, 0.f)); } if (!DesiredLVelChange.isequal(vector3::Zero, 0.0001f)) { if (!Actuated) { Actuated = true; SetEnabled(true); } // Vertical movement for non-flying actors is impulse (jump). // Since speed if already clamped to actor caps, we save vertical desired velocity as is. // Spring force pushes us from below the ground. //!!!!!!!!!!!!!!! //!!!calc correct impulse for the spring! //!!!!!!!!!!!!!!! float VerticalDesVelChange = DesiredLVelChange.y - (50.0f * DistanceToGround); float Mass = pMasterBody->GetMass(); //!!!remove calcs for Y, it is zero (optimization)! dVector3 ODEForce; dWorldImpulseToForce(Level->GetODEWorldID(), dReal(Level->GetStepSize()), DesiredLVelChange.x * Mass, 0.f, DesiredLVelChange.z * Mass, ODEForce); float SqForceMagnitude = (float)dCalcVectorLengthSquare3(ODEForce); if (SqForceMagnitude > 0.f) { float MaxForceMagnitude = Mass * MaxHorizAccel; float SqMaxForceMagnitude = MaxForceMagnitude * MaxForceMagnitude; if (SqForceMagnitude > SqMaxForceMagnitude) dScaleVector3(ODEForce, MaxForceMagnitude / n_sqrt(SqForceMagnitude)); dBodyAddForce(pMasterBody->GetODEBodyID(), ODEForce[0], ODEForce[1], ODEForce[2]); } if (VerticalDesVelChange != 0.f) { dWorldImpulseToForce(Level->GetODEWorldID(), dReal(Level->GetStepSize()), 0.f, VerticalDesVelChange * Mass, 0.f, ODEForce); dBodyAddForce(pMasterBody->GetODEBodyID(), ODEForce[0], ODEForce[1], ODEForce[2]); } } if (BodyIsEnabled && !Actuated && DistanceToGround > -0.002f) { const float FreezeThreshold = 0.00001f; //???use TINY? bool AVelIsAlmostZero = n_fabs(AngularVel.y) < FreezeThreshold; bool LVelIsAlmostZero = n_fabs(LinearVel.x) * (float)Level->GetStepSize() < FreezeThreshold && n_fabs(LinearVel.z) * (float)Level->GetStepSize() < FreezeThreshold; if (AVelIsAlmostZero) pMasterBody->SetAngularVelocity(vector3::Zero); if (LVelIsAlmostZero) pMasterBody->SetLinearVelocity(vector3::Zero); if (AVelIsAlmostZero && LVelIsAlmostZero) SetEnabled(false); } } //???!!!else (when falling) apply damping?! } // NOTE: do NOT call the parent class, we don't need any damping }
mp_limb_t _ll_factor_SQUFOF(mp_limb_t n_hi, mp_limb_t n_lo, ulong max_iters) { mp_limb_t n[2]; mp_limb_t sqrt[2]; mp_limb_t rem[2]; mp_size_t num, sqroot, p, q; mp_limb_t l, l2, iq, pnext; mp_limb_t qarr[50]; mp_limb_t qupto, qlast, t, r = 0; ulong i, j; n[0] = n_lo; n[1] = n_hi; if (n_hi) num = mpn_sqrtrem(sqrt, rem, n, 2); else num = ((sqrt[0] = n_sqrtrem(rem, n_lo)) != 0UL); sqroot = sqrt[0]; p = sqroot; q = rem[0]; if ((q == 0) || (num == 0)) { return sqroot; } l = 1 + 2*n_sqrt(2*p); l2 = l/2; qupto = 0; qlast = 1; for (i = 0; i < max_iters; i++) { iq = (sqroot + p)/q; pnext = iq*q - p; if (q <= l) { if ((q & 1UL) == 0UL) { qarr[qupto] = q/2; qupto++; if (qupto >= 50UL) return 0UL; } else if (q <= l2) { qarr[qupto] = q; qupto++; if (qupto >= 50UL) return 0UL; } } t = qlast + iq*(p - pnext); qlast = q; q = t; p = pnext; if ((i & 1) == 1) continue; if (!n_is_square(q)) continue; r = n_sqrt(q); if (qupto == 0UL) break; for (j = 0; j < qupto; j++) if (r == qarr[j]) goto cont; break; cont: ; if (r == 1UL) return 0UL; } if (i == max_iters) return 0UL; /* taken too long, give up */ qlast = r; p = p + r*((sqroot - p)/r); umul_ppmm(rem[1], rem[0], p, p); sub_ddmmss(sqrt[1], sqrt[0], n[1], n[0], rem[1], rem[0]); if (sqrt[1]) { int norm; count_leading_zeros(norm, qlast); udiv_qrnnd(q, rem[0], (sqrt[1] << norm) + r_shift(sqrt[0], FLINT_BITS - norm), sqrt[0] << norm, qlast << norm); rem[0] >>= norm; } else {
void gamma_rising_fmprb_ui_delta(fmprb_t y, const fmprb_t x, ulong n, ulong m, long prec) { fmprb_ptr xs; fmprb_t t, u, v; ulong i, k, rem; fmpz_t c, h; fmpz *s, *d; long wp; if (n == 0) { fmprb_one(y); return; } if (n == 1) { fmprb_set_round(y, x, prec); return; } wp = FMPR_PREC_ADD(prec, FLINT_BIT_COUNT(n)); fmprb_init(t); fmprb_init(u); fmprb_init(v); fmpz_init(c); fmpz_init(h); if (m == 0) { ulong m1, m2; m1 = 0.2 * pow(wp, 0.4); m2 = n_sqrt(n); m = FLINT_MIN(m1, m2); } m = FLINT_MIN(m, n); m = FLINT_MAX(m, 1); xs = _fmprb_vec_init(m + 1); d = _fmpz_vec_init(m * m); s = _fmpz_vec_init(m + 1); _fmprb_vec_set_powers(xs, x, m + 1, wp); rising_difference_polynomial(s, d, m); /* tail */ rem = m; while (rem + m <= n) rem += m; fmprb_one(y); for (k = rem; k < n; k++) { fmprb_add_ui(t, xs + 1, k, wp); fmprb_mul(y, y, t, wp); } /* initial rising factorial */ fmprb_zero(t); for (i = 1; i <= m; i++) fmprb_addmul_fmpz(t, xs + i, s + i, wp); fmprb_mul(y, y, t, wp); /* the leading coefficient is always the same */ fmprb_mul_fmpz(xs + m - 1, xs + m - 1, d + m - 1 + 0, wp); for (k = 0; k + 2 * m <= n; k += m) { for (i = 0; i < m - 1; i++) { fmpz_set_ui(h, k); _fmpz_poly_evaluate_horner_fmpz(c, d + i * m, m - i, h); if (i == 0) fmprb_add_fmpz(t, t, c, wp); else fmprb_addmul_fmpz(t, xs + i, c, wp); } fmprb_add(t, t, xs + m - 1, wp); fmprb_mul(y, y, t, wp); } fmprb_set_round(y, y, prec); fmprb_clear(t); fmprb_clear(u); fmprb_clear(v); _fmprb_vec_clear(xs, m + 1); _fmpz_vec_clear(d, m * m); _fmpz_vec_clear(s, m + 1); fmpz_clear(c); fmpz_clear(h); }
void _qseive(const mp_limb_t n, const mp_limb_t B) { nmod_sparse_mat_t M; mp_limb_t quad, *quads, *xs, x, i = 0, j, piB = n_prime_pi(B); const mp_limb_t * ps = n_primes_arr_readonly(piB + 2); const double * pinvs = n_prime_inverses_arr_readonly(piB + 2); mzd_t *K; /* init */ quads = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *)); xs = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *)); K = mzd_init(piB + 1, 1); nmod_sparse_mat_init(M, piB + 1, piB + 1, 2); printf("init done\n"); printf("using %ld primes\n", piB); /* seive */ for (x = n_sqrt(n), i = 0; i <= piB; x++) { quad = x*x - n; if (quad == 0) continue; for (j = 0; j < piB; j++) n_remove2_precomp(&quad, ps[j], pinvs[j]); if (quad == 1) /* was B-smooth */ { quads[i] = x*x - n; quad = x*x - n; for (j = 0; j < piB; j++) { if (n_remove2_precomp(&quad, ps[j], pinvs[j]) % 2) _nmod_sparse_mat_set_entry(M, j, i, M->row_supports[j], 1); } xs[i] = x; i++; } } printf("data collection done\n"); n_cleanup_primes(); _bw(K, M, 1, 2, 7, 7); printf("procesing complete\n"); mzd_print(K); int done = 0; for (j = 0; !done; j++) { fmpz_t a, b, diff, N; fmpz_init_set_ui(a, 1); fmpz_init_set_ui(b, 1); fmpz_init_set_ui(N, n); fmpz_init(diff); for (i = 0; i < piB; i++) { if (mzd_read_bit(K, i, j)) { fmpz_mul_ui(a, a, xs[i]); fmpz_mul_ui(b, b, quads[i]); } } assert(fmpz_is_square(b)); fmpz_sqrt(b, b); if (fmpz_mod_ui(a, a, n) != fmpz_mod_ui(b, b, n) && fmpz_mod_ui(a, a, n) != n - fmpz_mod_ui(b, b, n)) { done = 1; fmpz_print(a); printf("\n"); fmpz_print(b); printf("\n"); fmpz_sub(diff, a, b); fmpz_gcd(a, diff, N); fmpz_divexact(b, N, a); fmpz_print(a); printf("\n"); fmpz_print(b); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(N); fmpz_clear(diff); } /* cleanup */ free(quads); free(xs); mzd_free(K); nmod_sparse_mat_clear(M); return; }
void acb_hypgeom_pfq_sum_rs(acb_t res, acb_t term, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) { acb_ptr zpow; acb_t s, t, u; slong i, j, k, m; mag_t B, C; if (n == 0) { acb_zero(res); acb_one(term); return; } if (n < 0) abort(); m = n_sqrt(n); m = FLINT_MIN(m, 150); mag_init(B); mag_init(C); acb_init(s); acb_init(t); acb_init(u); zpow = _acb_vec_init(m + 1); _acb_vec_set_powers(zpow, z, m + 1, prec); mag_one(B); for (k = n; k >= 0; k--) { j = k % m; if (k < n) acb_add(s, s, zpow + j, prec); if (k > 0) { if (p > 0) { acb_add_ui(u, a, k - 1, prec); for (i = 1; i < p; i++) { acb_add_ui(t, a + i, k - 1, prec); acb_mul(u, u, t, prec); } if (k < n) acb_mul(s, s, u, prec); acb_get_mag(C, u); mag_mul(B, B, C); } if (q > 0) { acb_add_ui(u, b, k - 1, prec); for (i = 1; i < q; i++) { acb_add_ui(t, b + i, k - 1, prec); acb_mul(u, u, t, prec); } if (k < n) acb_div(s, s, u, prec); acb_get_mag_lower(C, u); mag_div(B, B, C); } if (j == 0 && k < n) { acb_mul(s, s, zpow + m, prec); } } } acb_get_mag(C, z); mag_pow_ui(C, C, n); mag_mul(B, B, C); acb_zero(term); if (_acb_vec_is_real(a, p) && _acb_vec_is_real(b, q) && acb_is_real(z)) arb_add_error_mag(acb_realref(term), B); else acb_add_error_mag(term, B); acb_set(res, s); mag_clear(B); mag_clear(C); acb_clear(s); acb_clear(t); acb_clear(u); _acb_vec_clear(zpow, m + 1); }
slong _acb_poly_find_roots(acb_ptr roots, acb_srcptr poly, acb_srcptr initial, slong len, slong maxiter, slong prec) { slong iter, i, deg; slong rootmag, max_rootmag, correction, max_correction; deg = len - 1; if (deg == 0) { return 0; } else if (acb_contains_zero(poly + len - 1)) { /* if the leading coefficient contains zero, roots can be anywhere */ for (i = 0; i < deg; i++) { arb_zero_pm_inf(acb_realref(roots + i)); arb_zero_pm_inf(acb_imagref(roots + i)); } return 0; } else if (deg == 1) { acb_inv(roots + 0, poly + 1, prec); acb_mul(roots + 0, roots + 0, poly + 0, prec); acb_neg(roots + 0, roots + 0); return 1; } if (initial == NULL) _acb_poly_roots_initial_values(roots, deg, prec); else _acb_vec_set(roots, initial, deg); if (maxiter == 0) maxiter = 2 * deg + n_sqrt(prec); for (iter = 0; iter < maxiter; iter++) { max_rootmag = -ARF_PREC_EXACT; for (i = 0; i < deg; i++) { rootmag = _acb_get_mid_mag(roots + i); max_rootmag = FLINT_MAX(rootmag, max_rootmag); } _acb_poly_refine_roots_durand_kerner(roots, poly, len, prec); max_correction = -ARF_PREC_EXACT; for (i = 0; i < deg; i++) { correction = _acb_get_rad_mag(roots + i); max_correction = FLINT_MAX(correction, max_correction); } /* estimate the correction relative to the whole set of roots */ max_correction -= max_rootmag; /* flint_printf("ITER %wd MAX CORRECTION: %wd\n", iter, max_correction); */ if (max_correction < -prec / 2) maxiter = FLINT_MIN(maxiter, iter + 2); else if (max_correction < -prec / 3) maxiter = FLINT_MIN(maxiter, iter + 3); else if (max_correction < -prec / 4) maxiter = FLINT_MIN(maxiter, iter + 4); } return _acb_poly_validate_roots(roots, poly, len, prec); }
void _acb_poly_powsum_one_series_sieved(acb_ptr z, const acb_t s, slong n, slong len, slong prec) { slong * divisors; slong powers_alloc; slong i, j, k, ibound, kprev, power_of_two, horner_point; int critical_line, integer; acb_ptr powers; acb_ptr t, u, x; acb_ptr p1, p2; arb_t logk, v, w; critical_line = arb_is_exact(acb_realref(s)) && (arf_cmp_2exp_si(arb_midref(acb_realref(s)), -1) == 0); integer = arb_is_zero(acb_imagref(s)) && arb_is_int(acb_realref(s)); divisors = flint_calloc(n / 2 + 1, sizeof(slong)); powers_alloc = (n / 6 + 1) * len; powers = _acb_vec_init(powers_alloc); ibound = n_sqrt(n); for (i = 3; i <= ibound; i += 2) if (DIVISOR(i) == 0) for (j = i * i; j <= n; j += 2 * i) DIVISOR(j) = i; t = _acb_vec_init(len); u = _acb_vec_init(len); x = _acb_vec_init(len); arb_init(logk); arb_init(v); arb_init(w); power_of_two = 1; while (power_of_two * 2 <= n) power_of_two *= 2; horner_point = n / power_of_two; _acb_vec_zero(z, len); kprev = 0; COMPUTE_POWER(x, 2, kprev); for (k = 1; k <= n; k += 2) { /* t = k^(-s) */ if (DIVISOR(k) == 0) { COMPUTE_POWER(t, k, kprev); } else { p1 = POWER(DIVISOR(k)); p2 = POWER(k / DIVISOR(k)); if (len == 1) acb_mul(t, p1, p2, prec); else _acb_poly_mullow(t, p1, len, p2, len, len, prec); } if (k * 3 <= n) _acb_vec_set(POWER(k), t, len); _acb_vec_add(u, u, t, len, prec); while (k == horner_point && power_of_two != 1) { _acb_poly_mullow(t, z, len, x, len, len, prec); _acb_vec_add(z, t, u, len, prec); power_of_two /= 2; horner_point = n / power_of_two; horner_point -= (horner_point % 2 == 0); } } _acb_poly_mullow(t, z, len, x, len, len, prec); _acb_vec_add(z, t, u, len, prec); flint_free(divisors); _acb_vec_clear(powers, powers_alloc); _acb_vec_clear(t, len); _acb_vec_clear(u, len); _acb_vec_clear(x, len); arb_clear(logk); arb_clear(v); arb_clear(w); }
void _fmprb_poly_evaluate2_rectangular(fmprb_t y, fmprb_t z, fmprb_srcptr poly, long len, const fmprb_t x, long prec) { long i, j, m, r; fmprb_ptr xs; fmprb_t s, t, c; if (len < 3) { if (len == 0) { fmprb_zero(y); fmprb_zero(z); } else if (len == 1) { fmprb_set_round(y, poly + 0, prec); fmprb_zero(z); } else if (len == 2) { fmprb_mul(y, x, poly + 1, prec); fmprb_add(y, y, poly + 0, prec); fmprb_set_round(z, poly + 1, prec); } return; } m = n_sqrt(len) + 1; m *= 1; r = (len + m - 1) / m; xs = _fmprb_vec_init(m + 1); fmprb_init(s); fmprb_init(t); fmprb_init(c); _fmprb_vec_set_powers(xs, x, m + 1, prec); fmprb_set(y, poly + (r - 1) * m); for (j = 1; (r - 1) * m + j < len; j++) fmprb_addmul(y, xs + j, poly + (r - 1) * m + j, prec); for (i = r - 2; i >= 0; i--) { fmprb_set(s, poly + i * m); for (j = 1; j < m; j++) fmprb_addmul(s, xs + j, poly + i * m + j, prec); fmprb_mul(y, y, xs + m, prec); fmprb_add(y, y, s, prec); } len -= 1; r = (len + m - 1) / m; fmprb_mul_ui(z, poly + (r - 1) * m + 1, (r - 1) * m + 1, FMPR_PREC_EXACT); for (j = 1; (r - 1) * m + j < len; j++) { fmprb_mul_ui(c, poly + (r - 1) * m + j + 1, (r - 1) * m + j + 1, FMPR_PREC_EXACT); fmprb_addmul(z, xs + j, c, prec); } for (i = r - 2; i >= 0; i--) { fmprb_mul_ui(s, poly + i * m + 1, i * m + 1, FMPR_PREC_EXACT); for (j = 1; j < m; j++) { fmprb_mul_ui(c, poly + i * m + j + 1, i * m + j + 1, FMPR_PREC_EXACT); fmprb_addmul(s, xs + j, c, prec); } fmprb_mul(z, z, xs + m, prec); fmprb_add(z, z, s, prec); } _fmprb_vec_clear(xs, m + 1); fmprb_clear(s); fmprb_clear(t); fmprb_clear(c); }
void arb_rising2_ui_rs(arb_t u, arb_t v, const arb_t x, ulong n, ulong m, slong prec) { if (n == 0) { arb_zero(v); arb_one(u); } else if (n == 1) { arb_set(u, x); arb_one(v); } else { slong wp; ulong i, j, a, b; arb_ptr xs; arb_t S, T, U, V; fmpz *A, *B; wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); if (m == 0) { ulong m1, m2; m1 = 0.6 * pow(wp, 0.4); m2 = n_sqrt(n); m = FLINT_MIN(m1, m2); } m = FLINT_MAX(m, 1); xs = _arb_vec_init(m + 1); A = _fmpz_vec_init(2 * m + 1); B = A + (m + 1); arb_init(S); arb_init(T); arb_init(U); arb_init(V); _arb_vec_set_powers(xs, x, m + 1, wp); for (i = 0; i < n; i += m) { a = i; b = FLINT_MIN(n, a + m); if (a == 0 || b != a + m) { _gamma_rf_bsplit(A, a, b); } else { fmpz tt = m; _fmpz_poly_taylor_shift(A, &tt, m + 1); } _fmpz_poly_derivative(B, A, b - a + 1); arb_set_fmpz(S, A); for (j = 1; j <= b - a; j++) arb_addmul_fmpz(S, xs + j, A + j, wp); arb_set_fmpz(T, B); for (j = 1; j < b - a; j++) arb_addmul_fmpz(T, xs + j, B + j, wp); if (i == 0) { arb_set(U, S); arb_set(V, T); } else { arb_mul(V, V, S, wp); arb_addmul(V, U, T, wp); arb_mul(U, U, S, wp); } } arb_set(u, U); arb_set(v, V); _arb_vec_clear(xs, m + 1); _fmpz_vec_clear(A, 2 * m + 1); arb_clear(S); arb_clear(T); arb_clear(U); arb_clear(V); } }
/* evaluates the truncated Taylor series (assumes no aliasing) */ void _arb_mat_exp_taylor(arb_mat_t S, const arb_mat_t A, slong N, slong prec) { if (N == 1) { arb_mat_one(S); } else if (N == 2) { arb_mat_one(S); arb_mat_add(S, S, A, prec); } else if (N == 3) { arb_mat_t T; arb_mat_init(T, arb_mat_nrows(A), arb_mat_nrows(A)); arb_mat_mul(T, A, A, prec); arb_mat_scalar_mul_2exp_si(T, T, -1); arb_mat_add(S, A, T, prec); arb_mat_one(T); arb_mat_add(S, S, T, prec); arb_mat_clear(T); } else { slong i, lo, hi, m, w, dim; arb_mat_struct * pows; arb_mat_t T, U; fmpz_t c, f; dim = arb_mat_nrows(A); m = n_sqrt(N); w = (N + m - 1) / m; fmpz_init(c); fmpz_init(f); pows = flint_malloc(sizeof(arb_mat_t) * (m + 1)); arb_mat_init(T, dim, dim); arb_mat_init(U, dim, dim); for (i = 0; i <= m; i++) { arb_mat_init(pows + i, dim, dim); if (i == 0) arb_mat_one(pows + i); else if (i == 1) arb_mat_set(pows + i, A); else arb_mat_mul(pows + i, pows + i - 1, A, prec); } arb_mat_zero(S); fmpz_one(f); for (i = w - 1; i >= 0; i--) { lo = i * m; hi = FLINT_MIN(N - 1, lo + m - 1); arb_mat_zero(T); fmpz_one(c); while (hi >= lo) { arb_mat_scalar_addmul_fmpz(T, pows + hi - lo, c, prec); if (hi != 0) fmpz_mul_ui(c, c, hi); hi--; } arb_mat_mul(U, pows + m, S, prec); arb_mat_scalar_mul_fmpz(S, T, f, prec); arb_mat_add(S, S, U, prec); fmpz_mul(f, f, c); } arb_mat_scalar_div_fmpz(S, S, f, prec); fmpz_clear(c); fmpz_clear(f); for (i = 0; i <= m; i++) arb_mat_clear(pows + i); flint_free(pows); arb_mat_clear(T); arb_mat_clear(U); } }
void _nmod_poly_compose_mod_brent_kung(mp_ptr res, mp_srcptr poly1, long len1, mp_srcptr poly2, mp_srcptr poly3, long len3, nmod_t mod) { nmod_mat_t A, B, C; mp_ptr t, h; long i, n, m; n = len3 - 1; if (len3 == 1) return; if (len1 == 1) { res[0] = poly1[0]; return; } if (len3 == 2) { res[0] = _nmod_poly_evaluate_nmod(poly1, len1, poly2[0], mod); return; } m = n_sqrt(n) + 1; nmod_mat_init(A, m, n, mod.n); nmod_mat_init(B, m, m, mod.n); nmod_mat_init(C, m, n, mod.n); h = _nmod_vec_init(n); t = _nmod_vec_init(n); /* Set rows of B to the segments of poly1 */ for (i = 0; i < len1 / m; i++) _nmod_vec_set(B->rows[i], poly1 + i*m, m); _nmod_vec_set(B->rows[i], poly1 + i*m, len1 % m); /* Set rows of A to powers of poly2 */ A->rows[0][0] = 1UL; _nmod_vec_set(A->rows[1], poly2, n); for (i = 2; i < m; i++) _nmod_poly_mulmod(A->rows[i], A->rows[i-1], n, poly2, n, poly3, len3, mod); nmod_mat_mul(C, B, A); /* Evaluate block composition using the Horner scheme */ _nmod_vec_set(res, C->rows[m - 1], n); _nmod_poly_mulmod(h, A->rows[m - 1], n, poly2, n, poly3, len3, mod); for (i = m - 2; i >= 0; i--) { _nmod_poly_mulmod(t, res, n, h, n, poly3, len3, mod); _nmod_poly_add(res, t, n, C->rows[i], n, mod); } _nmod_vec_clear(h); _nmod_vec_clear(t); nmod_mat_clear(A); nmod_mat_clear(B); nmod_mat_clear(C); }