Darmon points

Initialize self. See help(type(self)) for accurate signature.

darmonpoints.darmonpoints.construct_homology_cycle(P, G, D, prec, hecke_poly_getter, outfile=None, max_n=None, elliptic_curve=None, smoothen_prime=None, **kwargs)[source]
darmonpoints.darmonpoints.darmon_discriminants(bound, split_primes=None, inert_primes=None)[source]
darmonpoints.darmonpoints.darmon_point(P, E, beta, prec, ramification_at_infinity=None, input_data=None, magma=None, working_prec=None, recognize_point=True, **kwargs)[source]

EXAMPLES:

We first need to import the module:

sage: from darmonpoints.darmonpoints import darmon_point

A first example (Stark–Heegner point):

sage: from darmonpoints.darmonpoints import darmon_point sage: darmon_point(7,EllipticCurve(‘35a1’),41,20, cohomological=False, use_magma=False, use_ps_dists = True)[0] Starting computation of the Darmon point … -70*alpha + 449

A quaternionic (Greenberg) point:

sage: darmon_point(13,EllipticCurve(‘78a1’),5,20) # long time # optional - magma

A Darmon point over a cubic (1,1) field:

sage: F.<r> = NumberField(x^3 - x^2 - x + 2) sage: E = EllipticCurve([-r -1, -r, -r - 1,-r - 1, 0]) sage: N = E.conductor() sage: P = F.ideal(r^2 - 2*r - 1) sage: beta = -3*r^2 + 9*r - 6 sage: darmon_point(P,E,beta,20) # long time # optional - magma

Darmon-Vonk points

Initialize self. See help(type(self)) for accurate signature.

class darmonpoints.darmonvonk.DVCocycle(G, x0, gamma_tau, tau_p)[source]

Bases: SageObject

all_matrix_candidates(gamma)[source]

Returns a list S of matrices in G satisfying g * (x1, gamma1*x1) meets (x2, gamma2*x2) => g belongs to S.

evaluate(gamma)[source]
class darmonpoints.darmonvonk.OverconvergentDVCocycle(G, phi0, base_ring=None)[source]

Bases: SageObject

base_ring()[source]
evaluate_at_cycle(theta, parity)[source]
improve(prec)[source]
darmonpoints.darmonvonk.admissible_discriminants(p, D, bound, magma=None)[source]
darmonpoints.darmonvonk.construct_bigfield(Dlist, magma, base=None, ringclassfield=True)[source]
darmonpoints.darmonvonk.construct_conjectural_field(D1, D2, magma, extra_conductor_1=1, extra_conductor_2=1, base=None, return_units=True)[source]
darmonpoints.darmonvonk.darmon_vonk_cocycle(G, D, prec, extra_conductor=1, padic_field=None, hecke_data=None, outfile=None, **kwargs)[source]
darmonpoints.darmonvonk.darmon_vonk_cycle(G, D, prec, extra_conductor=1, padic_field=None, hecke_data=None, outfile=None, **kwargs)[source]
darmonpoints.darmonvonk.darmon_vonk_group(p, DB, outfile=None, **kwargs)[source]
darmonpoints.darmonvonk.darmon_vonk_overconvergent_cocycle(G, D, prec, lift=True, working_prec=None, extra_conductor=1, outfile=None, **kwargs)[source]
darmonpoints.darmonvonk.darmon_vonk_point(p, DB, D1, D2, prec, working_prec=None, magma=None, extra_conductor_1=1, extra_conductor_2=1, recognize_point='algdep', parity='all', degree_bound=8, outfile=None, **kwargs)[source]

EXAMPLES

sage: from darmonpoints.darmonvonk import darmon_vonk_point sage: J = darmon_vonk_point(5, 1, 3, 13, 60, parity=’+’, recognize_point=’algdep’,magma=magma) # optional - magma #### Starting computation of the Darmon-Vonk point #### … f = 7*x^2 + 11*x + 7

