# Kanter’s Zeta Function – Part 2: an exploration with Python

Continuing from Part 1.

(note to the reader: this was posted without being proofread. I will proofread/check my work later because I am too tired right now. I might have also forgotten to include a few points)

Who want’s to do some math?

Let’s pick up right where we left off. I’m not going to go over anything from Part 1, because honestly, for the sake of digestibility, this should not have even been broken up into 2 parts, and I will probably just repost it as a single, combined post later anyway.

Ok. We have our gamma, psi, and zeta functions from part 1. We’re going to want to graph some of that data with python, but in order to do that, we ought to modify a lot of that code from Part 1 in order to make the whole process go faster/smoother. First, we’ll want to quickly generate a file with all of the gamma values which we can reference to quickly get the psi values (this way we can cut out many steps of recursion).

```def gfilemaker(n):
glist = 
gglist = str(glist)
gfile = open('gammafile.txt','w')
gfile.write(gglist)
d = len(glist)
if s < d:
return glist[s][k-1]
elif k==1:
return 1
elif k==s:
return 1
else:
y = 0
for x in range(1,min(s-k+1,k+1)):
return y
for a in range(1,n+1):
alist = []
for k in range(1,a+1):
glist.append(alist)
aglist = str(alist)
gfile.write('\n')
gfile.write(aglist)
gfile.close()
return glist

gammalist = gfilemaker(100)```

notice that the function gammaloader is basically our gamma function from part one, but modified to cut down on the amount of recursion we have to go through.

Now let’s make a similar function to quickly generate a file containing all of our zeta values. I won’t bother making a file with the psi values, because the psi values will be so easy to get (since psi(n) is just the sum of the list in the n+1-th row of gammafile.txt).

```def zetalister(n):
gammafile = open('gammafile.txt','r')
def gline(a):
gline=lines[a].replace('[','').replace(']','').replace(',','')
gline = gline.split()
for x in range(len(gline)):
gline[x]=int(gline[x])
return gline
def quickpsi(num):
guesses=primegenerator(num**0.5)
def quickprimer(trial):
primedict = {}
def factor(p, s):
if not(p in primedict):
primedict[p]=1
else:
primedict[p]+=1
for p in guesses:
while trial % p == 0:
factor(p, trial)
trial = int(trial/p)
if trial == 1:
return primedict
if trial != 1:
primedict[trial] = 1
return primedict
psifactlist=
for z in range(1,num+1):
b=1
for a in quickprimer(z):
c = sum(gline(quickprimer(z)[a])) # here is psi
b*=c # here is our zeta function
psifactlist.append(b)
return psifactlist
zetafile = open('zetafile.txt','w')
zetalist = quickpsi(n)
zetatext = str(zetalist)
gammafile.close()
zetafile.write(zetatext)
zetafile.close()
return zetalist

zetalist = zetalister(1000000)```

notice that quickpsi calls the primegenerator function from part 1. notice that quickprimer is essentially our primefactorizer function from part 1.  notice that our psi function is basically just expressed as c = sum(gline(quickprimer(z)[a])), and that our zeta function shows up in the line just below our psi function, ie, b*=c.

Now we have a file with the first million zeta values. I plotted out the data in multiple ways using matplotlib. I will spare you the details, since it was probably fairly routine, and not unique to this particular study. (If you really want, dear reader, I’m willing to share the code, I just assume you’d rather figure it out on your own). Take a look at the results below: zeta(x) for x up to one million (x-axis is linear scale)

Um. yeah. let’s look at that with a logarithmic x-axis. zeta(x) for x up to one million (x-axis is logarithmic scale)

okay, so zeta(x) is kind of weird to look at. We see a much thicker blue closer to the bottom, because that’s where the majority of data points are. I think the logarithmic scale on the x-axis makes it a bit easier to take in the data. Okay, now let’s take a look at the arithmetic means of the partial sums of zeta(x), which we call sigma(x), that is:

```def sigma(x):
b=0
for a in range(1,x+1):
b+=zeta(a)
return b/float(x)```

I didn’t actually write the code like this. I used the zetafile.txt which I generated. I just wanted it to be easier for you to read.

REMEMBER: Our main goal is to determine whether or not sigma(x) is Cesàro Summable. In other words, we want to know whether or not sigma(x) approaches some finite number y as x approaches infinity. Alright, let’s take a look at sigma(x) plotted out with linear x-axis and logarithmic x-axis.

Take a look at the graph with logarithmic x-axis. Notice how the data points seem to show up in clusters. Now count the number of data points in each of the first few clusters. 4, 8, 16…notice the pattern? Isn’t it obvious why we see clusters in increasing powers of 2? It’s because zeta(2n) is going to be substantially higher than zeta(x) for any x less than 2n. At least, this is the case for all x up to one million. This is because 2 is the smallest prime, so 2n will be the smallest number to “experience” psi(n). Consequentially, zeta(2n) pushes sigma higher than the other numbers around it do.

Here’s another observation: when we graph sigma with the logarithmic x-axis, the graph resembles something that looks “less than” a linear curve on a graph with a linear x-axis. This would lead us to believe that sigma is possibly “less than” logarithmic. Maybe it is. That doesn’t really help us much though, because even a logarithmic function is unbounded, so sigma still might not have a limit. The problem only becomes more pronounced when we chop the first 999 data points off the graph and zoom in accordingly:

Is it just me or is it starting to look almost linear toward the right end of that graph? Crap. No doubt this is a slow-moving function, but it looks like it’s getting harder to prove convergence (if it indeed converges). There’s another issue too. I plotted out the psi(x) for x up to 100. Take a look: