Skip to content

Commit

Permalink
mlp
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterLuschny committed Nov 30, 2023
1 parent 4861711 commit d88869e
Show file tree
Hide file tree
Showing 11 changed files with 428 additions and 118 deletions.
29 changes: 26 additions & 3 deletions src/Eulerian.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,44 @@
[6] 1, 57, 302, 302, 57, 1, 0,
[7] 1, 120, 1191, 2416, 1191, 120, 1, 0,
[8] 1, 247, 4293, 15619, 15619, 4293, 247, 1, 0
=======================================================
0: 1
1: 0 1
2: 0 1 1
3: 0 1 4 1
4: 0 1 11 11 1
5: 0 1 26 66 26 1
6: 0 1 57 302 302 57 1
7: 0 1 120 1191 2416 1191 120 1
8: 0 1 247 4293 15619 15619 4293 247 1
"""


@cache
def eulerian(n: int) -> list[int]:
def KnuthEulerian(n: int) -> list[int]:
if n == 0:
return [1]

row = eulerian(n - 1) + [0]
row = KnuthEulerian(n - 1) + [0]
for k in range(n, 0, -1):
row[k] = (n - k) * row[k - 1] + (k + 1) * row[k]
return row


@MakeTriangle(eulerian, "Eulerian", ["A173018", "A008292", "A123125"], False)
@cache
def eulerian(n: int) -> list[int]:
if n == 0:
return [1]
if n == 1:
return [0, 1]

row = eulerian(n - 1) + [1]
for k in range(n - 1, 0, -1):
row[k] = (n - k + 1) * row[k - 1] + k * row[k]
return row


@MakeTriangle(eulerian, "Eulerian", ["A123125", "A173018", "A008292"], True)
def Eulerian(n: int, k: int) -> int:
return eulerian(n)[k]

Expand Down
10 changes: 5 additions & 5 deletions src/NumBernoulli.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
from Genocchi import genocchi
from fractions import Fraction as frac
from fractions import Fraction

"""Bernoulli numbers A164555/A027642
"""

# #@


def Bernoulli(n: int) -> frac:
def Bernoulli(n: int) -> Fraction:
if n < 2:
return frac(1, n + 1)
return Fraction(1, n + 1)
if n % 2 == 1:
return frac(0, 1)
return Fraction(0, 1)
g = genocchi(n // 2 - 1)[-1]
f = frac(g, 2 ** (n + 1) - 2)
f = Fraction(g, 2 ** (n + 1) - 2)
return -f if n % 4 == 0 else f


Expand Down
62 changes: 29 additions & 33 deletions src/_tabldata.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
Needed for anti-diagonal traits of the triangle.
'''
DIAGSIZE = MINROWS + MINROWS // 2
'''
Maximal length of the string representing the sequence.
'''
MAXSTRLEN = 100

def GetMaxStrLen() -> int:
return MAXSTRLEN


def fnv(data: bytes) -> int:
Expand Down Expand Up @@ -102,7 +109,7 @@ def isInOEIS(seq: list[int]) -> bool:
Raises:
Exception: If the OEIS server cannot be reached after multiple attempts.
"""
strseq = SeqString(seq, 140, 24, 3)
strseq = SeqString(seq, 140, 24, ",", 3)
url = f"https://oeis.org/search?q={strseq}&fmt=json"

for _ in range(3):
Expand Down Expand Up @@ -133,7 +140,7 @@ def IsInOEIS(seq: list[int]) -> str:
Raises:
Exception: If the OEIS server cannot be reached after multiple attempts.
"""
strseq = SeqString(seq, 140, 24, 3)
strseq = SeqString(seq, 140, 24, ",", 3)
url = f"https://oeis.org/search?q={strseq}&fmt=json"

for _ in range(3):
Expand Down Expand Up @@ -218,7 +225,6 @@ def GetNames() -> None:
oeisnames = "https://oeis.org/names.gz"
r = requests.get(oeisnames, stream=True, timeout=10)
r.raise_for_status()
csvpath = GetDataPath("oeisnames", "csv")

# Save the names file
with open(oeisnamespath, "wb") as local:
Expand All @@ -227,6 +233,7 @@ def GetNames() -> None:
local.write(chunk)

# Extract the CSV file from the names file
csvpath = GetDataPath("oeisnames", "csv")
with gzip.open(oeisnamespath, "rb") as gz:
with open(csvpath, "wb") as da:
da.write(gz.read())
Expand Down Expand Up @@ -411,15 +418,15 @@ def DebugQueryOeis(H: str, seq: list[int], db_cur: sqlite3.Cursor) -> str:
return bnum


def GetType(name: str) -> str:
def GetType(name: str) -> list[str]:
"""
There are 7 types:
["", "Std", "Rev", "Inv", "Rev:Inv", "Inv:Rev", "Alt"]
"""
sp = name.split(":", 1)
if len(sp) == 1:
return ""
return name.split(":", 1)[1]
return ["", ""]
return name.split(":", 1)


def CreateTable(name: str) -> str:
Expand All @@ -430,21 +437,22 @@ def InsertTable(name: str) -> str:
return f"INSERT INTO {name} VALUES(?, ?, ?, ?, ?, ?)"


def FilterTraits(anum: str) -> bool:
def FilterTraits(anum: str, anumsonly: bool=False) -> bool:
"""
Filter traits to remove traits that are not interresting.
Args:
anumber (str): The traits as A-number.
anumsonly (bool, optional): Disregard missing anums. Defaults to False.
Returns:
True if the trait should be discarded.
"""
return anum in ["A000012", "A000007", "A000004"]

lame = ["A000012", "A000007", "A000004"]
if anumsonly:
lame.append("missing")

def GetMaxStrLen() -> int:
return 100
return anum in lame


def SaveTraits(fun: tgen, size: int, traits_cur: sqlite3.Cursor, oeis_cur: sqlite3.Cursor, table: str, TRAITS: dict) -> None:
Expand Down Expand Up @@ -474,7 +482,9 @@ def SaveTraits(fun: tgen, size: int, traits_cur: sqlite3.Cursor, oeis_cur: sqlit

r = fun.gen
triname = fun.id
trityp = GetType(triname)
funname, trityp = GetType(triname)
print(funname)
print(trityp)

for traitname, trait in TRAITS.items():
if trityp == traitname:
Expand All @@ -499,16 +509,9 @@ def SaveTraits(fun: tgen, size: int, traits_cur: sqlite3.Cursor, oeis_cur: sqlit
if FilterTraits(anum): # discard traits that are not interresting
continue

seqstr = ""
maxl = 0
for trm in seq:
s = str(trm) + " "
maxl += len(s)
if maxl > GetMaxStrLen():
break
seqstr += s
seqstr = SeqString(seq, MAXSTRLEN, 99)

tup = (triname, trityp, traitname, anum, fnvhash, seqstr)
tup = (funname, trityp, traitname, anum, fnvhash, seqstr)
sql = InsertTable(table)
traits_cur.execute(sql, tup)

Expand Down Expand Up @@ -642,7 +645,6 @@ def ConvertLocalDBtoCSVandMD() -> None:
def ConvertDBtoCSVandMD(dbpath: Path, funname: str) -> int:
"""
Converts a SQLite database to CSV and Markdown files.
We exclude cases 'A000012', 'A000007', and 'A000004', which are trivial.
Args:
dbpath (str): The path to the SQLite database.
Expand All @@ -662,11 +664,7 @@ def ConvertDBtoCSVandMD(dbpath: Path, funname: str) -> int:
tables = cursor.fetchall()
for table_name in tables:
table_name = table_name[0]
sql = f"""SELECT triangle, trait, anum, seq
FROM {table_name}
WHERE anum != 'A000012'
AND anum != 'A000007'
AND anum != 'A000004' """
sql = f"SELECT triangle, type, trait, anum, seq FROM {table_name}"
table = pd.read_sql_query(sql, db)
csv_path = GetDataPath(table_name, "csv")
md_path = GetDataPath(table_name, "md")
Expand All @@ -681,7 +679,7 @@ def ConvertDBtoCSVandMD(dbpath: Path, funname: str) -> int:

def SaveAllTraitsToDBandCSVandMD(tabl_fun: list[tgen]) -> None:
"""
Saves all traits to a database, CSV, and Markdown file.
Saves all traits to a database, a CSV file, and Markdown file.
This function iterates over a list of tabl_fun objects and performs the following actions for each object:
1. Saves the traits to a database using the SaveTraitsToDB function.
Expand All @@ -696,7 +694,6 @@ def SaveAllTraitsToDBandCSVandMD(tabl_fun: list[tgen]) -> None:
for fun in tabl_fun:
SaveTraitsToDB(fun)
ConvertDBtoCSVandMD(GetDataPath(fun.id, "db"), fun.id)
return


def MergeAllDBs(tablfun: list[tgen]):
Expand Down Expand Up @@ -794,8 +791,7 @@ def test99():
def test9():
MergeAllDBs(tabl_fun)

# Returns A051031 found by hash which is false if the constant
# MINTERMS is not large enough!

def test33():
from tabl import CTree as triangle
# from tabl import CentralE, CentralO
Expand All @@ -817,5 +813,5 @@ def test33():

print(cthash, ",FNVhash")

OeisToSql()
test33()
# OeisToSql()
# test33()
13 changes: 7 additions & 6 deletions src/_tablhtml.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
"</script>\n" "<p>&nbsp;</p></body></html>",
]

Footer = ("<div style='word-wrap: break-word; width: 95%;'><p style='margin-left:14px'>"
Footer = ("<div style='word-wrap: break-word; width: 95%; max-width:710px;'><p style='margin-left:14px'>"
"Note: The A-numbers are based on a finite number of numerical comparisons. "
"The B-numbers are A-numbers of sligthly different variants. They ignore the sign "
"and the OEIS-offset and might differ in the first few values. Since the offset "
Expand Down Expand Up @@ -189,18 +189,19 @@ def CsvToHtml(fun: tgen) -> None:
# Layout: index,triangle,trait,anum,seq
# 0,Abel:Std,Triangle,A137452,1 0 1 0 ...
# index = line[0]
h = line[1]
type = h[h.index(":") + 1:]
trait = line[2]
anum = line[3]
seq = line[4]
# name = line[1]
type = line[2]
trait = line[3]
anum = line[4]
seq = line[5]

outfile.write(f"<tr><td class='type'>{type}</td>")
tip = FORMULA[trait]
outfile.write(
f"<td class='tooltip'>{trait}<span class='formula'>{tip}</span></td>"
)

print(seq)
sseq = (seq.split(" ", 3)[3]).replace(" ", ",")

if anum == "missing":
Expand Down
7 changes: 4 additions & 3 deletions src/_tablmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@
"_tablexport.py",
"_tablhtml.py",
"_tabltraits.py",
"_tablstatistic",
"_tablstatistic.py",
"_tabldata.py",
"_tablsinglemake.py",
]


Expand Down Expand Up @@ -197,7 +198,7 @@
]\n""".format()

