sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.41k stars 475 forks source link

Creation of the sigma function (sum of divisors) applicable to Gaussian integers #29230

Open cee0de30-0e96-45ad-a14f-c59a3ec51191 opened 4 years ago

cee0de30-0e96-45ad-a14f-c59a3ec51191 commented 4 years ago

This is my first contribution ! Please forgive my possible clumsiness !

I would like to propose a new function for Sage called "sigma_gauss". This function would be an extension of the sigma function in number theory, which calculates the sum of the divisors of integers. The sigma_gauss function would apply to a Gaussian integer.

CC: @zimmermann6

Component: number theory

Keywords: gaussian integers, sigma function, first quadrant

Author: garambois

Issue created by migration from https://trac.sagemath.org/ticket/29230

cee0de30-0e96-45ad-a14f-c59a3ec51191 commented 4 years ago

Attachment: sigma_gauss_function.sage.gz

fchapoton commented 4 years ago
comment:1

Zeroth step, read the developer guide : https://doc.sagemath.org/html/en/developer/#writing-code-for-sage

First step, make it work for you in a ".py" file and not a ".sage" file.

You will need to add some "import" lines, that you can find using "import_statements" command in sage. In particular

sage: import_statements(GaussianIntegers,real,imag)
# ** Warning **: several names for that object: real, real_part
# ** Warning **: several names for that object: imag, imag_part, imaginary
from sage.functions.other import real, imag
from sage.rings.number_field.order import GaussianIntegers
cee0de30-0e96-45ad-a14f-c59a3ec51191 commented 4 years ago

Attachment: sigma_gauss_function.py.gz

cee0de30-0e96-45ad-a14f-c59a3ec51191 commented 4 years ago

Description changed:

