Skip to content

Instantly share code, notes, and snippets.

@davidlowryduda
Last active July 20, 2017 03:09
Show Gist options
  • Save davidlowryduda/deb1f88cc60b6e1243df8dd8f4601cde to your computer and use it in GitHub Desktop.
Save davidlowryduda/deb1f88cc60b6e1243df8dd8f4601cde to your computer and use it in GitHub Desktop.
A demo for an interface from sagemath to the LMFDB
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"# Interfacing sage and the LMFDB --- a prototype\n",
"\n",
"The [lmfdb](http://www.lmfdb.org/) and [sagemath](http://www.sagemath.org/) are both great things, but they don't currently talk to each other. Much of the lmfdb calls sage, but the lmfdb also includes vast amounts of data on $L$-functions and modular forms (hence the name) that is not accessible from within sage.\n",
"\n",
"This is an example prototype of an interface to the lmfdb from sage. Keep in mind that this is **a prototype** and every aspect can change. But we hope to show what may be possible in the future. If you have requests, comments, or questions, **please request/comment/ask** either now, or at my email: `david@lowryduda.com`.\n",
"\n",
"> Note that this notebook is available on http://davidlowryduda.com or https://gist.github.com/davidlowryduda/deb1f88cc60b6e1243df8dd8f4601cde, and the code is available at https://github.com/davidlowryduda/sage2lmfdb\n",
"\n",
"Let's dive into an example."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"# These names will change\n",
"from sage.all import *\n",
"import LMFDB2sage.elliptic_curves as lmfdb_ecurve"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"data": {
"text/plain": [
"[Elliptic Curve defined by y^2 + x*y = x^3 - 887688*x - 321987008 over Rational Field,\n",
" Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 + 10795*x - 97828 over Rational Field,\n",
" Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 2294115305*x - 42292668425178 over Rational Field,\n",
" Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 3170*x - 49318 over Rational Field,\n",
" Elliptic Curve defined by y^2 + y = x^3 + 1050*x - 26469 over Rational Field,\n",
" Elliptic Curve defined by y^2 + x*y = x^3 - x^2 - 1240542*x - 531472509 over Rational Field,\n",
" Elliptic Curve defined by y^2 + y = x^3 - x^2 + 8100*x - 263219 over Rational Field,\n",
" Elliptic Curve defined by y^2 + x*y = x^3 + 637*x - 68783 over Rational Field,\n",
" Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36*x - 380 over Rational Field,\n",
" Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2535*x - 49982 over Rational Field]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"lmfdb_ecurve.search(rank=1)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"This returns 10 elliptic curves of rank 1. But these are a bit different than sage's elliptic curves."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'LMFDB2sage.ell_lmfdb.EllipticCurve_rational_field_lmfdb_with_category'>\n"
]
}
],
"source": [
"Es = lmfdb_ecurve.search(rank=1)\n",
"E = Es[0]\n",
"print(type(E))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Note that the class of an elliptic curve is an lmfdb ElliptcCurve. But don't worry, this is a subclass of a normal elliptic curve. So we can call the normal things one might call on an elliptic curve."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['CPS_height_bound', 'CartesianProduct', 'Chow_form', 'Hom', 'Jacobian', 'Jacobian_matrix', 'Lambda', 'Np', 'S_integral_points', '_AlgebraicScheme__A', '_AlgebraicScheme__divisor_group', '_AlgebraicScheme_subscheme__polys', '_EllipticCurve_generic__ainvs', '_EllipticCurve_generic__b_invariants', '_EllipticCurve_generic__base_ring', '_EllipticCurve_generic__discriminant', '_EllipticCurve_generic__is_over_RationalField', '_EllipticCurve_generic__multiple_x_denominator', '_EllipticCurve_generic__multiple_x_numerator', '_EllipticCurve_rational_field__conductor_pari', '_EllipticCurve_rational_field__generalized_congruence_number', '_EllipticCurve_rational_field__generalized_modular_degree', '_EllipticCurve_rational_field__gens', '_EllipticCurve_rational_field__modular_degree', '_EllipticCurve_rational_field__np', '_EllipticCurve_rational_field__rank', '_EllipticCurve_rational_field__regulator', '_EllipticCurve_rational_field__torsion_order', '_Hom_', '__add__', '__cached_methods', '__call__', '__class__', '__cmp__', '__contains__', '__delattr__', '__dict__', '__dir__', '__div__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__make_element_class__', '__module__', '__mul__', '__ne__', '__new__', '__nonzero__', '__pari__', '__pow__', '__pyx_vtable__', '__rdiv__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__temporarily_change_names', '__truediv__', '__weakref__', '_abstract_element_class', '_adjust_heegner_index', '_an_element_', '_ascii_art_', '_assign_names', '_axiom_', '_axiom_init_', '_base', '_base_ring', '_base_scheme', '_best_affine_patch', '_cache__point_homset', '_cache_an_element', '_cache_key', '_check_satisfies_equations', '_cmp_', '_coerce_map_from_', '_coerce_map_via', '_coercions_used', '_compute_gens', '_convert_map_from_', '_convert_method_name', '_defining_names', '_defining_params_', '_doccls', '_element_constructor', '_element_constructor_', '_element_constructor_from_element_class', '_element_init_pass_parent', '_factory_data', '_first_ngens', '_forward_image', '_fricas_', '_fricas_init_', '_gap_', '_gap_init_', '_generalized_congmod_numbers', '_generic_coerce_map', '_generic_convert_map', '_get_action_', '_get_local_data', '_giac_', '_giac_init_', '_gp_', '_gp_init_', '_heegner_best_tau', '_heegner_forms_list', '_heegner_index_in_EK', '_homset', '_init_category_', '_initial_action_list', '_initial_coerce_list', '_initial_convert_list', '_interface_', '_interface_init_', '_interface_is_cached_', '_internal_coerce_map_from', '_internal_convert_map_from', '_introspect_coerce', '_is_category_initialized', '_is_valid_homomorphism_', '_isoclass', '_json', '_kash_', '_kash_init_', '_known_points', '_latex_', '_lmfdb_label', '_lmfdb_regulator', '_macaulay2_', '_macaulay2_init_', '_magma_init_', '_maple_', '_maple_init_', '_mathematica_', '_mathematica_init_', '_maxima_', '_maxima_init_', '_maxima_lib_', '_maxima_lib_init_', '_modsym', '_modular_symbol_normalize', '_morphism', '_multiple_of_degree_of_isogeny_to_optimal_curve', '_multiple_x_denominator', '_multiple_x_numerator', '_names', '_normalize_padic_lseries', '_octave_', '_octave_init_', '_p_primary_torsion_basis', '_pari_', '_pari_init_', '_point', '_point_homset', '_polymake_', '_polymake_init_', '_populate_coercion_lists_', '_r_init_', '_reduce_model', '_reduce_point', '_reduction', '_refine_category_', '_repr_', '_repr_option', '_repr_type', '_sage_', '_scale_by_units', '_set_conductor', '_set_cremona_label', '_set_element_constructor', '_set_gens', '_set_modular_degree', '_set_rank', '_set_torsion_order', '_shortest_paths', '_singular_', '_singular_init_', '_symbolic_', '_test_an_element', '_test_cardinality', '_test_category', '_test_elements', '_test_elements_eq_reflexive', '_test_elements_eq_symmetric', '_test_elements_eq_transitive', '_test_elements_neq', '_test_eq', '_test_new', '_test_not_implemented_methods', '_test_pickling', '_test_some_elements', '_tester', '_torsion_bound', '_unicode_art_', '_unset_category', '_unset_coercions_used', '_unset_embedding', 'a1', 'a2', 'a3', 'a4', 'a6', 'a_invariants', 'abelian_variety', 'affine_patch', 'ainvs', 'algebra', 'ambient_space', 'an', 'an_element', 'analytic_rank', 'analytic_rank_upper_bound', 'anlist', 'antilogarithm', 'ap', 'aplist', 'arithmetic_genus', 'automorphisms', 'b2', 'b4', 'b6', 'b8', 'b_invariants', 'base', 'base_extend', 'base_field', 'base_morphism', 'base_ring', 'base_scheme', 'c4', 'c6', 'c_invariants', 'cartesian_product', 'categories', 'category', 'change_ring', 'change_weierstrass_model', 'cm_discriminant', 'codimension', 'coerce', 'coerce_embedding', 'coerce_map_from', 'complement', 'conductor', 'congruence_number', 'construction', 'convert_map_from', 'coordinate_ring', 'count_points', 'cremona_label', 'database_attributes', 'database_curve', 'db', 'defining_ideal', 'defining_polynomial', 'defining_polynomials', 'degree', 'descend_to', 'dimension', 'dimension_absolute', 'dimension_relative', 'discriminant', 'division_field', 'division_polynomial', 'division_polynomial_0', 'divisor', 'divisor_group', 'divisor_of_function', 'dual', 'dump', 'dumps', 'element_class', 'elliptic_exponential', 'embedding_center', 'embedding_morphism', 'eval_modular_form', 'excellent_position', 'formal', 'formal_group', 'fundamental_group', 'galois_representation', 'gen', 'gens', 'gens_certain', 'gens_dict', 'gens_dict_recursive', 'genus', 'geometric_genus', 'get_action', 'global_integral_model', 'global_minimal_model', 'global_minimality_class', 'has_additive_reduction', 'has_bad_reduction', 'has_base', 'has_cm', 'has_coerce_map_from', 'has_global_minimal_model', 'has_good_reduction', 'has_good_reduction_outside_S', 'has_multiplicative_reduction', 'has_nonsplit_multiplicative_reduction', 'has_rational_cm', 'has_split_multiplicative_reduction', 'hasse_invariant', 'heegner_discriminants', 'heegner_discriminants_list', 'heegner_index', 'heegner_index_bound', 'heegner_point', 'heegner_point_height', 'heegner_sha_an', 'height', 'height_function', 'height_pairing_matrix', 'hom', 'hyperelliptic_polynomials', 'identity_morphism', 'inject_variables', 'integral_model', 'integral_points', 'integral_short_weierstrass_model', 'integral_weierstrass_model', 'integral_x_coords_in_interval', 'intersection', 'intersection_multiplicity', 'intersection_points', 'intersects_at', 'irreducible_components', 'is_atomic_repr', 'is_coercion_cached', 'is_complete_intersection', 'is_conversion_cached', 'is_exact', 'is_global_integral_model', 'is_global_minimal_model', 'is_good', 'is_integral', 'is_irreducible', 'is_isogenous', 'is_isomorphic', 'is_local_integral_model', 'is_minimal', 'is_on_curve', 'is_ordinary', 'is_ordinary_singularity', 'is_p_integral', 'is_p_minimal', 'is_parent_of', 'is_projective', 'is_quadratic_twist', 'is_quartic_twist', 'is_semistable', 'is_sextic_twist', 'is_singular', 'is_smooth', 'is_supersingular', 'is_transverse', 'is_x_coord', 'isogenies_prime_degree', 'isogeny', 'isogeny_class', 'isogeny_codomain', 'isogeny_degree', 'isogeny_graph', 'isomorphism_to', 'isomorphisms', 'j_invariant', 'kodaira_symbol', 'kodaira_type', 'kodaira_type_old', 'kolyvagin_point', 'label', 'latex_name', 'latex_variable_names', 'lift_x', 'lll_reduce', 'lmfdb_page', 'local_coordinates', 'local_data', 'local_integral_model', 'local_minimal_model', 'lseries', 'lseries_gross_zagier', 'manin_constant', 'matrix_of_frobenius', 'minimal_discriminant_ideal', 'minimal_model', 'minimal_quadratic_twist', 'mod5family', 'modular_degree', 'modular_form', 'modular_parametrization', 'modular_symbol', 'modular_symbol_numerical', 'modular_symbol_space', 'multiplication_by_m', 'multiplication_by_m_isogeny', 'multiplicity', 'mwrank', 'mwrank_curve', 'neighborhood', 'newform', 'ngens', 'non_minimal_primes', 'nth_iterate', 'objgen', 'objgens', 'optimal_curve', 'orbit', 'ordinary_model', 'ordinary_primes', 'padic_E2', 'padic_height', 'padic_height_pairing_matrix', 'padic_height_via_multiply', 'padic_lseries', 'padic_regulator', 'padic_sigma', 'padic_sigma_truncated', 'parent', 'pari_curve', 'pari_mincurve', 'period_lattice', 'plane_projection', 'plot', 'point', 'point_homset', 'point_search', 'point_set', 'pollack_stevens_modular_symbol', 'preimage', 'projection', 'prove_BSD', 'q_eigenform', 'q_expansion', 'quadratic_transform', 'quadratic_twist', 'quartic_twist', 'rank', 'rank_bound', 'rank_bounds', 'rational_parameterization', 'rational_points', 'real_components', 'reduce', 'reduction', 'register_action', 'register_coercion', 'register_conversion', 'register_embedding', 'regulator', 'regulator_of_points', 'rename', 'reset_name', 'root_number', 'rst_transform', 'satisfies_heegner_hypothesis', 'saturation', 'save', 'scale_curve', 'selmer_rank', 'sextic_twist', 'sha', 'short_weierstrass_model', 'silverman_height_bound', 'simon_two_descent', 'singular_points', 'singular_subscheme', 'some_elements', 'specialization', 'structure_morphism', 'supersingular_primes', 'tamagawa_exponent', 'tamagawa_number', 'tamagawa_number_old', 'tamagawa_numbers', 'tamagawa_product', 'tamagawa_product_bsd', 'tangents', 'tate_curve', 'three_selmer_rank', 'torsion_order', 'torsion_points', 'torsion_polynomial', 'torsion_subgroup', 'two_descent', 'two_descent_simon', 'two_division_polynomial', 'two_torsion_rank', 'union', 'variable_name', 'variable_names', 'weierstrass_p', 'weil_restriction', 'zeta_series']\n"
]
}
],
"source": [
"# Try autocompleting the following. It has all the things!\n",
"print(dir(E))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"![All the things](https://cdn.meme.am/cache/instances/folder251/500x/79798251/x-all-the-things-all-the-elliptic-curve-things.jpg)\n",
"\n",
"This gives quick access to some data that is not stored within the LMFDB, but which is relatively quickly computable. For example,"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"data": {
"text/plain": [
"Ideal (-x^3 + x*y*z + y^2*z + 887688*x*z^2 + 321987008*z^3) of Multivariate Polynomial Ring in x, y, z over Rational Field"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"E.defining_ideal()"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"source": [
"But one of the great powers is that there are some things which are computed and stored in the LMFDB, and not in sage. We can now immediately give many examples of rank 3 elliptic curves with:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"There are 10 curves returned.\n",
"Elliptic Curve defined by y^2 + x*y + y = x^3 - 3476*x - 79152 over Rational Field\n"
]
}
],
"source": [
"Es = lmfdb_ecurve.search(conductor=11050, torsion_order=2)\n",
"print(\"There are {} curves returned.\".format(len(Es)))\n",
"E = Es[0]\n",
"print(E)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And for these curves, the lmfdb contains data on its rank, generators, regulator, and so on."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[(-34 : 17 : 1)]\n",
"1\n",
"1.63852610029\n"
]
}
],
"source": [
"print(E.gens())\n",
"print(E.rank())\n",
"print(E.regulator())"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 971 ms, sys: 6.82 ms, total: 978 ms\n",
"Wall time: 978 ms\n"
]
}
],
"source": [
"res = []\n",
"%time for E in Es: res.append(E.gens()); res.append(E.rank()); res.append(E.regulator())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"That's pretty fast, and this is because all of this was pulled from the LMFDB when the curves were returned by the `search()` function.\n",
"\n",
"In this case, elliptic curves over the rationals are only an okay example, as they're really well studied and sage can compute much of the data very quickly. On the other hand, through the LMFDB there are millions of examples and corresponding data at one's fingertips.\n",
"\n",
"### This is where we're really looking for input.\n",
"\n",
"Think of what you might want to have easy access to through an interface from sage to the LMFDB, and tell us. We're actively seeking comments, suggestions, and requests. Elliptic curves over the rationals are a prototype, and the LMFDB has lots of (much more challenging to compute) data. There is data on the LMFDB that is simply not accessible from within sage.\n",
"\n",
"**email: david@lowryduda.com, or post an issue on https://github.com/LMFDB/lmfdb/issues**\n",
"\n",
"\n",
"\n",
"## Now let's describe what's going on under the hood a little bit\n",
"\n",
"There is an API for the LMFDB at http://beta.lmfdb.org/api/. This API is a bit green, and we will change certain aspects of it to behave better in the future. A call to the API [looks like](http://beta.lmfdb.org/api/elliptic_curves/curves/?rank=i1&conductor=i11050&_format=json)\n",
"\n",
" http://beta.lmfdb.org/api/elliptic_curves/curves/?rank=i1&conductor=i11050\n",
" \n",
"The result is a large mess of data, which can be exported as json and parsed.\n",
"\n",
"But that's hard, and the resulting data are not sage objects. They are just strings or ints, and these require time *and thought* to parse.\n",
"\n",
"So we created a module in sage that writes the API call and parses the output back into sage objects. The 22 curves given by the above API call are the same 22 curves returned by this call:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"22\n"
]
}
],
"source": [
"Es = lmfdb_ecurve.search(rank=1, conductor=11050, max_items=25)\n",
"print(len(Es))\n",
"E = Es[0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The total functionality of this search function is visible from its current documentation."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" Search the LMFDB for an elliptic curve.\n",
"\n",
" Note that all inputs are optional, but at least one input is necessary.\n",
"\n",
" INPUT:\n",
"\n",
" - ``label=l`` -- a string ``l`` representing a label in the LMFDB.\n",
"\n",
" - ``degree=d`` -- an int ``d`` giving the minimum degree of a\n",
" parameterization of the modular curve\n",
"\n",
" - ``conductor=c`` -- an int ``c`` giving the conductor of the curve\n",
"\n",
" - ``min_conductor=mc`` -- an int ``mc`` giving a lower bound on the\n",
" conductor for desired curves\n",
"\n",
" - ``max_conductor=mc`` -- an int ``mc`` giving an upper bound on the\n",
" conductor for desired curves\n",
"\n",
" - ``torsion_order=t`` -- an int ``t`` giving the order of the torsion\n",
" subgroup of the curve\n",
"\n",
" - ``rank=r`` -- an int ``r`` giving the rank of the curve\n",
"\n",
" - ``regulator=f`` -- a float ``f`` giving the regulator of the curve\n",
"\n",
" - ``max_items=m`` -- an int ``m`` (default: 10, max: 100) indicating the\n",
" maximum number of results to return\n",
"\n",
" - ``base_item=b`` -- an int ``b`` (default: 0) specifying where to start\n",
" returning values from. The search will begin by returning the ``b``th\n",
" curve. Combined with ``max_items`` to return data in chunks.\n",
"\n",
" - ``sort=s`` -- a string ``s`` specifying what database field to sort the\n",
" results on. See the LMFDB api for more info.\n",
"\n",
" EXAMPLES::\n",
"\n",
" sage: Es = search(conductor=11050, rank=2)\n",
" [Elliptic Curve defined by y^2 + x*y = x^3 - x^2 - 442*x + 1716 over Rational Field, Elliptic Curve defined by y^2 + x*y = x^3 - x^2 + 1558*x + 11716 over Rational Field]\n",
" sage: E = E[0]\n",
" sage: E.conductor()\n",
" 11050\n",
" \n"
]
}
],
"source": [
"# Execute this cell for the documentation\n",
"print(lmfdb_ecurve.search.__doc__)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[Elliptic Curve defined by y^2 + y = x^3 + x^2 - 5155*x + 140756 over Rational Field]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# So, for instance, one could perform the following search, finding a unique elliptic curve\n",
"lmfdb_ecurve.search(rank=2, torsion_order=3, degree=4608)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### What if there are no curves?\n",
"\n",
"If there are no curves satisfying the search criteria, then a message is displayed and that's that. These searches may take a couple of seconds to complete.\n",
"\n",
"For example, no elliptic curve in the database has rank 5."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"No fields were found satisfying input criteria.\n"
]
}
],
"source": [
"lmfdb_ecurve.search(rank=5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### How does one step through the data?\n",
"\n",
"Right now, at most 100 curves are returned in a single API call. This is the limit even from directly querying the API. But one can pass in the argument `base_item` (the name will probably change... to `skip`? or perhaps to `offset`?) to start returning at the `base_item`th element."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[Elliptic Curve defined by y^2 + x*y = x^3 - 887688*x - 321987008 over Rational Field,\n",
" Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 + 10795*x - 97828 over Rational Field,\n",
" Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 2294115305*x - 42292668425178 over Rational Field]\n",
"\n",
"[Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 2294115305*x - 42292668425178 over Rational Field,\n",
" Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 3170*x - 49318 over Rational Field,\n",
" Elliptic Curve defined by y^2 + y = x^3 + 1050*x - 26469 over Rational Field]\n"
]
}
],
"source": [
"from pprint import pprint\n",
"pprint(lmfdb_ecurve.search(rank=1, max_items=3)) # The last item in this list\n",
"print('')\n",
"pprint(lmfdb_ecurve.search(rank=1, max_items=3, base_item=2)) # should be the first item in this list"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Included in the documentation is also a bit of hopefulness. Right now, the LMFDB API does not actually accept `max_conductor` or `min_conductor` (or arguments of that type). But it will sometime. (This introduces a few extra difficulties on the server side, and so it will take some extra time to decide how to do this)."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"ename": "NotImplementedError",
"evalue": "This would be a great thing to have, but the LMFDB api does not yet provide this functionality.",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-14-3d98f2cf7a13>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mlmfdb_ecurve\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msearch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrank\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmin_conductor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m500\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax_conductor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Not implemented\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/home/djlowry/Dropbox/EllipticCurve_LMFDB/LMFDB2sage/elliptic_curves.py\u001b[0m in \u001b[0;36msearch\u001b[0;34m(**kwargs)\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 77\u001b[0m raise NotImplementedError(\"This would be a great thing to have, \" +\n\u001b[0;32m---> 78\u001b[0;31m \"but the LMFDB api does not yet provide this functionality.\")\n\u001b[0m\u001b[1;32m 79\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 80\u001b[0m \u001b[0;32mpass\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNotImplementedError\u001b[0m: This would be a great thing to have, but the LMFDB api does not yet provide this functionality."
]
}
],
"source": [
"lmfdb_ecurve.search(rank=1, min_conductor=500, max_conductor=10000) # Not implemented"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"source": [
"Our `EllipticCurve_rational_field_lmfdb` class constructs a sage elliptic curve from the json and overrides (somem of the) the default methods in sage if there is quicker data available on the LMFDB. In principle, this new object is just a sage object with some slightly different methods.\n",
"\n",
"Generically, documentation and introspection on objects from this class should work. Much of sage's documentation carries through directly."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" Return generators for the Mordell-Weil group E(Q) *modulo*\n",
" torsion.\n",
"\n",
" .. warning::\n",
"\n",
" If the program fails to give a provably correct result, it\n",
" prints a warning message, but does not raise an\n",
" exception. Use :meth:`~gens_certain` to find out if this\n",
" warning message was printed.\n",
"\n",
" INPUT:\n",
"\n",
" - ``proof`` -- bool or None (default None), see\n",
" ``proof.elliptic_curve`` or ``sage.structure.proof``\n",
"\n",
" - ``verbose`` - (default: None), if specified changes the\n",
" verbosity of mwrank computations\n",
"\n",
" - ``rank1_search`` - (default: 10), if the curve has analytic\n",
" rank 1, try to find a generator by a direct search up to\n",
" this logarithmic height. If this fails, the usual mwrank\n",
" procedure is called.\n",
"\n",
" - algorithm -- one of the following:\n",
"\n",
" - ``'mwrank_shell'`` (default) -- call mwrank shell command\n",
"\n",
" - ``'mwrank_lib'`` -- call mwrank C library\n",
"\n",
" - ``only_use_mwrank`` -- bool (default True) if False, first\n",
" attempts to use more naive, natively implemented methods\n",
"\n",
" - ``use_database`` -- bool (default True) if True, attempts to\n",
" find curve and gens in the (optional) database\n",
"\n",
" - ``descent_second_limit`` -- (default: 12) used in 2-descent\n",
"\n",
" - ``sat_bound`` -- (default: 1000) bound on primes used in\n",
" saturation. If the computed bound on the index of the\n",
" points found by two-descent in the Mordell-Weil group is\n",
" greater than this, a warning message will be displayed.\n",
"\n",
" OUTPUT:\n",
"\n",
" - ``generators`` - list of generators for the Mordell-Weil\n",
" group modulo torsion\n",
"\n",
" IMPLEMENTATION: Uses Cremona's mwrank C library.\n",
"\n",
" EXAMPLES::\n",
"\n",
" sage: E = EllipticCurve('389a')\n",
" sage: E.gens() # random output\n",
" [(-1 : 1 : 1), (0 : 0 : 1)]\n",
"\n",
" A non-integral example::\n",
"\n",
" sage: E = EllipticCurve([-3/8,-2/3])\n",
" sage: E.gens() # random (up to sign)\n",
" [(10/9 : 29/54 : 1)]\n",
"\n",
" A non-minimal example::\n",
"\n",
" sage: E = EllipticCurve('389a1')\n",
" sage: E1 = E.change_weierstrass_model([1/20,0,0,0]); E1\n",
" Elliptic Curve defined by y^2 + 8000*y = x^3 + 400*x^2 - 320000*x over Rational Field\n",
" sage: E1.gens() # random (if database not used)\n",
" [(-400 : 8000 : 1), (0 : -8000 : 1)]\n",
" \n"
]
}
],
"source": [
"print(E.gens.__doc__)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Modified methods should have a note indicating that the data comes from the LMFDB, and then give sage's documentation. This is not yet implemented. (So if you examine the current version, you can see some incomplete docstrings like `regulator()`.)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" Return the regulator of the curve. This is taken from the lmfdb if available.\n",
"\n",
" NOTE:\n",
" In later implementations, this docstring will probably include the\n",
" docstring from sage's regular implementation. But that's not\n",
" currently the case.\n",
" \n"
]
}
],
"source": [
"print(E.regulator.__doc__)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## This concludes our demo of an interface between sage and the LMFDB.\n",
"\n",
"Thank you, and if you have any questions, comments, or concerns, please find me/email me/raise an issue on LMFDB's github.\n",
"\n",
"![XKCD's automation](https://imgs.xkcd.com/comics/automation.png)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "SageMath 8.0.rc1",
"language": "",
"name": "sagemath"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment