Skip to content

Releases: sagemath/sage

4.3.4

17 Aug 00:21
Compare
Choose a tag to compare

Sage 4.3.4 (released Mar 19, 2010; changelog)

120 tickets (PRs) merged, 55 contributors

Full Changelog: 4.3.3...4.3.4

4.3.3

17 Aug 00:20
Compare
Choose a tag to compare

Sage 4.3.3 (released Feb 21, 2010; changelog)

131 tickets (PRs) merged, 54 contributors

Full Changelog: 4.3.2...4.3.3

4.3.2

17 Aug 00:20
Compare
Choose a tag to compare

Release Tour

Sage 4.3.2 was released on Feb 6, 2010 (changelog), 126 tickets (PRs) merged, 41 contributors.

Major features

  • much improved interface to Singular which makes using any Singular function much more efficient and easy (cf. Libraries section below)

Libraries

  • much improved interface to Singular which makes using any Singular function much more efficient and easy #7939
sage: P.<x,y,z> = QQ[];
sage: A = Matrix(ZZ,[[1,1,0],[0,1,1]])
sage: toric_ideal = sage.libs.singular.ff.toric__lib.toric_ideal # we load the function
sage: toric_ideal(A,"du") # the integer matrix does not tell us which ring we want
Traceback (most recent call last)
...
ValueError: Could not detect ring.

sage: toric_ideal(A,"du",ring=P) # so we try again
[x*z - y]

Geometry

  • a major refactoring of the Polyhedron class fixed many bugs, added new functionality, and created a cleaner structure that should make future improvements much easier.

Full Changelog: 4.3.1...4.3.2

4.3.1

17 Aug 00:19
Compare
Choose a tag to compare

Release Tour

Sage 4.3.1 was released on Jan 20, 2010 (changelog), 193 tickets (PRs) merged, 55 contributors.

Major features

  • Substantial work towards a complete SPARC Solaris 10 port. This is due to the hard work of David Kirkby. The relevant tickets include #6595, #7067, #7138, #7162, #7387, #7505, #7781, #7815, #7817, #7849
  • We're moving closer towards a FreeBSD port, thanks to the work of Peter Jeremy at ticket #7825.

Algebra

  • Chinese Remainder Theorem for polynomials #7595 (Robert Miller) -- An implementation of the Chinese Remainder Theorem is needed for general descents on elliptic curves. Here are some examples for polynomial rings:
sage: K.<a> = NumberField(x^3 - 7)
sage: R.<y> = K[]
sage: f = y^2 + 3
sage: g = y^3 - 5
sage: CRT(1,3,f,g)
-3/26*y^4 + 5/26*y^3 + 15/26*y + 53/26
sage: CRT(1,a,f,g)
(-3/52*a + 3/52)*y^4 + (5/52*a - 5/52)*y^3 + (15/52*a - 15/52)*y + 27/52*a + 25/52
 

This also works for any number of moduli:

sage: K.<a> = NumberField(x^3 - 7)
sage: R.<x> = K[]
sage: CRT([], [])
0
sage: CRT([a], [x])
a
sage: f = x^2 + 3
sage: g = x^3 - 5
sage: h = x^5 + x^2 - 9
sage: k = CRT([1, a, 3], [f, g, h]); k
(127/26988*a - 5807/386828)*x^9 + (45/8996*a - 33677/1160484)*x^8 + (2/173*a - 6/173)*x^7 + (133/6747*a - 5373/96707)*x^6 + (-6/2249*a + 18584/290121)*x^5 + (-277/8996*a + 38847/386828)*x^4 + (-135/4498*a + 42673/193414)*x^3 + (-1005/8996*a + 470245/1160484)*x^2 + (-1215/8996*a + 141165/386828)*x + 621/8996*a + 836445/386828
sage: k.mod(f)
1
sage: k.mod(g)
a
sage: k.mod(h)
3
 

Basic arithmetic

  • Implement conjugate() for RealDoubleElement #7834 (Dag Sverre Seljebotn) --- New method conjugate() in the class RealDoubleElement of the module sage/rings/real_double.pyx for returning the complex conjugate of a real number. This is consistent with conjugate() methods in ZZ and RR. For example, ```txt
    sage: ZZ(5).conjugate()
    5
    sage: RR(5).conjugate()
    5.00000000000000
    sage: RDF(5).conjugate()
    5.0