darmonpoints.darmonvonk.prime_list_candidates(D1, D2, extra_conductor_1=1, extra_conductor_2=1)[source]
darmonpoints.darmonvonk.trace_cycle(G, theta, twist=False)[source]

Curve finding

Initialize self. See help(type(self)) for accurate signature.

darmonpoints.findcurve.find_curve(P, DB, NE, prec, sign_ap=None, magma=None, return_all=False, initial_data=None, ramification_at_infinity=None, **kwargs)[source]

EXAMPLES:

First example:

sage: from darmonpoints.findcurve import find_curve sage: find_curve(5,6,30,20) # long time # optional - magma # B = F<i,j,k>, with i^2 = -1 and j^2 = 3 … ‘(1, 0, 1, -289, 1862)’

A second example, now over a real quadratic:

sage: from darmonpoints.findcurve import find_curve sage: F.<r> = QuadraticField(5) sage: P = F.ideal(3/2*r + 1/2) sage: D = F.ideal(3) sage: find_curve(P,D,P*D,30,ramification_at_infinity = F.real_places()[:1]) # long time # optional - magma …

Now over a cubic of mixed signature:

sage: from darmonpoints.findcurve import find_curve sage: F.<r> = NumberField(x^3 -3) sage: P = F.ideal(r-2) sage: D = F.ideal(r-1) sage: find_curve(P,D,P*D,30) # long time # optional - magma …

p-adic periods

Initialize self. See help(type(self)) for accurate signature.

darmonpoints.padicperiods.HalfPeriodsInTermsOfLambdas(L1, L2, L3, lvec_and_Mlist=None, HP0=None, prec=None, max_iters=20)[source]
darmonpoints.padicperiods.I2_inv_from_xvec(xvec)[source]
darmonpoints.padicperiods.I2_inv_padic_from_half_periods(a, b, c, q1, q2, q3, prec, threshold=None)[source]
darmonpoints.padicperiods.I2_inv_padic_from_xvec(xvec, prec, threshold=None)[source]
darmonpoints.padicperiods.Theta(p1, p2, p3, version, prec=None)[source]
darmonpoints.padicperiods.Thetas(p1, p2, p3, q1, q2, q3, prec=None)[source]
darmonpoints.padicperiods.absolute_igusa_padic_from_half_periods(p1, p2, p3, q1, q2, q3, prec, threshold=None)[source]
darmonpoints.padicperiods.absolute_igusa_padic_from_xvec(xvec, prec, threshold=None)[source]
darmonpoints.padicperiods.all_possible_ordmats(Lpmat, N)[source]
darmonpoints.padicperiods.all_possible_qords(Tmatrix, N, initial=None)[source]
darmonpoints.padicperiods.build_Lambdalist_from_AB(A, B, T, scaling)[source]
darmonpoints.padicperiods.change_period_logs(Alog, Blog, T)[source]
darmonpoints.padicperiods.check_absoluteinvs(xvec, prec, data, **kwargs)[source]
darmonpoints.padicperiods.check_cheatjs(xvec, prec, data, **kwargs)[source]
darmonpoints.padicperiods.check_generic(xvec, prec, data, **kwargs)[source]
darmonpoints.padicperiods.check_listI10(xvec, prec, data, **kwargs)[source]
darmonpoints.padicperiods.compare_AB_periods(Alist, Blist, T, Ag, Bg, Dg, prec, base=Rational Field, matlist=None)[source]
darmonpoints.padicperiods.compute_lvec_and_Mlist(prec)[source]
darmonpoints.padicperiods.compute_twisted_jacobian_data(fvec, x, y, z, prec)[source]
darmonpoints.padicperiods.euler_factor_twodim(p, T)[source]
darmonpoints.padicperiods.euler_factor_twodim_tn(q, t, n)[source]
darmonpoints.padicperiods.evaluate_twisted_jacobian_matrix(p1, p2, p3, Mlist)[source]
darmonpoints.padicperiods.find_igusa_invariants(a, b, T, embedding, prec=None, outfile=None, list_I10=None, Pgen=None, N=6, cheatjs=None, parallelize=True)[source]
darmonpoints.padicperiods.find_igusa_invariants_from_AB(A, B, T, scaling, prec, **kwargs)[source]
darmonpoints.padicperiods.find_initial_approx(L1, L2, L3, lvec)[source]
darmonpoints.padicperiods.find_kadziela_matrices(M, T)[source]