import_header: list[str] = [
# "from os import remove\n",
"from os import remove\n",
"import datetime\n",
"from functools import cache, reduce\n",
"from itertools import accumulate\n",
Expand All @@ -217,7 +218,7 @@
"import gzip\n",
"import sqlite3\n",
"import pandas as pd\n",
"from fractions import Fraction as frac\n",
"from fractions import Fraction\n",
"from pathlib import Path\n",
]

Expand Down
12 changes: 6 additions & 6 deletions src/_tablpoly.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Callable
from fractions import Fraction as frac
from fractions import Fraction
from _tabltypes import rgen, tgen, tabl, trow

# #@
Expand Down Expand Up @@ -50,29 +50,29 @@ def Poly(g: rgen, size: int) -> trow:
return [i for row in PolyDiagTabl(g, size) for i in row]


def PolyFrac(T: tabl, x: frac) -> list[frac | int]:
def PolyFrac(T: tabl, x: Fraction) -> list[Fraction | int]:
return [sum(c * (x ** k) for (k, c) in enumerate(row)) for row in T]


def PosHalf_(g: rgen, size: int) -> trow:
T = [g(n) for n in range(size)]
R = PolyFrac(T, frac(1, 2))
R = PolyFrac(T, Fraction(1, 2))
return [((2 ** n) * r).numerator for n, r in enumerate(R)]


def PosHalf(T: tabl) -> trow:
R = PolyFrac(T, frac(1, 2))
R = PolyFrac(T, Fraction(1, 2))
return [((2 ** n) * r).numerator for n, r in enumerate(R)]


def NegHalf_(g: rgen, size: int) -> trow:
T = [g(n) for n in range(size)]
R = PolyFrac(T, frac(-1, 2))
R = PolyFrac(T, Fraction(-1, 2))
return [(((-2) ** n) * r).numerator for n, r in enumerate(R)]


def NegHalf(T: tabl) -> trow:
R = PolyFrac(T, frac(-1, 2))
R = PolyFrac(T, Fraction(-1, 2))
return [(((-2) ** n) * r).numerator for n, r in enumerate(R)]


Expand Down
2 changes: 2 additions & 0 deletions src/_tablsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,6 @@ def setup() -> None:
# DO NOT USE 'setup' if you only want to update tabl.py.
# If you want to update 'tabl.py' after you have added a new
# triangle implementation just run "src/_tablmake.py".
# Or use the function 'SingleMake(triangle)' from _tablsinglemake
# where 'triangle' is the generator of the triangle.
setup()
31 changes: 31 additions & 0 deletions src/_tablsinglemake.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from _tabltypes import tgen
from _tablpaths import GetDataPath
from _tablhtml import CsvToHtml
from _tabldata import SaveTraitsToDB, ConvertDBtoCSVandMD
from _tablstatistic import SingleStatistic


# #@


def SingleMake(fun: tgen) -> None:
"""
- Saves the traits of the triangle 'fun' to a database, a CSV file, and Markdown file.
- Then the HTML file is updated.
- The traits statistics is displayed.
Args:
fun (tgen): The generator of the triangle.
Returns:
None
"""
SaveTraitsToDB(fun)
ConvertDBtoCSVandMD(GetDataPath(fun.id, "db"), fun.id)
CsvToHtml(fun)
SingleStatistic(fun)


if __name__ == "__main__":
from Eulerian import Eulerian as triangle
SingleMake(triangle)
Loading

0 comments on commit d88869e

Please sign in to comment.