--- 
+++ 
@@ -9,60 +9,108 @@

 ```python
-#Calculation program sigma(z), z Gaussian integer.
-#Calculates the sum of the complex divisors of z.
-#The Gaussian integer prime factors must be taken in the first quadrant.
-#Observation: equivalent to the Mathematica's function DivisorSigma [1, z, GaussianIntegers -> True]
-#References http://mathworld.wolfram.com/DivisorFunction.html
-#References https://www.jstor.org/stable/2312472?seq=1
-#References https://encompass.eku.edu/etd/158/
+r"""
+sigma_gauss function (sum of divisors) applicable to a Gaussian integer.
+
+This function is an extension of the sigma function in number theory to Gaussian integers.
+
+
+INPUT:
+
+    ''z'' -- GaussianInteger
+
+OUTPUT:
+
+    ''sigma_gauss(z)'' -- GaussianInteger, the sum of the Gaussian integer divisors of z
+
+    Caution: The Gaussian integer prime factors are only taken in the first quadrant,
+    see why in the references below.
+
+EXAMPLES:
+
+The sum of the divisors of Gauss integers z = 2*I + 2, z = 3*I + 2, z = 13::
+
+    sage: sigma_gauss(2*I + 2)
+    5*I
+    sage: sigma_gauss(3*I + 2)
+    3*I + 3
+    sage: sigma_gauss(5)
+    8*I + 4
+
+AUTHORS:
+
+    Paul Zimmermann and Jean-Luc Garambois (2019): initial version
+
+REFERENCES:
+
+    [1] http://mathworld.wolfram.com/DivisorFunction.html
+        Equivalent on the Mathematica software to DivisorSigma [1, z, GaussianIntegers -> True] 
+    [2] https://www.jstor.org/stable/2312472?seq=1
+    [3] https://encompass.eku.edu/etd/158/
+"""
+# ****************************************************************************
+#       Copyright (C) 2019 Jean-Luc Garambois <jlgarambois@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#                  https://www.gnu.org/licenses/
+# ****************************************************************************
+
+from sage.functions.other import real, imag
+from sage.rings.number_field.order import GaussianIntegers

 R = GaussianIntegers()

 def sigma_gauss_aux (l):
-   s = 1
-   e=0
-   while e<len(l):
-      p = l[e][0]
-      k = l[e][1]
-      s = s * (p^(k+1)-1) / (p-1)
-      e+=1
-   return R(s)
+    s = 1
+    e = 0
+    while e < len(l):
+        p = l[e][0]
+        k = l[e][1]
+        s = s * (p**(k+1) - 1) / (p-1)
+        e = e + 1
+    return R(s)

 def sigma_gauss(z):
-   ll=list(R(z).factor())
-   l=[]
-   i=0
+    ll = list(R(z).factor())
+    l = []
+    i = 0

-#Gaussian prime factors must be selected in the first quadrant.
-#To understand why, refer to the references cited at the beginning of the program.
+# ****************************************************************************
+# Gaussian prime factors must be selected in the first quadrant.
+# ****************************************************************************

-   while i<len(ll):
-      nz=ll[i][0]
-      if real(nz)<0 and imag(nz)<0:
-         nz=-nz
-      if real(nz)<0 and imag(nz)>=0:
-         nz=-I*nz
-      if real(nz)>=0 and imag(nz)<0:
-         nz=I*nz
-      assert real(nz)>=0 and imag(nz)>=0
-      lz=[nz,ll[i][1]]
-      l.append(lz)
-      i+=1
-   r=0
+    while i < len(ll):
+        nz = ll[i][0]
+        if real(nz) < 0 and imag(nz) < 0:
+            nz = -nz
+        if real(nz) < 0 and imag(nz) >= 0:
+            nz = -I * nz
+        if real(nz) >= 0 and imag(nz) < 0:
+            nz = I * nz
+        assert real(nz) >= 0 and imag(nz) >= 0
+        lz = [nz, ll[i][1]]
+        l.append(lz)
+        i = i + 1
+    r = 0

-#Be careful not to have the same factor twice in the list of factors after their selection in the first quadrant and before applying the "sigma_gauss_aux" function.
+# ****************************************************************************
+# Be careful not to have the same factor twice after their selection
+# in the first quadrant and before applying the "sigma_gauss_aux" function.
+# ****************************************************************************

-   while r<len(l)-1:
-      t=r+1
-      while t<len(l):
-         if l[r][0]==l[t][0]:
-            l[r][1]=l[r][1]+l[t][1]
-            del l[t]
-            t-=1
-         t+=1
-      r+=1
-   for x,e in l:
-      assert e != 0
-   return sigma_gauss_aux(l)
+    while r < len(l) - 1:
+        t = r + 1
+        while t < len(l):
+            if l[r][0] == l[t][0]:
+                l[r][1] = l[r][1] + l[t][1]
+                del l[t]
+                t = t - 1
+            t = t + 1
+        r= r + 1
+    for x, e in l:
+        assert e != 0
+    return sigma_gauss_aux(l)
cee0de30-0e96-45ad-a14f-c59a3ec51191 commented 4 years ago
comment:2

Attachment: sigma_gauss_function.2.py.gz

Thank you very much chapoton.

I have tried to follow your advice and also the advice given in the link you sent me.

So I modified the Ticket with the new code. And I enclose a modified "sigma_gauss_function.py" file. Sorry, I attached the .py file twice, it's useless, but I couldn't remove the second one.

To switch from sage code to python code, I also had to make some other changes.

mkoeppe commented 4 years ago
comment:3

Batch modifying tickets that will likely not be ready for 9.1, based on a review of the ticket title, branch/review status, and last modification date.

mkoeppe commented 4 years ago

Description changed:

--- 
+++ 
@@ -5,112 +5,4 @@
 This function would be an extension of the sigma function in number theory, which calculates the sum of the divisors of integers.
 The sigma_gauss function would apply to a Gaussian integer.

-Here is the code I propose:

-
-```python
-r"""
-sigma_gauss function (sum of divisors) applicable to a Gaussian integer.
-
-This function is an extension of the sigma function in number theory to Gaussian integers.
-
-
-INPUT:
-
-    ''z'' -- GaussianInteger
-
-OUTPUT:
-
-    ''sigma_gauss(z)'' -- GaussianInteger, the sum of the Gaussian integer divisors of z
-
-    Caution: The Gaussian integer prime factors are only taken in the first quadrant,
-    see why in the references below.
-
-EXAMPLES:
-
-The sum of the divisors of Gauss integers z = 2*I + 2, z = 3*I + 2, z = 13::
-
-    sage: sigma_gauss(2*I + 2)
-    5*I
-    sage: sigma_gauss(3*I + 2)
-    3*I + 3
-    sage: sigma_gauss(5)
-    8*I + 4
-
-AUTHORS:
-
-    Paul Zimmermann and Jean-Luc Garambois (2019): initial version
-
-REFERENCES:
-
-    [1] http://mathworld.wolfram.com/DivisorFunction.html
-        Equivalent on the Mathematica software to DivisorSigma [1, z, GaussianIntegers -> True] 
-    [2] https://www.jstor.org/stable/2312472?seq=1
-    [3] https://encompass.eku.edu/etd/158/
-"""
-# ****************************************************************************
-#       Copyright (C) 2019 Jean-Luc Garambois <jlgarambois@gmail.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#                  https://www.gnu.org/licenses/
-# ****************************************************************************
-
-from sage.functions.other import real, imag
-from sage.rings.number_field.order import GaussianIntegers
-
-R = GaussianIntegers()
-
-def sigma_gauss_aux (l):
-    s = 1
-    e = 0
-    while e < len(l):
-        p = l[e][0]
-        k = l[e][1]
-        s = s * (p**(k+1) - 1) / (p-1)
-        e = e + 1
-    return R(s)
-
-def sigma_gauss(z):
-    ll = list(R(z).factor())
-    l = []
-    i = 0
-
-# ****************************************************************************
-# Gaussian prime factors must be selected in the first quadrant.
-# ****************************************************************************
-
-    while i < len(ll):
-        nz = ll[i][0]
-        if real(nz) < 0 and imag(nz) < 0:
-            nz = -nz
-        if real(nz) < 0 and imag(nz) >= 0:
-            nz = -I * nz
-        if real(nz) >= 0 and imag(nz) < 0:
-            nz = I * nz
-        assert real(nz) >= 0 and imag(nz) >= 0
-        lz = [nz, ll[i][1]]
-        l.append(lz)
-        i = i + 1
-    r = 0
-
-# ****************************************************************************
-# Be careful not to have the same factor twice after their selection
-# in the first quadrant and before applying the "sigma_gauss_aux" function.
-# ****************************************************************************
-
-    while r < len(l) - 1:
-        t = r + 1
-        while t < len(l):
-            if l[r][0] == l[t][0]:
-                l[r][1] = l[r][1] + l[t][1]
-                del l[t]
-                t = t - 1
-            t = t + 1
-        r= r + 1
-    for x, e in l:
-        assert e != 0
-    return sigma_gauss_aux(l)
-```
mkoeppe commented 3 years ago
comment:6

Setting new milestone based on a cursory review of ticket status, priority, and last modification date.