The matrix M describes the relation between periods (A,B,D)^t and the periods (A0,B0)^t, where (A,B,D) are the periods of the Teitelbaum periods, and (A0,B0) are the Darmon ones.

(A,B,D)^t = M * (A0,B0)^t

The matrix T describes the action of Hecke on homology. That is, the first column of T describes the image of T on the first basis vector.

The output are matrices X and Y such that

X * matrix(2,2,[A,B,B,D]) = matrix(2,2,[A0,B0,C0,D0]) * Y

darmonpoints.padicperiods.frobenius_polynomial(C)[source]
darmonpoints.padicperiods.generate_listI10(F, N)[source]

Generates a list of possible I10’s, of the form:

(+-1) * 2^i * u^j * p^k * N^2

where i is taken in a specific range(20,25) and j is taken in another range(-15,16) and p is taken in another range(3)

darmonpoints.padicperiods.generate_matlists(Lambdalist, mat_coeffs_range=3)[source]
darmonpoints.padicperiods.get_pseudo_orthonormal_homology(G, cocycles, hecke_data=None, outfile=None)[source]
darmonpoints.padicperiods.guess_equation(code, pol, Pgen, Dgen, Npgen, Sinf=None, sign_ap=None, prec=-1, hecke_data_init=None, working_prec=None, recognize_invariants=True, return_all=True, compute_G=True, compute_cohomology=True, abtuple=None, logfile=None, **kwargs)[source]
darmonpoints.padicperiods.igusa_clebsch_absolute_from_half_periods(p1, p2, p3, q1=None, q2=None, q3=None, prec=None, padic=True)[source]
darmonpoints.padicperiods.igusa_clebsch_absolute_from_xvec(xvec)[source]
darmonpoints.padicperiods.igusa_clebsch_from_half_periods(p1, p2, p3, q1, q2, q3, prec=None, padic=True)[source]
darmonpoints.padicperiods.igusa_clebsch_from_xvec(xvec)[source]
darmonpoints.padicperiods.j1_inv_from_xvec(xvec)[source]
darmonpoints.padicperiods.j1_inv_padic_from_half_periods(a, b, c, q1, q2, q3, prec, threshold=None)[source]
darmonpoints.padicperiods.j1_inv_padic_from_xvec(xvec, prec, threshold=None)[source]
darmonpoints.padicperiods.jacobian_matrix(fvec)[source]
darmonpoints.padicperiods.lambdavec(p1, p2, p3, prec=None, theta=None, prec_pseries=None)[source]
darmonpoints.padicperiods.lambdavec_padic(p1, p2, p3, q1, q2, q3, prec=None)[source]
darmonpoints.padicperiods.left_multiply_multiplicative(B, V)[source]
darmonpoints.padicperiods.load_lvec_and_Mlist(prec)[source]
darmonpoints.padicperiods.multiplicative_scalar_product(b, v)[source]
darmonpoints.padicperiods.normalize_periods(A, B, alpha, T, a, b, outfile=None)[source]

alpha = (phi1, theta1) beta = (phi2, theta2) = -n(T) * alpha, where T is the Hecke operator used when computing A and B. T is the new hecke operator.

