GitLab's annual major release is around the corner. Along with a lot of new and exciting features, there will be a few breaking changes. Learn more here.

  1. 09 May, 2021 2 commits
  2. 07 May, 2021 5 commits
  3. 06 May, 2021 2 commits
  4. 30 Apr, 2021 1 commit
  5. 26 Apr, 2021 4 commits
    • Release Manager's avatar
      Trac #31640: 2d Bezier path does not plot in 3d · b570ac37
      Release Manager authored
      From https://ask.sagemath.org/question/56590/problem-with-plotting-a-3d-
      bezier-curve/
      {{{
      sage: p2d = [[(3.0,0.0),(3.0,0.13),(2.94,0.25),(2.8,0.35)],
      [(2.7,0.44),(2.6,0.5),(2.5,0.5)], [(2.36,0.5),(2.24,0.44),(2.14,0.35)],
      [(2.05,0.25),(2.0,0.13),(2.0,6.1e-17)]]
      sage: bp=bezier_path(p2d)
      sage: bp.plot3d()
      Traceback (most recent call last):
      /opt/sage/local/lib/python3.9/site-packages/sage/symbolic/expression.pyx
      in sage.symbolic.expression.Expression._integer_
      (build/cythonized/sage/symbolic/expression.cpp:8801)()
         1298         try:
      -> 1299             n = self.pyobject()
         1300         except TypeError:
      
      /opt/sage/local/lib/python3.9/site-packages/sage/symbolic/expression.pyx
      in sage.symbolic.expression.Expression.pyobject
      (build/cythonized/sage/symbolic/expression.cpp:6136)()
          586         if not is_a_numeric(self._gobj):
      --> 587             raise TypeError("self must be a numeric expression")
          588         return py_object_from_numeric(self._gobj)
      
      TypeError: self must be a numeric expression
      
      During handling of the above exception, another exception occurred:
      
      TypeError                                 Traceback (most recent call
      last)
      <ipython-input-6-37e325e9051f> in <module>
      ----> 1 bp.plot3d()
      
      /opt/sage/local/lib/python3.9/site-packages/sage/plot/graphics.py in
      plot3d(self, z, **kwds)
         1279         """
         1280         from sage.plot.plot3d.base import Graphics3dGroup
      -> 1281         g = Graphics3dGroup([g.plot3d(**kwds) for g in
      self._objects])
         1282         if z:
         1283             g = g.translate(0,0,z)
      
      /opt/sage/local/lib/python3.9/site-packages/sage/plot/graphics.py in
      <listcomp>(.0)
         1279         """
         1280         from sage.plot.plot3d.base import Graphics3dGroup
      -> 1281         g = Graphics3dGroup([g.plot3d(**kwds) for g in
      self._objects])
         1282         if z:
         1283             g = g.translate(0,0,z)
      
      /opt/sage/local/lib/python3.9/site-packages/sage/plot/bezier_path.py in
      plot3d(self, z, **kwds)
          168         options = self._plot3d_options()
          169         options.update(kwds)
      --> 170         return bezier3d([[(x,y,0) for x,y in self.path[i]] for i
      in range(len(self.path))], **options)
          171
          172     def _repr_(self):
      
      /opt/sage/local/lib/python3.9/site-packages/sage/misc/decorators.py in
      wrapper(*args, **kwds)
          649                     kwds[new_name] = kwds[old_name]
          650                     del kwds[old_name]
      --> 651             return func(*args, **kwds)
          652
          653         return wrapper
      
      /opt/sage/local/lib/python3.9/site-packages/sage/misc/decorators.py in
      wrapper(*args, **kwds)
          489                 options['__original_opts'] = kwds
          490             options.update(kwds)
      --> 491             return func(*args, **options)
          492
          493         #Add the options specified by @Options to the signature
      of the wrapped
      
      /opt/sage/local/lib/python3.9/site-packages/sage/plot/plot3d/shapes2.py
      in bezier3d(path, **options)
          244             p2 = vector(curve[-2])
          245             p3 = vector(curve[-1])
      --> 246             B =
      (1-t)**3*p0+3*t*(1-t)**2*p1+3*t**2*(1-t)*p2+t**3*p3
          247             G += P3D.parametric_plot3d(list(B), (0, 1),
      color=options['color'], aspect_ratio=options['aspect_ratio'],
      thickness=options['thickness'], opacity=options['opacity'])
          248         else:
      
      /opt/sage/local/lib/python3.9/site-packages/sage/symbolic/expression.pyx
      in sage.symbolic.expression.Expression.__index__
      (build/cythonized/sage/symbolic/expression.cpp:34734)()
         5985             [0, 1, 2, 3, 4]
         5986         """
      -> 5987         return int(self._integer_())
         5988
         5989     def iterator(self):
      
      /opt/sage/local/lib/python3.9/site-packages/sage/symbolic/expression.pyx
      in sage.symbolic.expression.Expression._integer_
      (build/cythonized/sage/symbolic/expression.cpp:8850)()
         1299             n = self.pyobject()
         1300         except TypeError:
      -> 1301             raise TypeError("unable to convert %r to an integer"
      % self)
         1302         if isinstance(n, sage.rings.integer.Integer):
         1303             return n
      
      TypeError: unable to convert -(t - 1)^3 to an integer
      }}}
      
      URL: https://trac.sagemath.org/31640
      Reported by: vdelecroix
      Ticket author(s): Vincent Delecroix
      Reviewer(s): Frédéric Chapoton
      b570ac37
    • Release Manager's avatar
      Trac #31646: clean BezierPath constructor · bc548368
      Release Manager authored
      From http://ask.sagemath.org/question/56608/possible-problem-in-
      bezier_pathpy/
      
      URL: https://trac.sagemath.org/31646
      Reported by: vdelecroix
      Ticket author(s): Vincent Delecroix
      Reviewer(s): Travis Scrimshaw
      bc548368
    • Release Manager's avatar
      Trac #30518: eigenvectors over QQbar are incorrectly conjugated · bd3334c7
      Release Manager authored
      Eigenvectors over QQbar could get incorrectly conjugated. In the
      following example from [https://groups.google.com/g/sage-
      devel/c/9Ss98-XKR9c devel], the eigenvectors of a matrix over
      `QuadraticField(-1)` are computed in two ways, one of which incorrectly
      returns the conjugate of some eigenvectors.
      
      By converting the matrix to `QQbar` first:
      {{{
      sage: K.<i> = QuadraticField(-1)
      sage: m = matrix(K, 4, [2,4*i,-i,0, -4*i,2,-1,0, 2*i,-2,0,0, 4*i+4,
      4*i-4,1-i,-2])
      sage: sorted([(e, matrix.column(vs)) for e, vs, _ in
      m.change_ring(QQbar).eigenvectors_right()])
      [(
          [  1   0]
          [1*I   0]
          [  0   0]
      -2, [  0   1]
      ),
       (
                            [           1.000000000000000? + 0.?e-16*I]
                            [           0.?e-16 - 1.000000000000000?*I]
                            [           0.?e-16 - 6.605551275463989?*I]
      -0.6055512754639893?, [1.000000000000000? + 1.000000000000000?*I]
      ),
       (
                          [           1.000000000000000? + 0.?e-17*I]
                          [           0.?e-17 - 1.000000000000000?*I]
                          [          0.?e-17 + 0.6055512754639893?*I]
      6.605551275463989?, [1.000000000000000? + 1.000000000000000?*I]
      )]
      }}}
      
      Supposedly, this result is correct. In contrast, computing the
      eigenvectors directly, without first converting to `QQbar`, leads to
      some eigenvectors getting conjugated:
      
      {{{
      sage: sorted([(QQbar(e), matrix.column(QQbar, vs)) for e, vs, _ in
      m.eigenvectors_right()])
      [(
          [1 0]
          [I 0]
          [0 0]
      -2, [0 1]
      ),
       (
                            [                                        1]
                            [           0.?e-54 + 1.000000000000000?*I]
                            [           0.?e-53 + 6.605551275463989?*I]
      -0.6055512754639893?, [1.000000000000000? - 1.000000000000000?*I]
      ),
       (
                          [                                        1]
                          [           0.?e-53 + 1.000000000000000?*I]
                          [          0.?e-52 - 0.6055512754639893?*I]
      6.605551275463989?, [1.000000000000000? - 1.000000000000000?*I]
      )]
      }}}
      
      Note that the `QuadraticField` constructor automatically sets an
      embedding.
      {{{
      sage: K.coerce_embedding()
      Generic morphism:
        From: Number Field in i with defining polynomial x^2 + 1 with i = 1*I
        To:   Complex Lazy Field
        Defn: i -> 1*I
      }}}
      
      URL: https://trac.sagemath.org/30518
      Reported by: gh-mwageringel
      Ticket author(s): Vincent Delecroix
      Reviewer(s): Marc Mezzarobba
      bd3334c7
    • Release Manager's avatar
      Trac #31628: fix/improve conversions to QQbar and AA · de9c3d51
      Release Manager authored
      * fix conversion from ℚ[i] to `QQbar` (honor complex embeddings)
      * add implicit coercions from python ints and from number fields with
      compatible embeddings
      
      URL: https://trac.sagemath.org/31628
      Reported by: mmezzarobba
      Ticket author(s): Marc Mezzarobba, Vincent Delecroix
      Reviewer(s): Vincent Delecroix, Marc Mezzarobba
      de9c3d51
  6. 25 Apr, 2021 10 commits
    • Vincent Delecroix's avatar
      #31628: two doctests · ed195584
      Vincent Delecroix authored
      ed195584
    • Release Manager's avatar
      Trac #31641: Remove outdated MacPorts/fink ban · 96c2708f
      Release Manager authored
      (split out from #31505)
      
      URL: https://trac.sagemath.org/31641
      Reported by: mkoeppe
      Ticket author(s): Matthias Koeppe
      Reviewer(s): Dima Pasechnik
      96c2708f
    • Release Manager's avatar
      Trac #31625: Memory leak for IntegralLattice · 64b0382b
      Release Manager authored
      Computing the discriminant group of an integral lattice causes
      both to persist in memory.
      {{{
      sage: L = IntegralLattice("A2")
      sage: for k in range(1,500):
      ....:     G = L.twist(k)
      sage: gc.collect()
      sage: len([a for a in gc.get_objects() if type(a)==type(L)])
      1058
      3
      sage: L = IntegralLattice("A2")
      sage: for k in range(1,500):
      ....:     G = L.twist(k)
      ....:     D = G.discriminant_group()
      sage: gc.collect()
      sage: len([a for a in gc.get_objects() if type(a)==type(L)])
      1284
      501
      }}}
      Creating thousands of lattices and computing their discriminant groups
      is actually a common use case. Serious computations are impossible with
      this kind of memory leak.
      
      URL: https://trac.sagemath.org/31625
      Reported by: sbrandhorst
      Ticket author(s): Simon Brandhorst
      Reviewer(s): Travis Scrimshaw
      64b0382b
    • Release Manager's avatar
      Trac #31620: Document installing sagemath kernel without copying documentation · 068797f2
      Release Manager authored
      Follow up to #30476: Using `jupyter kernelspec` to install `sagemath`
      kernel results in copying about 2Gb of documentation into the jupyter
      kernels share directory. That's generally not the spot to put large
      files/documentation. Document how to avoid this.
      
      URL: https://trac.sagemath.org/31620
      Reported by: nbruin
      Ticket author(s): Nils Bruin
      Reviewer(s): Matthias Koeppe
      068797f2
    • Release Manager's avatar
      Trac #31612: Update setuptools_scm to 6.0.1 · d4650fc3
      Release Manager authored
      Prompted by a problem report using WSL at https://groups.google.com/g
      /sage-devel/c/1SQf-k15J4Y/m/3EnxbDdWAAAJ
      
      https://pypi.org/project/setuptools-scm/#history
      
      The new version has `python_requires = >=3.6`, so it is OK for Sage 9.3
      
      To try this ticket: `make configure && ./configure --enable-download-
      from-upstream-url && make build`
      
      URL: https://trac.sagemath.org/31612
      Reported by: mkoeppe
      Ticket author(s): Matthias Koeppe
      Reviewer(s): Dima Pasechnik
      d4650fc3
    • Release Manager's avatar
      Trac #31600: threejs does not handle transparency correctly · 69db9b24
      Release Manager authored
      Here is an example to reproduce it yourself:
      
      {{{
      theta,z=var('theta,z')
      cb = cylindrical_plot3d(2,(theta,0,2*pi),(z,-5,5), alpha=0.3,
      color='blue')
      cr = cylindrical_plot3d(1,(theta,0,2*pi),(z,-7,7), alpha=0.3,
      color='red')
      cv = cylindrical_plot3d(0.5,(theta,0,2*pi),(z,-10,10), alpha=0.5,
      color='green')
      p = cb + cr + cv
      }}}
      
      Compare
      
      {{{
      p.show(aspect_ratio=1)
      }}}
      
      with
      
      {{{
      p.show(viewer='jmol', aspect_ratio=1)
      }}}
      
      As you can see, with `threejs`, when you rotate the picture, on some
      angles, the transparency is correct, but sometimes there is no
      transparency at all, and sometimes there is a wrong transparency, see
      the attached pictures.
      
      [[Image( threejs.good.transparency.png)]]
      [[Image( threejs.no.transparency.png)]]
      [[Image( threejs.wrong.transparency.png)]]
      
      URL: https://trac.sagemath.org/31600
      Reported by: tmonteil
      Ticket author(s): Joshua Campbell
      Reviewer(s): Matthias Koeppe
      69db9b24
    • Release Manager's avatar
      Trac #31541: GH Actions: Update 32-bit platforms · 54821113
      Release Manager authored
      (from #31538)
      
      `ubuntu-focal-i386-standard` consistently fails - lots of missing
      packages (https://github.com/mkoeppe/sage/runs/2170889217).
      "Upgrades on i386: Users of the i386 architecture will not be presented
      with an upgrade to Ubuntu 20.04 LTS. Support for i386 as a host
      architecture was dropped in 19.10."
      (https://wiki.ubuntu.com/FocalFossa/ReleaseNotes)
      
      We replace it by [[https://github.com/pypa/manylinux|manylinux_2_24]]
      (which is based on `debian-stretch`).
      
      URL: https://trac.sagemath.org/31541
      Reported by: mkoeppe
      Ticket author(s): Matthias Koeppe
      Reviewer(s): Dima Pasechnik
      54821113
    • Release Manager's avatar
      Trac #29372: At the end of configure, show installation hints for non-enabled... · 0e8c26ba
      Release Manager authored
      Trac #29372: At the end of configure, show installation hints for non-enabled optional packages separately
      
      When running the configure script, `--enable-foo` and `--disable-foo`
      should be used to control the installation of optional packages.
      
      '''Original wishlist item:'''
      
      With respect to the system-package support, this means that
      `./configure` should not try to find any optional packages that I don't
      want, and it shouldn't tell me to install them. For example,
      
      {{{
      $ ./configure
      ...
      Checking whether SageMath should install SPKG gp2c...
      checking installing pari? ... no
      checking for gp2c... no
      configure: using pari/gp from the system, but building gp2c
      configure: one might prefer to install a system-wide gp2c, instead
      configure: and re-run configure.
      configure: gp prefix is /usr
      configure: pari.cfg is /usr/share/pari/pari.cfg
      configure: no suitable system package found for SPKG gp2c
      using Sage's gp2c SPKG
      ...
      gp2c-0.0.10.p0:                              no suitable system package;
      optional, use "./configure --enable-gp2c" to install
      ...
      configure: Hint: The following SPKGs did not find equivalent system
      packages:
      configure:   cbc gp2c libsemigroups
      checking for the package system in use... gentoo
      configure: Hint: Installing the following system packages is recommended
      and may avoid building some of the above SPKGs from source:
      configure:   $ # install the following packages: sci-mathematics/gp2c
      }}}
      
      I guess this is partly due to the default of `if_installed` for
      `--enable-foo` (which I think is a bad default, but that's another
      matter), but the same thing happens if I explicitly pass `--disable-
      gp2c`.
      
      '''In this ticket, as a milder change,''' we show the list of system
      packages corresponding to non-enabled optional packages separately.
      
      To test this branch, remember to use `./bootstrap` before `./configure`.
      
      Critical for Sage 9.3 because there is evidence that users get concerned
      when too many packages are suggested to be installed.
      
      Related:
      
      - #29498: Do not check for system packages of disabled optional packages
      
      URL: https://trac.sagemath.org/29372
      Reported by: mjo
      Ticket author(s): Matthias Koeppe
      Reviewer(s): Samuel Lelièvre
      0e8c26ba
    • Release Manager's avatar
      Trac #31673: MR53: Unbreak sagelib's setup.py install · a0672c62
      Release Manager authored
      Mauricio Collares ([https://gitlab.com/sagemath/dev/tracmirror/collares
      @collares]) opened a merge request at
      sagemath/sage!53:
      ----
      {{{
      #!markdown
      The pattern of importing setuptools before distutils was already used in
      other files, but not in sagelib's setup.py. This caused errors of the
      form "AttributeError: 'Extension' object has no attribute '_needs_stub'"
      on my machine.
      
      I understand this install method is deprecated, but I believe this patch
      has essentially zero cost and can safely be added to Sage 9.3.
      }}}
      [[BR]][[BR]][[BR]]
      
      URL: https://trac.sagemath.org/31673
      Reported by: galois
      Ticket author(s): Mauricio Collares
      Reviewer(s): Matthias Koeppe
      a0672c62
    • Release Manager's avatar
      Trac #31645: incorrect handling of constant term when creating power series · 80c22588
      Release Manager authored
      As reported by user TBK in [https://groups.google.com/g/sage-
      devel/c/av4L3qQZl0o/m/d-UDze62AQAJ this sage devel thread], the `series`
      method sometimes returns an incorrect power series in which a constant
      term has erroneously been multiplied by a power of x:
      {{{
          sage: ((1-sqrt(1-x))/x + 0).series(x,3)
          1/2 + 1/8*x + 1/16*x^2 + Order(x^3)  # correct
          sage: ((1-sqrt(1-x))/x + 123).series(x,3)
          123*x^(-1) + 1/2 + 1/8*x + 1/16*x^2 + Order(x^3)  # wrong !!!
      }}}
      
      URL: https://trac.sagemath.org/31645
      Reported by: gh-DaveWitteMorris
      Ticket author(s): Dave Morris
      Reviewer(s): Travis Scrimshaw
      80c22588
  7. 24 Apr, 2021 2 commits
    • Release Manager's avatar
      Trac #31555: Update freetype to 2.10.4 - fixes a vulnerability · 889f3f9e
      Release Manager authored
      https://www.freetype.org/
      
      URL: https://trac.sagemath.org/31555
      Reported by: mkoeppe
      Ticket author(s): Matthias Koeppe
      Reviewer(s): Dima Pasechnik
      889f3f9e
    • Release Manager's avatar
      Trac #25034: Special case for gen_legendre_P with n == m gives incorrect results for x in (-1,1) · 6d8b561f
      Release Manager authored
      The current implementation of `gen_legendre_P` is not accurate. No
      distinction between Ferrers functions and Legendre functions has been
      made and some special cases are not correctly implemented. This heavily
      affects spherical harmonics. For a quick fix, to make spherical
      harmonics work, I propose to temporarily restrict `gen_legendre_P` to
      Ferrers functions. In a follow-up #31637, we will make the distinction
      complete.
      
      ----
      
      **Old Description**
      
      I am using the `gen_legendre_P` function (an instance of
      `Func_assoc_legendre_P`
      from `sage/functions/orthogonal_polys.py`) to evaluate associated
      Legendre
      functions / Ferrers functions in !SageMath 8.1.
      
      There appears to be a discrepancy in the results I obtain, depending on
      whether
      I use `gen_legendre_P.eval_poly()` or directly call `gen_legendre_P()`
      in some cases.
      I think this is because the `_eval_` method first tries to call the
      `_eval_special_values_`
      method, before using `eval_poly`.
      
      With this input
      {{{
      x = SR.var('x')
      print(gen_legendre_P.eval_poly(1, 1, x))
      print(gen_legendre_P(1, 1, x))
      print(gen_legendre_P.eval_poly(1, 1, 0.5))
      print(gen_legendre_P(1, 1, 0.5))
      }}}
      
      I obtain
      {{{
      -sqrt(-x^2 + 1)
      sqrt(x^2 - 1)
      -0.866025403784439
      5.30287619362453e-17 + 0.866025403784439*I
      }}}
      
      The result from eval_poly agrees with Mathematica, i.e.
      {{{
      LegendreP[1, 1, 0.5]
      -0.866025
      }}}
      
      Based on the above output, it seems to me that
      `gen_legendre_P.eval_poly(1, 1, cos(theta))` will always be real while
      `gen_legendre_P(1, 1, cos(theta))` will be complex (unless |cos(theta)|
      = 1), since cos(theta) is in the interval [-1,1].
      
      Looking at the code for `Func_assoc_legendre_P._eval_special_values_`, I
      suspect the culprit is the `n == m` case, which returns
      {{{
      factorial(2*m)/2**m/factorial(m) * (x**2-1)**(m/2)
      }}}
      
      This discrepancy also seems to be present in `spherical_harmonic` when
      `n == m` (an instance of `SphericalHarmonic` from
      `sage/functions/special.py`),
      which is built using `gen_legendre_P`.
      
      After [[https://groups.google.com/d/msg/sage-
      devel/IDtiGF6HB28/ErLsqI1eBAAJ|discussion]]
      in the sage-devel mailing list it appears that this is because the `n ==
      m`
      case in `_eval_special_values_` is based on
      https://dlmf.nist.gov/14.7#E15,
      but this is not defined in (-infinity,1].
      
      For the spherical harmonics, where the argument x = cos(theta),
      x will always be in the range [-1, 1 ], where special case used
      in `_eval_special_values_` is not defined.
      
      On the sage-devel mailing list, Howard Cohl suggested that
      the correct formula for x in [-1, 1] is
      {{{
      P_m^m(x)=(-1)^m (2m)!/(2^m m!) (1-x^2)^(m/2)
      }}}
      
      See: https://groups.google.com/d/msg/sage-devel/IDtiGF6HB28/QWwnAeLJBAAJ
      
      According to Howard Cohl this is formally a Ferrers function
      (defined on (-1,1) ), rather than an associated Legendre polynomial.
      However, the existing code for Func_assoc_legendre_P does not
      seem to make any distinction between Ferrers and associated
      Legendre functions.
      
      My proposed fix would be to have
      `Func_assoc_legendre_P._eval_special_values_` choose between two `n ==
      m` special cases, based on whether `-1 <= x <= 1` (above expression) or
      `> 1` (current expression).
      
      This raises the question of whether `Func_assoc_legendre_P` is correctly
      defined, as at present it would seem to cover both Ferrers functions and
      associated Legendre functions.
      
      In my experience with the physics/chemistry literature, the spherical
      harmonics are universally defined in terms of "associated Legendre
      functions", even though the argument is x = cos(theta). DLMF suggests
      these are defined in terms of Ferrers functions of the first kind
      (https://dlmf.nist.gov/14.30.E1). Wolfram Mathematica does not seem to
      distinguish. Possibly it is worth flagging in the docstring for
      `Func_assoc_legendre_P` that the class seems to cover both functions.
      
      URL: https://trac.sagemath.org/25034
      Reported by: jcwomack
      Ticket author(s): Michael Jung
      Reviewer(s): Eric Gourgoulhon, Travis Scrimshaw
      6d8b561f
  8. 21 Apr, 2021 1 commit
  9. 20 Apr, 2021 2 commits
  10. 19 Apr, 2021 4 commits
  11. 18 Apr, 2021 3 commits
  12. 17 Apr, 2021 4 commits