Skip to content

Releases: sagemath/sage

4.3.5

17 Aug 00:22
Compare
Choose a tag to compare

Sage 4.3.5 (released Mar 28, 2010; changelog)

3 tickets (PRs) merged, 6 contributors

Full Changelog: 4.3.4...4.3.5

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