darmonpoints.padicperiods.p_adic_l_invariant(A, B, Tmatrix)[source]
darmonpoints.padicperiods.p_adic_l_invariant_additive(logA, logB, alpha, beta, Tmatrix)[source]
darmonpoints.padicperiods.precompute_powers(p, q, N)[source]
darmonpoints.padicperiods.qlogs_from_Lp_and_ords(a, b, Tmatrix, q1ord, q2ord, q3ord)[source]
darmonpoints.padicperiods.recognize_invariant(j_invariant, base=None, threshold=None, prec=None, outfile=None, twopowlist=None, return_all=False)[source]
darmonpoints.padicperiods.right_multiply_multiplicative(W, A)[source]
darmonpoints.padicperiods.take_to_Qp(x, tolerance=None)[source]
darmonpoints.padicperiods.teichmuller_system(self)[source]
darmonpoints.padicperiods.xvec(p1, p2, p3, prec)[source]
darmonpoints.padicperiods.xvec_padic(p1, p2, p3, q1, q2, q3, prec=None)[source]

Plectic points

Initialize self. See help(type(self)) for accurate signature.

darmonpoints.plectic.PlecticGroup(p1, p2, quat_data, level, base=None, grouptype=None, seed=None, magma=None, logfile=None, **kwargs)[source]
class darmonpoints.plectic.PlecticGroup_class(base, p0, p1, discriminant, abtuple, level=1, outfile=None, magma=None, **kwargs)[source]

Bases: AlgebraicGroup

base_field()[source]
compute_presentation_GG()[source]
compute_presentation_GS()[source]
construct_EV_dict(depth)[source]

EXAMPLES:

sage: class Foo:
....:     def __init__(self, x):
....:         self._x = x
....:     @cached_method
....:     def f(self,*args):
....:         return self._x^2
sage: a = Foo(2)
sage: a.f.cache
{}
sage: a.f()
4
sage: a.f.cache
{((), ()): 4}
construct_VE_dict(depth)[source]

EXAMPLES:

sage: class Foo:
....:     def __init__(self, x):
....:         self._x = x
....:     @cached_method
....:     def f(self,*args):
....:         return self._x^2
sage: a = Foo(2)
sage: a.f.cache
{}
sage: a.f()
4
sage: a.f.cache
{((), ()): 4}
construct_edge_reps(depth)[source]

EXAMPLES:

sage: class Foo:
....:     def __init__(self, x):
....:         self._x = x
....:     @cached_method
....:     def f(self,*args):
....:         return self._x^2
sage: a = Foo(2)
sage: a.f.cache
{}
sage: a.f()
4
sage: a.f.cache
{((), ()): 4}
edge_from_quaternion(g, g1, g2)[source]
embeddings()[source]
get_BT_reps(**kwargs)[source]
get_Up_reps_bianchi(pi, pi_bar)[source]
get_covering(depth)[source]
get_degeneration(vv, f, idx)[source]
get_edge_rep(e0, e1)[source]

EXAMPLES:

sage: class Foo:
....:     def __init__(self, x):
....:         self._x = x
....:     @cached_method
....:     def f(self,*args):
....:         return self._x^2
sage: a = Foo(2)
sage: a.f.cache
{}
sage: a.f()
4
sage: a.f.cache
{((), ()): 4}
prime()[source]
quaternion_algebra()[source]
reduce_in_amalgam(x, return_word=False, check=True)[source]
small_group()[source]
use_shapiro()[source]
vert_depth(v0, v1)[source]
darmonpoints.plectic.additive_integral(mu, phi)[source]

Calculates the additive integral of the rational function phi against mu.