* Improvements to complex arithmetic-geometric mean for real and complex double fields  <a class="http" href="http://trac.sagemath.org/sage_trac/ticket/7739">#7739</a> (Robert Bradshaw, John Cremona) --- Adds an `algorithm` option to the method `agm()` for complex numbers. The values of `algorithm` be can: 
   * "pari" --- Call the agm function from the Pari library. 
   * "optimal" --- Use the AGM sequence such that at each stage `(a,b)` is replaced by `(a_1,b_1) = ((a+b)/2,\pm\sqrt{ab})` where the sign is chosen so that `|a_1-b_1| \le |a_1+b_1|`, or equivalently `\Re(b_1/a_1)\ge0`. The resulting limit is maximal among all possible values. 
   * "principal" --- Use the AGM sequence such that at each stage `(a,b)` is replaced by `(a_1,b_1) = ((a+b)/2,\pm\sqrt{ab})` where the sign is chosen so that `\Re(b_1/a_1)\ge0` (the so-called principal branch of the square root). The following examples illustrate that the returned value depends on the algorithm parameter: ```txt
sage: a = CDF(-0.95, -0.65)
sage: b = CDF(0.683, 0.747)
sage: a.agm(b, algorithm="optimal")
-0.371591652352 + 0.319894660207*I
sage: a.agm(b, algorithm="principal")
0.338175462986 - 0.0135326969565*I
sage: a.agm(b, algorithm="pari")
0.080689185076 + 0.239036532686*I
 

The same thing for multiprecision real and complex numbers has also been implemented #7719 and will be in the next release.

  • New decorator coerce_binop #383 (Robert Bradshaw) --- The new decroator coerce_binop can be applied to methods to ensure the arguments have the same parent. For example
@coerce_binop
def quo_rem(self, other):
    ...
 

will guarantee that self and other have the same parent before this method is called.

Combinatorics

  • Weyl group optimizations #7754 (Nicolas M. Thiéry) --- Three major improvements that indirectly also improve efficiency of most Weyl group routines:
    • Faster hash method calling the hash of the underlying matrix (which is set as immutable for that purpose).
    • New __eq__() method.
    • Action on the weight lattice realization: optimization of the matrix multiplication. Some operations are now up to 34% faster than previously:
BEFORE

sage: W = WeylGroup(["F", 4])
sage: W.cardinality()
1152
sage: %time list(W);
CPU times: user 10.51 s, sys: 0.05 s, total: 10.56 s
Wall time: 10.56 s
sage: W = WeylGroup(["E", 8])
sage: %time W.long_element();
CPU times: user 1.47 s, sys: 0.00 s, total: 1.47 s
Wall time: 1.47 s


AFTER

sage: W = WeylGroup(["F", 4])
sage: W.cardinality()
1152
sage: %time list(W);
CPU times: user 6.89 s, sys: 0.04 s, total: 6.93 s
Wall time: 6.93 s
sage: W = WeylGroup(["E", 8])
sage: %time W.long_element();
CPU times: user 1.21 s, sys: 0.00 s, total: 1.21 s
Wall time: 1.21 s
 
  • Implement the Gale Ryser theorem #7301 (Nathann Cohen, David Joyner) --- The Gale Ryser theorem asserts that if p_1, p_2 are two partitions of n of respective lengths k_1, k_2, then there is a binary k_1 \times k_2 matrix M such that p_1 is the vector of row sums and p_2 is the vector of column sums of M, if and only if p_2 dominates p_1. T.S. Michael helped a great deal with the refereeing process. Here are some examples:
sage: from sage.combinat.integer_vector import gale_ryser_theorem
sage: p1 = [4, 2, 2]
sage: p2 = [3, 3, 1, 1]
sage: gale_ryser_theorem(p1, p2)
[1 1 1 1]
[1 1 0 0]
[1 1 0 0]
sage: p1 = [4, 2, 2, 0]
sage: p2 = [3, 3, 1, 1, 0, 0]
sage: gale_ryser_theorem(p1, p2)
[1 1 1 1 0 0]
[1 1 0 0 0 0]
[1 1 0 0 0 0]
[0 0 0 0 0 0]
 
  • Iwahori Hecke algebras on the T basis #7729 (Daniel Bump, Nicolas M. Thiéry) --- Iwahori Hecke algebras are deformations of the group algebras of Coxeter groups, such as Weyl groups (finite or affine). Here are some examples:
sage: R.<q> = PolynomialRing(QQ)
sage: H = IwahoriHeckeAlgebra("A3", q)
sage: [T1, T2, T3] = H.algebra_generators()
sage: T1 * (T2 + T3) * T1
T1*T2*T1 + (q-1)*T3*T1 + q*T3
 
  • Coxeter groups: more Bruhat and weak order features #7753 (Nicolas M. Thiéry, Daniel Bump) --- Four new methods implementing the Bruhat order for Coxeter groups. The method bruhat_le() for Bruhat comparison:
sage: W = WeylGroup(["A", 3])
sage: u = W.from_reduced_word([1, 2, 1])
sage: v = W.from_reduced_word([1, 2, 3, 2, 1])
sage: u.bruhat_le(u)
True
sage: u.bruhat_le(v)
True
sage: v.bruhat_le(u)
False
sage: v.bruhat_le(v)
True
sage: s = W.simple_reflections()
sage: s[1].bruhat_le(W.one())
False
 

The method weak_le() for comparison in weak order:

sage: W = WeylGroup(["A", 3])
sage: u = W.from_reduced_word([1, 2])
sage: v = W.from_reduced_word([1, 2, 3, 2])
sage: u.weak_le(u)
True
sage: u.weak_le(v)
True
sage: v.weak_le(u)
False
sage: v.weak_le(v)
True
 

The method bruhat_poset() returns the Bruhat poset of a Weyl group:

sage: W = WeylGroup(["A", 3])
sage: P = W.bruhat_poset()
sage: u = W.from_reduced_word([3, 1])
sage: v = W.from_reduced_word([3, 2, 1, 2, 3])
sage: P(u) <= P(v)
True
sage: len(P.interval(P(u), P(v)))
10
sage: P.is_join_semilattice()
False
 

The method weak_poset() returns the left (resp. right) poset for weak order:

sage: W = WeylGroup(["A", 2])
sage: P = W.weak_poset(); P
Finite poset containing 6 elements
sage: W = WeylGroup(["B", 3])
sage: P = W.weak_poset(side="left")
sage: P.is_join_semilattice(), P.is_meet_semilattice()
(True, True)
 
  • Interval exchange transformations #7145 (Vincent Delecroix) --- New module for manipulating interval exchange transformations and linear involutions. Here, we create an interval exchange transformation:
sage: T = iet.IntervalExchangeTransformation(('a b','b a'),(sqrt(2),1))
sage: print T
Interval exchange transformation of [0, sqrt(2) + 1[ with permutation
a b
b a
 

It can also be initialized using permutation (group theoretic ones):

sage: p = Permutation([3,2,1])
sage: T = iet.IntervalExchangeTransformation(p, [1/3,2/3,1])
sage: print T
Interval exchange transformation of [0, 2[ with permutation
1 2 3
3 2 1
 

For the manipulation of permutations of IET, there are special types provided by this module. All of them can be constructed using the con...

Read more

4.3

17 Aug 00:18
Compare
Choose a tag to compare
4.3

Sage 4.3 Release Tour

Sage 4.3 was released on Dec 24, 2009 (changelog), 237 tickets (PRs) merged, 63 contributors.

Major features:

  • Improvements in the build system.
  • Major new features in the Sage notebook server.
  • Numerous new features in the combinatorics module.
  • Many improvements in the graph theory module, both the backend implementation and new features.
  • Updates/upgrades to 15 packages.

Algebra

Algebraic Topology

Calculus

Categories

Combinatorics

Commutative Algebra

Documentation

Graph Theory

Group Theory

Linear Algebra

Miscellaneous

Numerical

Packages

Statistics

Symbolics

Full Changelog: 4.2.1...4.3

4.2.1

17 Aug 00:18
Compare
Choose a tag to compare

Sage 4.2.1 (released Nov 14, 2009; changelog)

94 tickets (PRs) merged, 42 contributors

Full Changelog: 4.1.2...4.2.1

4.2

17 Aug 00:17
Compare
Choose a tag to compare
4.2

Sage 4.2 (released Oct 24, 2009; changelog)

109 tickets (PRs) merged, 43 contributors

Full Changelog: 4.1.2...4.2

4.1.2

17 Aug 00:16
Compare
Choose a tag to compare

Sage 4.1.2 (released Oct 14, 2009; changelog)

245 tickets (PRs) merged, 79 contributors

Full Changelog: 4.1.1...4.1.2

4.1.1

17 Aug 00:15
Compare
Choose a tag to compare

Release Tour

Sage 4.1.1 was released on August 14th, 2009 (changelog), 165 tickets (PRs) merged, 56 contributors. A nicely formatted version of this release tour can be found here. The following points are some of the foci of this release:

  • Improved data conversion between NumPy and Sage
  • Solaris support, Solaris specific bug fixes for NTL, zn_poly, Pari/GP, FLINT, MPFR, PolyBoRI, ATLAS
  • Upgrade/updates for about 8 standard packages
  • Three new optional packages: openopt, GLPK, p_group_cohomology

Algebra

  • Adds method __nonzero__() to abelian groups (Taylor Sutton) #6510 --- New method __nonzero__() for the class AbelianGroup_class in sage/groups/abelian_gps/abelian_group.py. This method returns True if the abelian group in question is non-trivial:
sage: E = EllipticCurve([0, 82])
sage: T = E.torsion_subgroup()
sage: bool(T)
False
sage: T.__nonzero__()
False
 

Basic Arithmetic

  • Implement real_part() and imag_part() for CDF and CC (Alex Ghitza) #6159 --- The name real_part is now an alias to the method real(); similarly, imag_part is now an alias to the method imag().
sage: a = CDF(3, -2)
sage: a.real()
3.0
sage: a.real_part()
3.0
sage: a.imag()
-2.0
sage: a.imag_part()
-2.0
sage: i = ComplexField(100).0
sage: z = 2 + 3*i
sage: z.real()
2.0000000000000000000000000000
sage: z.real_part()
2.0000000000000000000000000000
sage: z.imag()
3.0000000000000000000000000000
sage: z.imag_part()
3.0000000000000000000000000000
 
  • Efficient summing using balanced sum (Jason Grout, Mike Hansen) #2737 --- New function balanced_sum() in the module sage/misc/misc_c.pyx for summing the elements in a list. In some cases, balanced_sum() is more efficient than the built-in Python sum() function, where the efficiency can range from 26x up to 1410x faster than sum(). The following timing statistics were obtained using the machine sage.math:
sage: R.<x,y> = QQ["x,y"]
sage: L = [x^i for i in range(1000)]
sage: %time sum(L);
CPU times: user 0.01 s, sys: 0.00 s, total: 0.01 s
Wall time: 0.01 s
sage: %time balanced_sum(L);
CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 0.00 s
sage: %timeit sum(L);
100 loops, best of 3: 8.66 ms per loop
sage: %timeit balanced_sum(L);
1000 loops, best of 3: 324 µs per loop
sage: 
sage: L = [[i] for i in range(10e4)]
sage: %time sum(L, []);
CPU times: user 84.61 s, sys: 0.00 s, total: 84.61 s
Wall time: 84.61 s
sage: %time balanced_sum(L, []);
CPU times: user 0.06 s, sys: 0.00 s, total: 0.06 s
Wall time: 0.06 s
 

Calculus

  • Wigner 3j, 6j, 9j, Clebsch-Gordan, Racah and Gaunt coefficients (Jens Rasch) #5996 --- A collection of functions for exactly calculating Wigner 3j, 6j, 9j, Clebsch-Gordan, Racah as well as Gaunt coefficients. All these functions evaluate to a rational number times the square root of a rational number. These new functions are defined in the module sage/functions/wigner.py. Here are some examples on calculating the Wigner 3j, 6j, 9j symbols:
sage: wigner_3j(2, 6, 4, 0, 0, 0)
sqrt(5/143)
sage: wigner_3j(0.5, 0.5, 1, 0.5, -0.5, 0)
sqrt(1/6)
sage: wigner_6j(3,3,3,3,3,3)
-1/14
sage: wigner_6j(8,8,8,8,8,8)
-12219/965770
sage: wigner_9j(1,1,1, 1,1,1, 1,1,0 ,prec=64) # ==1/18
0.0555555555555555555
sage: wigner_9j(15,15,15, 15,3,15, 15,18,10, prec=1000)*1.0
-0.0000778324615309539
 

The Clebsch-Gordan, Racah and Gaunt coefficients can be computed as follows:

sage: simplify(clebsch_gordan(3/2,1/2,2, 3/2,1/2,2))
1
sage: clebsch_gordan(1.5,0.5,1, 1.5,-0.5,1)
1/2*sqrt(3)
sage: racah(3,3,3,3,3,3)
-1/14
sage: gaunt(1,0,1,1,0,-1)
-1/2/sqrt(pi)
sage: gaunt(12,15,5,2,3,-5)
91/124062*sqrt(36890)/sqrt(pi)
sage: gaunt(1000,1000,1200,9,3,-12).n(64)
0.00689500421922113448
 

Combinatorics

  • Optimize the words library code (Vincent Delecroix, Sébastien Labbé, Franco Saliola) #6519 --- An enhancement of the words library code in sage/combinat/words to improve its efficiency and reorganize the code. The efficiency gain for creating small words can be up to 6x:
# BEFORE

sage: %timeit Word()
10000 loops, best of 3: 46.6 µs per loop
sage: %timeit Word("abbabaab")
10000 loops, best of 3: 62 µs per loop
sage: %timeit Word([0,1,1,0,1,0,0,1])
10000 loops, best of 3: 59.4 µs per loop


# AFTER

sage: %timeit Word()
100000 loops, best of 3: 6.85 µs per loop
sage: %timeit Word("abbabaab")
100000 loops, best of 3: 11.8 µs per loop
sage: %timeit Word([0,1,1,0,1,0,0,1])
100000 loops, best of 3: 10.6 µs per loop
 

For the creation of large words, the improvement can be from between 8000x up to 39000x:

# BEFORE

sage: t = words.ThueMorseWord()
sage: w = list(t[:1000000])
sage: %timeit Word(w)
10 loops, best of 3: 792 ms per loop
sage: u = "".join(map(str, list(t[:1000000])))
sage: %timeit Word(u)
10 loops, best of 3: 777 ms per loop
sage: %timeit Words("01")(u)
10 loops, best of 3: 748 ms per loop


# AFTER

sage: t = words.ThueMorseWord()
sage: w = list(t[:1000000])
sage: %timeit Word(w)
10000 loops, best of 3: 20.3 µs per loop
sage: u = "".join(map(str, list(t[:1000000])))
sage: %timeit Word(u)
10000 loops, best of 3: 21.9 µs per loop
sage: %timeit Words("01")(u)
10000 loops, best of 3: 84.3 µs per loop
 

All of the above timing statistics were obtained using the machine sage.math. Further timing comparisons can be found at the Sage wiki page.

  • Improve the speed of Permutation.inverse() (Anders Claesson) #6621 --- In some cases, the speed gain is up to 11x. The following timing statistics were obtained using the machine sage.math:
#!python numbers=off 
# BEFORE

sage: p = Permutation([6, 7, 8, 9, 4, 2, 3, 1, 5])
sage: %timeit p.inverse()
10000 loops, best of 3: 67.1 µs per loop
sage: p = Permutation([19, 5, 13, 8, 7, 15, 9, 10, 16, 3, 12, 6, 2, 20, 18, 11, 14, 4, 17, 1])
sage: %timeit p.inverse()                                                       
1000 loops, best of 3: 240 µs per loop
sage: p = Permutation([14, 17, 1, 24, 16, 34, 19, 9, 20, 18, 36, 5, 22, 2, 27, 40, 37, 15, 3, 35, 10, 25, 21, 8, 13, 26, 12, 32, 23, 38, 11, 4, 6, 39, 31, 28, 29, 7, 30, 33])
sage: %timeit p.inverse()                                                       
1000 loops, best of 3: 857 µs per loop


# AFTER

sage: p = Permutation([6, 7, 8, 9, 4, 2, 3, 1, 5])
sage: %timeit p.inverse()
10000 loops, best of 3: 24.6 µs per loop
sage: p = Permutation([19, 5, 13, 8, 7, 15, 9, 10, 16, 3, 12, 6, 2, 20, 18, 11, 14, 4, 17, 1])
sage: %timeit p.inverse()
10000 loops, best of 3: 41.4 µs per loop
sage: p = Permutation([14, 17, 1, 24, 16, 34, 19, 9, 20, 18, 36, 5, 22, 2, 27, 40, 37, 15, 3, 35, 10, 25, 21, 8, 13, 26, 12, 32, 23, 38, 11, 4, 6, 39, 31, 28, 29, 7, 30, 33])
sage: %timeit p.inverse()
10000 loops, best of 3: 72.4 µs per loop
 
  • Updating some quirks in sage/combinat/partition.py (Andrew Mathas) #5790 --- The functions r_core(), r_quotient(), k_core(), and partition_sign() are now deprecated. These are replaced with core(), quotient(), and sign() respectively. The rewrite of the function Partition() deprecated the argument core_and_quotient. The core and the quotient can be passed as keywords of Partition().
sage: Partition(core_and_quotient=([2,1], [[2,1],[3],[1,1,1]]))
/home/mvngu/.sage/temp/sage.math.washington.edu/9221/_home_mvngu__sage_init_sage_0.py:1: DeprecationWarning: "core_and_quotient=(*)" is deprecated. Use "core=[*], quotient=[*]" instead.
  # -*- coding: utf-8 -*-
[11, 5, 5, 3, 2, 2, 2]
sage: Partition(core=[2,1], quotient=[[2,1],[3],[1,1,1]])
[11, 5, 5, 3, 2, 2, 2]

sage: Partition([6,3,2,2]).r_quotient(3)
/home/mvngu/.sage/temp/sage.math.washington.edu/9221/_home_mvngu__sage_init_sage_0.py:1: DeprecationWarning: r_quotient is deprecated. Please use quotient instead.
  # -*- coding: utf-8 -*-
[[], [], [2, 1]]
sage: Partition([6,3,2,2]).quotient(3)
[[], [], [2, 1]]

sage: partition_sign([5,1,1,1,1,1])
/home/mvngu/.sage/temp/sage.math.washington.edu/9221/_home_mvngu__sage_init_sage_0.py:1: DeprecationWarning: "partition_sign deprecated. Use Partition(pi).sign() instead
  # -*- coding: utf-8 -*-
1
sage: Partition([5,1,1,1,1,1]).sign()
1
 

Cryptography

  • Improve S-box linear and differences matrices computation (Yann Laigle-Chapuy) #6454 --- Speed up the functions difference_distribution_matrix() and linear_approximation_matrix() of the class SBox in the module sage/crypto/mq/sbox.py. The function linear_approximation_matrix() now uses the Walsh transform. The efficiency of difference_distribution_matrix() can be up to 277x, while that for linear_approximation_matrix() can be up to 132x. The following timing statistics were ob...
Read more

4.1

17 Aug 00:15
Compare
Choose a tag to compare
4.1

Release Tour

Sage 4.1 was released on July 09, 2009 (changelog), 91 tickets (PRs) merged, 44 contributors. A nicely formatted version of this release tour can be found here. The following points are some of the foci of this release:

  • Upgrade to the Python 2.6.x series
  • Support for building Singular with GCC 4.4
  • FreeBSD support for the following packages: FreeType, gd, libgcrypt, libgpg-error, Linbox, NTL, Readline, Tachyon
  • Combinatorics: irreducible matrix representations of symmetric groups; and Yang-Baxter Graphs
  • Cryptography: Mini Advanced Encryption Standard for educational purposes
  • Graph theory: a backend for graph theory using Cython (c_graph); and improve accuracy of graph eigenvalues
  • Linear algebra: a general package for finitely generated, not-necessarily free R-modules; and multiplicative order for matrices over finite fields
  • Miscellaneous: optimized Sudoku solver; a decorator for declaring abstract methods; support Unicode in LaTeX cells (notebook); and optimized integer division
  • Number theory: improved random element generation for number field orders and ideals; support Michael Stoll's ratpoints package; and elliptic exponential
  • Numerical: computing numerical values of constants using mpmath
  • Update/upgrade 19 packages to latest upstream releases

Algebraic Geometry

  • Construct an elliptic curve from a plane curve of genus one (Lloyd Kilford, John Cremona ) -- New function EllipticCurve_from_plane_curve() in the module sage/schemes/elliptic_curves/constructor.py to allow the construction of an elliptic curve from a smooth plane cubic with a rational point. Currently, this function uses Magma and it will not work on machines that do not have Magma installed. Assuming you have Magma installed on your computer, we can use the function EllipticCurve_from_plane_curve() to first check that the Fermat cubic is isomorphic to the curve with Cremona label "27a1":
sage: x, y, z = PolynomialRing(QQ, 3, 'xyz').gens() # optional - magma  
sage: C = Curve(x^3 + y^3 + z^3) # optional - magma 
sage: P = C(1, -1, 0) # optional - magma 
sage: E = EllipticCurve_from_plane_curve(C, P) # optional - magma 
sage: E # optional - magma 
Elliptic Curve defined by y^2 + y = x^3 - 7 over Rational Field 
sage: E.label() # optional - magma 
'27a1'
 

Here is a quartic example:

sage: u, v, w = PolynomialRing(QQ, 3, 'uvw').gens() # optional - magma  
sage: C = Curve(u^4 + u^2*v^2 - w^4) # optional - magma 
sage: P = C(1, 0, 1) # optional - magma 
sage: E = EllipticCurve_from_plane_curve(C, P) # optional - magma 
sage: E # optional - magma 
Elliptic Curve defined by y^2  = x^3 + 4*x over Rational Field 
sage: E.label() # optional - magma 
'32a1'
 

Basic Arithmetic

  • Speed-up integer division (Robert Bradshaw ) -- In some cases, integer division is now up to 31% faster than previously. The following timing statistics were obtained using the machine sage.math:
# BEFORE

sage: a = next_prime(2**31)
sage: b = Integers(a)(100)
sage: %timeit a % b;
1000000 loops, best of 3: 1.12 µs per loop
sage: %timeit 101 // int(5);
1000000 loops, best of 3: 215 ns per loop
sage: %timeit 100 // int(-3)
1000000 loops, best of 3: 214 ns per loop
sage: a = ZZ.random_element(10**50)
sage: b = ZZ.random_element(10**15)
sage: %timeit a.quo_rem(b)
1000000 loops, best of 3: 454 ns per loop


# AFTER

sage: a = next_prime(2**31)
sage: b = Integers(a)(100)
sage: %timeit a % b;
1000000 loops, best of 3: 1.02 µs per loop
sage: %timeit 101 // int(5);
1000000 loops, best of 3: 201 ns per loop
sage: %timeit 100 // int(-3)
1000000 loops, best of 3: 194 ns per loop
sage: a = ZZ.random_element(10**50)
sage: b = ZZ.random_element(10**15)
sage: %timeit a.quo_rem(b)
1000000 loops, best of 3: 313 ns per loop
 

Combinatorics

  • Irreducible matrix representations of symmetric groups (Franco Saliola) -- Support for constructing irreducible representations of the symmetric group. This is based on Alain Lascoux's article Young representations of the symmetric group. The following types of representations are supported:
    * Specht representations -- The matrices have integer entries:
sage: chi = SymmetricGroupRepresentation([3, 2]); chi
Specht representation of the symmetric group corresponding to [3, 2]
sage: chi([5, 4, 3, 2, 1])

[ 1 -1  0  1  0]
[ 0  0 -1  0  1]
[ 0  0  0 -1  1]
[ 0  1 -1 -1  1]
[ 0  1  0 -1  1]
     * Young's seminormal representation -- The matrices have rational entries: 
sage: snorm = SymmetricGroupRepresentation([2, 1], "seminormal"); snorm
Seminormal representation of the symmetric group corresponding to [2, 1]
sage: snorm([1, 3, 2])

[-1/2  3/2]
[ 1/2  1/2]
     * Young's orthogonal representation (the matrices are orthogonal) -- These matrices are defined over Sage's `Symbolic Ring`: 
sage: ortho = SymmetricGroupRepresentation([3, 2], "orthogonal"); ortho
Orthogonal representation of the symmetric group corresponding to [3, 2]
sage: ortho([1, 3, 2, 4, 5])

[          1           0           0           0           0]
[          0        -1/2 1/2*sqrt(3)           0           0]
[          0 1/2*sqrt(3)         1/2           0           0]
[          0           0           0        -1/2 1/2*sqrt(3)]
[          0           0           0 1/2*sqrt(3)         1/2]

You can also create the CombinatorialClass of all irreducible matrix representations of a given symmetric group. Then particular representations can be created by providing partitions. For example:

sage: chi = SymmetricGroupRepresentations(5); chi
Specht representations of the symmetric group of order 5! over Integer Ring
sage: chi([5]) # the trivial representation
Specht representation of the symmetric group corresponding to [5]
sage: chi([5])([2, 1, 3, 4, 5])
[1]
sage: chi([1, 1, 1, 1, 1]) # the sign representation
Specht representation of the symmetric group corresponding to [1, 1, 1, 1, 1]
sage: chi([1, 1, 1, 1, 1])([2, 1, 3, 4, 5])
[-1]
sage: chi([3, 2])
Specht representation of the symmetric group corresponding to [3, 2]
sage: chi([3, 2])([5, 4, 3, 2, 1])

[ 1 -1  0  1  0]
[ 0  0 -1  0  1]
[ 0  0  0 -1  1]
[ 0  1 -1 -1  1]
[ 0  1  0 -1  1]

See the documentation of SymmetricGroupRepresentation and SymmetricGroupRepresentations for more information and examples.

  • Yang-Baxter graphs (Franco Saliola) -- Besides being used for constructing the irreducible matrix representations of the symmetric group, Yang-Baxter graphs can also be used to construct the Cayley graph of a finite group. For example:
sage: def left_multiplication_by(g):
....:     return lambda h : h*g
....: 
sage: G = AlternatingGroup(4)
sage: operators = [ left_multiplication_by(gen) for gen in G.gens() ]
sage: Y = YangBaxterGraph(root=G.identity(), operators=operators); Y
Yang-Baxter graph with root vertex ()
sage: Y.plot(edge_labels=False)

cayley-graph

  • Yang-Baxter graphs can also be used to construct the permutahedron:
sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
sage: operators = [SwapIncreasingOperator(i) for i in range(3)]
sage: Y = YangBaxterGraph(root=(1,2,3,4), operators=operators); Y
Yang-Baxter graph with root vertex (1, 2, 3, 4)
sage: Y.plot()

permutahedron

  • See the documentation of YangBaxterGraph for more information and examples.

Cryptography

  • Mini Advanced Encryption Standard for educational purposes (Minh Van Nguyen) -- New module sage/crypto/block_cipher/miniaes.py to support the Mini Advanced Encryption Standard (Mini-AES) to allow students to explore the working of a block cipher. This is a simplified variant of the Advanced Encryption Standard (AES) to be used for cryptography education. Mini-AES is described in the paper:
    • A. C.-W. Phan. Mini advanced encryption standard (mini-AES): a testbed for cryptanalysis students. Cryptologia, 26(4):283--306, 2002. We can encrypt a plaintext using Mini-AES as follows:
sage: from sage.crypto.block_cipher.miniaes import MiniAES
sage: maes = MiniAES()
sage: K = FiniteField(16, "x")
sage: MS = MatrixSpace(K, 2, 2)
sage: P = MS([K("x^3 + x"), K("x^2 + 1"), K("x^2 + x"), K("x^3 + x^2")]); P

[  x^3 + x   x^2 + 1]
[  x^2 + x x^3 + x^2]
sage: key = MS([K("x^3 + x^2"), K("x^3 + x"), K("x^3 + x^2 + x"), K("x^2 + x + 1")]); key

[    x^3 + x^2       x^3 + x]
[x^3 + x^2 + x   x^2 + x + 1]
sage: C = maes.encrypt(P, key); C

[            x       x^2 + x]
[x^3 + x^2 + x       x^3 + x]
 

Here is the decryption process:

sage: plaintxt = maes.decrypt(C, key)
sage: plaintxt == P
True
 

We can also work directly with binary strings:

sage: from sage.crypto.block_cipher.miniaes import MiniAES
sage: maes = MiniAES()
sage: bin = BinaryStrings()
sage: key = bin.encoding("KE"); key
0100101101000101
sage: P = bin.encoding("Encrypt this secret message!")
sage: C = maes(P, key, algorithm="encrypt")
sage: plaintxt = maes(C, key, algorithm="decrypt")
sage: plaintxt == P
True
 

Or work with integers n such that 0 <= n <= 15:

sage: from sage.crypto.block_cipher.miniaes import MiniAES
sage: maes = MiniAES()
sage: P = [n for n in xrange(16)]; P
[0, 1, 2, 3, 4, 5, 6, 7, 8, ...
Read more