- LTK for installation and related
- Local SageMath files
- Local SageMath 'Ecole Mathématique Africaine - notebooks
- Paul Masson's succint overview

- iPhython.org
- SageMath on github - development
- SageMath.org - 'OpenSource Mathematica'
- SageMath docs
- Launching SageMath
- Alternative SageMath docs
- Alternative SageMath docs - Jacobi
- List of mathematical functions native to SageMath: - imports
- Getting help: use ? behind construction/object name, e.g. 'factor?'
- Getting help: use ? behind method name, e.g. for a method like
*small_roots*that is used like this : 'f.small_roots()' ask for help as 'f.small_roots?', see also https://ask.sagemath.org/question/25714/how-to-get-doc-for-object-methods-in-sage/

- Functionality: supports computation with objects in many different computer algebra systems “under one roof” using a common interface and clean programming language.
- GAP https://www.gap-system.org/ system for computational discrete algebra, emphasis on Computational Group Theory, consisting of a programming language, libraries, objects.
- GP/PARI
- Singular
- Maxima
- SageMath Wiki
- SageMath expository from David Joyner - legacy
- SageMath - William Stein - legacy

- 'sage' in a console starts a Sage session. To quit the session enter quit and then press
. - 'sage -n jupyter' in a console starts a Sage session in a Jupyter notebook
- HELP takes you to tutorials etc

- sagecell - on-line
- cocalc - collaborative - on-line

- With some minor exceptions, Sage uses the Python programming language, so most introductory books on Python will help you to learn Sage.
- Preceding a command with 'time' shows the time it took to perform the calculation.
- Use 'parent' to find out the construction, 'type' to find out its type.
- Use the 'tab'-button for autocompletion.
- Use the 'show' function to nicely display output in LaTeX style.

- Python 3 Language Reference - syntax and “core semantics” of the language
- Python 3 standard library - semantics of non-essential built-in object types and of the built-in functions and modules - Python objects and methods

- Any classes for mathematical objects in Sage should inherit from SageObject rather than from object. Most of the time, they actually inherit from a subclass such as Parent or Element.
- Printing should be done through _repr_ instead of __repr__ to allow for renaming.
- More generally, Sage-specific special methods are usually named _meth_ rather than __meth__. For example, lots of classes implement _hash_ which is used and cached by __hash__. In the same vein, elements of a group usually implement _mul_, so that there is no need to take care about coercions as they are done in __mul__.

- 7 # integer, type is
*class 'sage.rings.integer.Integer'*, parent is*Integer Ring* - 7.0 # real, type is
*class 'sage.rings.real_mpfr.RealLiteral*and parent is*Real Field with 53 bits of precision<*/li>

- To get help: 'numerical_approx?'
- Returns: 'numerical_approx(x, prec=None, digits=None, algorithm=None)'
- where prec is in bits, and digits is in decimal digits
- default is 53 bits of precision (approximately 16 digits)
- the accepted algorithms depend on the object

- If n is a number, len(n.str(2)) gives n's lenght as binary string.
- If n is a number, len(n.str(10)) gives n's lenght as decimal number.

- a = 5 # a is an integer
- type(a)
- class 'sage.rings.integer.Integer'
*a = 5/3 # now a is a rational number*- type(a)
*class 'sage.rings.rational.Rational'*- a = 'hello' # now a is a string
- type(a)
- <... 'str'>

- 2**3 # ** means exponent
- 2^3 # ^ is a synonym for ** (unlike in Python)
- 10 % 3 # for integer arguments, % means mod, i.e., remainder
- 10/4
- 10//4 # for integer arguments, // returns the integer quotient

- bool(sqrt(x**4)==x**2)
- Returns False # counter-intuitive but correct given signs
- One can use 'assume':
- assume(x > 0), bool(sqrt(x**4)==x**2)
- Returns: (none, True)
- Remember you clear your assumption with 'forget', and erase it completely with 'reset'.

- Definition: f(x,y) = (x^2+2*y)/(log(y)+1)
- Invocation ('evaluation'): f(0,1) returns '2'

- Use of 'substitution method': f(x,y).subs(x==1) returns (2*y + 1)/(log(y) + 1)
- Another 'substitution': f(x,y).subs(y==sqrt(3)) returns (x^2 + 2*sqrt(3))/(log(sqrt(3)) + 1)

- To compute the derivative of the function f(x,y) with respect to the variable y using the derivative method: f(x,y).derivative(y)
- There are many methods, which can be identified through autocompletion tab: f.tab

- Constructions - general “How do I construct … in Sage?”
- Constructions - number theory modular power, discrete log, primes, divisors, quadratic residus, ...

- Basics, log, exp background

- 'log(*args, **kwds)' # Returns the logarithm of the first argument to the base of the second argument
**which if missing defaults to "e"**. - examples:
- sage: log(e^2)
- 2
- To change the base of the logarithm, add the second parameter: sage: log(1000,10)
- 3
- The synonym "ln" can only take one argument: sage: ln(RDF(10))
- 2.302585092994046

- sage: F = GF(13); g = F.multiplicative_generator(); g
- 2
- sage: a = F(8)
- sage: log(a,g); g^log(a,g)
- 3
- 8
- sage: log(a,3)
- Traceback (most recent call last):
- ...
- ValueError: No discrete log of 8 found to base 3 modulo 13
- sage: log(F(9), 3)
- 2

- Rings - basics
- Finite Rings doc
- Integer Mod Ring doc
- Rings - SageMath tutorial include:
- the integers, called ZZ in Sage
- the rational numbers – i.e., fractions, or ratios, of integers – called QQ in Sage
- the real numbers, called RR in Sage
- the complex numbers, called CC in Sage