darmonpoints.plectic.check_is_cycle(G, cycle_list)[source]
darmonpoints.plectic.compute_edge_to_eqs(G, depth)[source]
darmonpoints.plectic.compute_indeps_parallel(G, phi, ff, hh, depth, njobs=1, max_cpus=1)[source]
darmonpoints.plectic.compute_large_system_sparse_parallel(G, phi, ff, hh, depth)[source]
darmonpoints.plectic.compute_plectic_point(G, phiE, Fdict, depth, beta, njobs=1, max_cpus=1, outfile=None)[source]
darmonpoints.plectic.do_twist(G, gamma, tau0, tau1)[source]
darmonpoints.plectic.evaluate_HC(G, phi, F, gamma, gamma_e, edge_dict=None, scaling=1)[source]
darmonpoints.plectic.find_coboundaries(G, phi)[source]
darmonpoints.plectic.get_cycle(G, beta, prec)[source]
darmonpoints.plectic.get_edge_list(BT, center, depth)[source]
darmonpoints.plectic.get_nu0(G, phi, v0, e1, F=None, Co=0, Ce=0, scaling=1)[source]
darmonpoints.plectic.get_nu1(G, phi, e0, v1, F=None, Co=0, Ce=0, scaling=1)[source]
darmonpoints.plectic.get_vertex_list(BT, center, depth)[source]
darmonpoints.plectic.lift_to_HC(G, phiE, depth, njobs=1, max_cpus=1)[source]
darmonpoints.plectic.op_edge_adj(self, M)[source]
darmonpoints.plectic.riemann_sum(G, tau0, tau1, gamma, Phi, depth=1, progress_bar=True, max_iters=-1, F=None, twist=True, edge_dict=None)[source]
darmonpoints.plectic.riemann_sum_parallel(G, tau0, tau1, gammaquatrep, phiE, depth, Fdict, njobs=1, twist=True, max_cpus=1)[source]
darmonpoints.plectic.sample_point(h, r0, r1, prec=20)[source]

Schottky groups

Initialize self. See help(type(self)) for accurate signature.

class darmonpoints.schottky.Ball(parent, center, radius, is_open=True, is_complement=False)[source]

Bases: Element

closure()[source]
complement()[source]
get_key()[source]

EXAMPLES:

sage: class Foo:
....:     def __init__(self, x):
....:         self._x = x
....:     @cached_method
....:     def f(self):
....:         return self._x^2
sage: a = Foo(2)
sage: print(a.f.cache)
None
sage: a.f()
4
sage: a.f.cache
4
interior()[source]
intersects(other)[source]
class darmonpoints.schottky.Balls(K, oriented=True)[source]

Bases: UniqueRepresentation, Parent

Element

alias of Ball

are_equal(left, right)[source]
base_ring()[source]
find_midpoint(v0, v1)[source]
vertex_from_three_points(a)[source]
class darmonpoints.schottky.NeighborJoiningTree(K, leaves)[source]

Bases: SageObject

add_leaf(new_leaf, subtree=None)[source]
adjacency(subtree=None, root=None)[source]
adjacency_list()[source]
get_subtree(v1, v2)[source]
to_graph()[source]
to_string(subtree)[source]
update_vertex_table()[source]
vertices(subtree=None)[source]
class darmonpoints.schottky.PreSchottkyGroup(K, generators)[source]

Bases: SchottkyGroup_abstract

action_table()[source]
base()[source]

Initialize self.

EXAMPLES:

sage: def f(x):
....:     "doc of f"
....:     return 1
....:
sage: x = lazy_attribute(f); x
<sage.misc.lazy_attribute.lazy_attribute object at ...>
sage: x.__doc__
'doc of f'
sage: x.__name__
'f'
sage: x.__module__
'__main__'
certify(pairing, i0)[source]
construct_tree(level)[source]
edge_classes(action_table=None)[source]
fundamental_domain(*args, **kwargs)[source]

EXAMPLES:

sage: class Foo:
....:     def __init__(self, x):
....:         self._x = x
....:     @cached_method
....:     def f(self,*args):
....:         return self._x^2
sage: a = Foo(2)
sage: a.f.cache
{}
sage: a.f()
4
sage: a.f.cache
{((), ()): 4}
to_schottky()[source]
vertex_classes()[source]
class darmonpoints.schottky.SchottkyGroup(K, generators, balls=None, transformation=None, parameters=None, keep_generators=True, check=True)[source]

Bases: SchottkyGroup_abstract

a_point()[source]
balls()[source]
find_equivalent_divisor(D)[source]
find_point(gamma, eps=1, idx=None)[source]
gens_extended()[source]

EXAMPLES:

