Releases: sagemath/sage
4.3.5
4.3.4
4.3.3
4.3.2
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
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()
forRealDoubleElement
#7834 (Dag Sverre Seljebotn) --- New methodconjugate()
in the classRealDoubleElement
of the modulesage/rings/real_double.pyx
for returning the complex conjugate of a real number. This is consistent withconjugate()
methods inZZ
andRR
. 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 decroatorcoerce_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 ofn
of respective lengthsk_1, k_2
, then there is a binaryk_1 \times k_2
matrixM
such thatp_1
is the vector of row sums andp_2
is the vector of column sums ofM
, if and only ifp_2
dominatesp_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...
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
- #7547
- #7533
- #7364
- #6813
- #7487
- #7564
- #7157
- #6679
- #7571
- #7184
- #7640
- #7294
- #7536
- #7314
- #7673
- #6764
- #7365
- #7291
- #7358
- #7528
- #7541
- #7594
- #7592
- #7593
- #7599
- #7601
- #7605
- #7705
- #6962
- #7721
- #7600
Group Theory
Linear Algebra
Miscellaneous
Numerical
Packages
- #7036
- #7187
- #7272
- #7352
- #6517
- #7464
- #7375
- #7268
- #7287
- #7471
- #7333
- #7164
- #7610
- #7625
- #5686
- #7195
- #7726
- #7757
Statistics
Symbolics
Full Changelog: 4.2.1...4.3
4.2.1
4.2
4.1.2
4.1.1
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 classAbelianGroup_class
insage/groups/abelian_gps/abelian_group.py
. This method returnsTrue
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()
andimag_part()
forCDF
andCC
(Alex Ghitza) #6159 --- The namereal_part
is now an alias to the methodreal()
; similarly,imag_part
is now an alias to the methodimag()
.
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 modulesage/misc/misc_c.pyx
for summing the elements in a list. In some cases,balanced_sum()
is more efficient than the built-in Pythonsum()
function, where the efficiency can range from 26x up to 1410x faster thansum()
. 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 Wigner3j
,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 modulesage/functions/wigner.py
. Here are some examples on calculating the Wigner3j
,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 functionsr_core()
,r_quotient()
,k_core()
, andpartition_sign()
are now deprecated. These are replaced withcore()
,quotient()
, andsign()
respectively. The rewrite of the functionPartition()
deprecated the argumentcore_and_quotient
. The core and the quotient can be passed as keywords ofPartition()
.
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()
andlinear_approximation_matrix()
of the classSBox
in the modulesage/crypto/mq/sbox.py
. The functionlinear_approximation_matrix()
now uses the Walsh transform. The efficiency ofdifference_distribution_matrix()
can be up to 277x, while that forlinear_approximation_matrix()
can be up to 132x. The following timing statistics were ob...