- One way:
*R =***Integers(97)**# 'Integers' creates a finite ring of integers mod 97- R
- Ring of integers modulo 97
- list(R)
- 0...96
- parent(R)
- class 'sage.rings.finite_rings.integer_mod_ring.IntegerModRing_generic_with_category'
- Another way:
- R =
**IntegerModRing(97)**# 'IntegerModRing(x) creates apparently the same of the preceding example - parent(R)
- class 'sage.rings.finite_rings.integer_mod_ring.IntegerModRing_generic_with_category>

- a = R(5)
- a
- 5
*parent(a)*- Ring of integers modulo 97
- a = R(2) / R(3)
- a
- 33
*a.rational_reconstruction()**2/3*

**Syntax 1**to build the ring R ℚ[𝑋] of polynomials with coefficients in ℚ and indeterminate X.- R.
= PolynomialRing(QQ) - R
- Univariate Polynomial Ring in X over Rational Field
- Find out about R
- R.base_ring()
- Rational Field
- R.variable_name()
- 'X'
- R.tab-for-autocomplete
**Syntax 2**to build the ring R ℚ[𝑋] of polynomials with coefficients in ℚ and indeterminate X.- R.< X > = QQ[]

- P.list() to list of coefficients of P,
- degree (to find the highest exponent of the variable),
- factor, and roots, e.g.
- R.
= PolynomialRing(QQ) - Q = X^3 + 4/3*X^2 + 4/3*X + 1/3
- Q.factor()
- (X + 1/3) * (X^2 + X + 1)
- Q.roots()
- [(-1/3, 1)])
- is_irreducible, ...

- R = IntegerModRing(15) # here n=15 and 'R = Integers(15)' is an equivalent syntax
- R(2021) # Converts an integer into an element of `R`, to construct an element of R
- R(2021).parent() # Contrary to what appears to be, this element is not an integer but an element of `R`
- R.is_field() # One may ask Sage about the properties of the ring `R` using its associated methods
- # Of course Z/15Z is not a field because 15 is not a prime number (hence there is no multiplicative inverse guaranteed for all elements)

- A.
= ZZ[] # ... with coefficients in Z - B.
= RR[] # ... with coefficients floating-point approximations of real numbers - C.
= GF(17)[] # ... with coefficients in a finite field of 17 elements

- M = X^3+X+1
- M.is_irreducible()
- True

- Using the change_ring method, construct the polynomial N which is a "copy" of M in ℝ[𝑋]
- Check if N is irreducible in ℝ[𝑋]
- If not, factor N in ℝ[𝑋]

- N=M.change_ring(RR)
- N
- X^3 + X + 1.00000000000000 # observe the real
- type(N)
- class 'sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense'
- N.is_irreducible()
- False
- factor(N)
- (X + 0.682327803828019) * (X^2 - 0.682327803828019*X + 1.46557123187677)
- So M is irreducible over ℚ but reducible over ℝ.

- R.
= RR[]; R - Univariate Polynomial Ring in x over Real Field with 53 bits of precision
- R.change_ring(QQ)
- Univariate Polynomial Ring in x over Rational Field

- A.
= PolynomialRing(QQ) # so three variables now - P = 2*x^2+y^3-y-2
- Q = x^2-x*y+y^2-1

- GF(3)
- Finite Field of size 3
*GF(27, 'a') # need to name the generator if not a prime field**Finite Field in a of size 3^3*- Zp(5)
- 5-adic Ring with capped relative precision 20

- gcd(m, n)
- factor(n) Use 'factor?' for help...
- Calls Pari’s factor C library function.
- This has proof
*False*by default. Sage has a global proof flag, set to True by default (see "sage.structure.proof.proof", or proof.[tab]). To override the default, call this function with proof=False. - E.g. sage: factor(3^89-1, proof=False)
- qsieve (n) - Bill Hart - the best algorithm for factoring numbers of the form
*pq*up to around 100 digits. - ecm.factor(n) - GMP-ECM - Paul Zimmerman
- The elliptic curve factorization (ECM) algorithm is the best algorithm for factoring numbers of the form
*n=pm*, where*p*is not “too big”. ECM is due to Hendrik Lenstra, which works by “pretending” that*n*is prime, choosing a random elliptic curve over Z/nZ, and doing arithmetic on that curve - if something goes wrong when doing arithmetic, we factor*n*.

- ratpoly.
= PolynomialRing(QQ) - realpoly.
= PolynomialRing(RR)

- factor(t^2-2)
- t^2 - 2
- factor(z^2-2)
- (z - 1.41421356237310) * (z + 1.41421356237310)

- b = R(47)
- b^20052005
- 50
*b.modulus()**97*- b.is_square()
- True

- For a prime: phi(p)=p-1
- For a composite: phi(20)=phi(4)*phi(5)=8, and this is {1, 3, 7, 9, 11, 13, 17, 19}

- sage: m = 8
- sage: Zmod(m).list_of_elements_of_multiplicative_group()
- [1, 3, 5, 7]

- sage: type(Zmod(m).list_of_elements_of_multiplicative_group()[0])

- sage: m = 8/li>
- sage: [ZZ(k) for k in Zmod(m).list_of_elements_of_multiplicative_group()]
- [1, 3, 5, 7]

- sage: [ZZ(k) for k in Zmod(m).list_of_elements_of_multiplicative_group()][0].parent()
- Integer Ring

- sage: m = 8
- sage: m.coprime_integers(m)

- sage: m.coprime_integers(29) # list up to 29 (excluded)
- [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27]

- sage: m.coprime_integers(m)[0].parent()
- Integer Ring