sage: class Foo:
....:     def __init__(self, x):
....:         self._x = x
....:     @cached_method
....:     def f(self):
....:         return self._x^2
sage: a = Foo(2)
sage: print(a.f.cache)
None
sage: a.f()
4
sage: a.f.cache
4
in_fundamental_domain(x, strict=False)[source]
in_which_ball(x, closure=False)[source]
matrix_to_element(*args, **kwargs)[source]
parameters()[source]

Initialize self.

EXAMPLES:

sage: def f(x):
....:     "doc of f"
....:     return 1
....:
sage: x = lazy_attribute(f); x
<sage.misc.lazy_attribute.lazy_attribute object at ...>
sage: x.__doc__
'doc of f'
sage: x.__name__
'f'
sage: x.__module__
'__main__'
period(i, j, prec, **kwargs)[source]

Compute the (i,j)-entry of the period matrix.

EXAMPLES

sage: from darmonpoints.schottky import * sage: p = 3 sage: prec = 10 sage: working_prec = 200 sage: K = Qp(p,working_prec) sage: h1 = matrix(K, 2, 2, [-5,32,-8,35]) sage: h2 = matrix(K, 2, 2, [-13,80,-8,43]) sage: G = SchottkyGroup(K, (h1,h2)) sage: q00g = G.period_naive(0, 0, prec) sage: q01g = G.period_naive(0, 1, prec) sage: q11g = G.period_naive(1, 1, prec) sage: q00 = G.period(0,0, prec) sage: q01 = G.period(0,1, prec) sage: q11 = G.period(1,1, prec) sage: (q00g/q00-1).valuation() > prec True sage: (q01g/q01-1).valuation() > prec True sage: (q11g/q11-1).valuation() > prec True

period_matrix(prec, **kwargs)[source]

EXAMPLES:

sage: class Foo:
....:     def __init__(self, x):
....:         self._x = x
....:     @cached_method
....:     def f(self,*args):
....:         return self._x^2
sage: a = Foo(2)
sage: a.f.cache
{}
sage: a.f()
4
sage: a.f.cache
{((), ()): 4}
period_naive(i, j, prec, **kwargs)[source]
test_fundamental_domain()[source]
theta(prec, a, b=None, **kwargs)[source]

Compute the Theta function

EXAMPLES

sage: from darmonpoints.schottky import * sage: p = 3 sage: prec = 20 sage: working_prec = 200 sage: K = Qp(p,working_prec) sage: g1 = matrix(K, 2, 2, [-5,32,-8,35]) sage: g2 = matrix(K, 2, 2, [-13,80,-8,43]) sage: G = SchottkyGroup(K, (g1, g2)) sage: a = 23 sage: b = 14 sage: z0 = K(8) sage: m = 10 sage: Tg = G.theta_naive(m, z=z0, a=a,b=b) sage: T = G.theta(prec, a, b).improve(m) sage: (T(z0) / Tg - 1).valuation() > m True

to_fundamental_domain(x)[source]

Returns a point z in the closure of the fundamental domain and a word w = [i1,…,ik] (in Tietze notation) such that gi1 * … * gik * z = x

u_function(gamma, prec, a=None, **kwargs)[source]

Compute u_gamma

word_problem(gamma)[source]
class darmonpoints.schottky.SchottkyGroup_abstract(K, generators)[source]

Bases: SageObject

all_elements_up_to_length(N)[source]
base_field()[source]
base_ring()[source]
element_to_matrix(*args, **kwargs)[source]
enumerate_group_elements(length)[source]
generators()[source]
genus()[source]
group()[source]
inverse_generators()[source]
theta_derivative_naive(m, a, b, z=None, max_length=-1, base_field=None, s=None)[source]
theta_naive(m, a=0, b=1, z=None, gamma=None, **kwargs)[source]
uniformizer()[source]
darmonpoints.schottky.all_elements_up_to_length(gens, invgens, N)[source]
darmonpoints.schottky.choose_leaf(tree)[source]
darmonpoints.schottky.cross_ratio(points)[source]
darmonpoints.schottky.enumerate_group_elements(gens, invgens, length)[source]
darmonpoints.schottky.find_eigenvector_matrix(*args, **kwargs)[source]
darmonpoints.schottky.find_parameter(ball, pi=None, check=True)[source]

Create a cached version of a function, which only recomputes values it hasn’t already computed. A custom name can be provided by an optional argument “name”.

If f is a function, do either g = CachedFunction(f) to make a cached version of f, or put @CachedFunction right before the definition of f (i.e., use Python decorators):

@CachedFunction
def f(...):
    ....

The inputs to the function must be hashable or they must define sage.structure.sage_object.SageObject._cache_key().

TESTS:

sage: # needs sage.combinat
sage: g = CachedFunction(number_of_partitions)
sage: g.__name__
'number_of_partitions'
sage: 'partitions' in sage.misc.sageinspect.sage_getdoc(g)
True
sage: g(5)                                                                  # needs sage.libs.flint
7
sage: g.cache                                                               # needs sage.libs.flint
{((5, 'default'), ()): 7}

sage: def f(t=1): print(t)
sage: h = CachedFunction(f)
sage: w = walltime()
sage: h(); h(1); h(t=1)
1
sage: walltime(w) < 2
True

By default, the contents of the cache are not pickled:

sage: @cached_function
....: def f(n): return None
sage: import __main__
sage: __main__.f = f
sage: for i in range(100): f(i)
sage: len(f.cache)
100

sage: s = dumps(f)
sage: f.clear_cache()
sage: f = loads(s)
sage: len(f.cache)
0

If do_pickle is set, then the cache is pickled:

sage: @cached_function(do_pickle=True)
....: def f(n): return None
sage: __main__.f = f
sage: for i in range(100): f(i)
sage: len(f.cache)
100

sage: s = dumps(f)
sage: f.clear_cache()
sage: f = loads(s)
sage: len(f.cache)
100
darmonpoints.schottky.find_parameter_new(ball, pi=None, check=True)[source]

Create a cached version of a function, which only recomputes values it hasn’t already computed. A custom name can be provided by an optional argument “name”.

If f is a function, do either g = CachedFunction(f) to make a cached version of f, or put @CachedFunction right before the definition of f (i.e., use Python decorators):

@CachedFunction
def f(...):
    ....

The inputs to the function must be hashable or they must define sage.structure.sage_object.SageObject._cache_key().

TESTS:

sage: # needs sage.combinat
sage: g = CachedFunction(number_of_partitions)
sage: g.__name__
'number_of_partitions'
sage: 'partitions' in sage.misc.sageinspect.sage_getdoc(g)
True
sage: g(5)                                                                  # needs sage.libs.flint
7
sage: g.cache                                                               # needs sage.libs.flint
{((5, 'default'), ()): 7}

sage: def f(t=1): print(t)
sage: h = CachedFunction(f)
sage: w = walltime()
sage: h(); h(1); h(t=1)
1
sage: walltime(w) < 2
True

By default, the contents of the cache are not pickled:

sage: @cached_function
....: def f(n): return None
sage: import __main__
sage: __main__.f = f
sage: for i in range(100): f(i)
sage: len(f.cache)
100

sage: s = dumps(f)
sage: f.clear_cache()
sage: f = loads(s)
sage: len(f.cache)
0

If do_pickle is set, then the cache is pickled:

sage: @cached_function(do_pickle=True)
....: def f(n): return None
sage: __main__.f = f
sage: for i in range(100): f(i)
sage: len(f.cache)
100

sage: s = dumps(f)
sage: f.clear_cache()
sage: f = loads(s)
sage: len(f.cache)
100
darmonpoints.schottky.four_point_configuration(K, pts)[source]
darmonpoints.schottky.four_point_configuration_works(K, pts)[source]
darmonpoints.schottky.hash_vertex(v)[source]
darmonpoints.schottky.invert_word(w)[source]
darmonpoints.schottky.leaf(t)
darmonpoints.schottky.reduce_word(w)[source]
darmonpoints.schottky.test_fundamental_domain(gens, balls)[source]
darmonpoints.schottky.uniq(lst)[source]