Code to calculate tetration using my method
#6
I asked ChatGTP to add the docstrings (which I edited, but I have no clue what this code does)

Fixed the tabulation error.

I suggest to use math.complex instead of the real and imaginary parts

I added some "TODO:" labels 

Code:
# This code uses Shanghai46 method for calculation of tetration as described in
# TODO: fix link
# https://tetrationforum.org/search.php?action=results&sid=afae76cdf0119ae9ab1587cdd6166152&sortby=dateline&order=desc&uid=0
#
#Call tree
# tetra
# ├── fn <-- n is integer
# ├── tetraa <-- e^-e < X < e^(1/e)
# │   ├── entier
# │   ├── decimal
# │   ├── Nu
# │   ├── fn
# │   ├── TAU
# │   ├── LPr
# │   ├── LPi
# │   └── logan
# └── fin <-- e^(1/e) < X
#     ├── decimal
#     ├── entier
#     ├── logwan
#     ├── lim
#     ├── NA
#     ├── BIGx
#     ├── gamma
#     ├── Gn
#     ├── BIGn
#     ├── logan
#     ├── PUr
#     └── PUi
from math import *
import numpy as np


def mod(a, b):
    # TODO this function is unnecessary, because is equivalent to abs(math.complex(a,b))
    """Calculates the modulus of a and b.

    Args:
        a: A number.
        b: A number.

    Returns:
        The modulus of a and b.
    """

    # A = (a**2 + b**2) ** 0.5
    # return A
    return abs(complex(a, b))


def Arg(a, b):
    # TODO this function is unnecessary, because is equivalent to np.angle(math.complex(a,b))
    """Calculates the argument of a and b.

    Args:
        a: A number.
        b: A number.

    Returns:
        The argument of a and b.
    """

    # Z = atan2(b, a)
    # return Z
    return np.angle(complex(a, b))


def p(x):
    """returns x when x is positive,
       or the fractional part of x, when x is negative

    Args:
        x: A number.

    Returns:
        If x is positive, the function returns x.
        If x is negative, the function returns the fractional part of x.
    """

    # a = x
    # while a < 0:
    #     a = a + 1
    # return a
    return x if x >= 0 else x % 1


def fn(a, n):
    """Calculates the tetration of a to the power of n.

    Args:
        a: A number.
        n: A number.

    Returns:
        The repeated power of a, n times
    """

    # X = 0
    # while n + 1 > 0:
    #     n = n - 1
    #     X = a**X
    # return X

    result = 1
    for i in range(n):
        result = a**result
    return result


def logan(X, Y, a, n):
    """Calculates the n-iterated logarithm of X in base a.

    Args:
        X: A number.
        Y: A number.
        a: A number.
        n: A number.

    Returns:
        a tuple of real numbers:
        The real, and the imaginary part of:
            The n-iterated logarithm of X in base a.
    """

    result = complex(X, Y)
    for i in range(n):
        result = log(result, a)

    return result.real, result.imag


def TAU(X):
    """Calculates the TAU function of X.

    Args:
        X: A number.

    Returns:
        The TAU function of X.
    """
    # TODO: Is this a limit for long tetrations?
    # It will rapidly overflow
    # maybe is better to check the radius of convergence and calcualte the limit using the known functions.

    # n = 0
    # a = 1
    # while n < 400:
    #     a = X**a
    #     n += 1
    # return a
    a = 1
    for i in range(400):
        a = X**a
    return a


def LAMBDA(X):
    """Calculates the LAMBDA function of X.

    Args:
        X: A number.

    Returns:
        The LAMBDA function of X.
    """

    # a = log(X, e) * TAU(X)
    a = log(X) * TAU(X)
    return a


def lpr(x, p, b):
    # TODO: No clue if this calculates a real part
    # Should use complex numbers right away?
    """Calculates the real part of the lp function of x, p, and b.

    Args:
        x: A number.
        p: A number.
        b: A number.

    Returns:
        The real part of the lp function of x, p, and b.
    """

    X = LAMBDA(x)
    if X >= 0:
        A = (X**p) * cos(log(X) * b)
    else:
        A = exp(log(-X, e) * p - pi * b) * cos(log(-X) * b + p * pi)
    return A


def lpi(x, p, b):
    # TODO: No clue if this calculates a maginary part
    # Should use complex numbers right away?
    """Calculates the imaginary part of the L function of x, p, and b.

    Args:
        x: A number.
        p: A number.
        b: A number.

    Returns:
        The imaginary part of the L function of x, p, and b.
    """

    X = LAMBDA(x)
    if X >= 0:
        A = (X**p) * sin(log(X, e) * b)
    else:
        A = e ** (log(-X, e) * p - pi * b) * sin(log(-X, e) * b + p * pi)
    return A


def entier(X):
    # TODO:redundant function, which renames floor()
    # Is better to rename the function to "floor" and delete it.
    """Calculates the integer part of X.

    Args:
        X: A number.

    Returns:
        The integer part of X.
    """

    return floor(X)


def decimal(X):
    # TODO: check if is required for readability.
    # Otherwise rename decimal(X) to "x % 1"
    """Calculates the decimal part of X."""
    # a = entier(X)
    # b = X - a
    # return b
    return X % 1


def Nu(X):
    """Calculates the number of iterations needed to calculate the b**iterations = X.

    Args:
        X: A number.

    Returns:
        An integer.
        The number of iterations.
    """

    n = 0
    a = fn(X, n)
    b = TAU(X)
    error_squared = (
        0.0001**2
    )  # To avoid redundant calculations and improve readability
    while ((a - b) ** 2) > error_squared:
        n = n + 1
        a = fn(X, n)
    return n


def tetraa(X, a, b):
    """Calculates the iterated logarithm of [TODO:SOMETHING] in base X, Nu(X) times.

    Args:
        X: A number.
        a: A number.
        b: A number.

    Returns:
        A tuple of real numbers
    """

    E = entier(a)
    D = decimal(a)
    N = Nu(X)
    A = fn(X, N + E) - TAU(X)
    B = (A * (lpr(X, D, b))) + TAU(X)
    C = A * (lpi(X, D, b))
    O = logan(B, C, X, N)
    return O


def BIGn(X):
    """Calculates the BIGn function of X.
    Which is a number of iterations

    TODO:
    WARNING: SIDE EFFECT:
    THE VALUE OF X IS MODIFIED
    Args:
        X: A number.

    Returns:
        an integer
    """

    n = X
    a = 1
    if 3.9 < X < 5:
        X = X**X
        a = 2
    else:
        # TODO: if X is complex, X < 3000 will fail
        while X < 3000:
            X = n**X
            a = a + 1
    return a


def BIGx(X):
    """Calculates the BIGx function of X. TODO: ?

    Args:
        X: A number.

    Returns:
        The BIGx function of X.
    """

    n = X
    if 3.9 < X < 5:
        X = X**X
    else:
        while X < 3000:
            X = n**X
    return X


def logwan(X, a, n):
    """Calculates the n-iterated-logarithm of X in base a.

    Args:
        X: A number.
        a: A number.
        n: A number.

    Returns:
        A number.
    """

    # while n > 0:
    #     X = log(X + 1, a)
    #     n = n - 1
    # return X
    for i in range(n):
        X = log(X + 1, a)
    return X


def PUr(X, a, b, n):
    """Calculates the [real part?] of the PU [?] function of X, a, b, and n.

    TODO:
    WARNING: SIDE EFFECTS
    a, b and n are modified
    Args:
        X: A number.
        a: A number.
        b: A number.
        n: A number.

    Returns:
        A number
    """

    while n > 0:
        A = (X**a) * cos(log(X, e) * b)
        B = (X**a) * sin(log(X, e) * b)
        a = A
        b = B
        n = n - 1
    return a


def PUi(X, a, b, n):
    """Calculates the [imaginary part?] of the PU function of X, a, b, and n.

    Args:
        X: A number.
        a: A number.
        b: A number.
        n: A number.

    Returns:
        A number
    """

    while n > 0:
        A = (X**a) * cos(log(X, e) * b)
        B = (X**a) * sin(log(X, e) * b)
        a = A
        b = B
        n = n - 1
    return b


def Gn(a, b, X, n):
    """Calculates the [real and imaginary parts?] of the G function of a, b, X, and n.

    Args:
        a: A number.
        b: A number.
        X: A number.
        n: A number.

    Returns:
        a tuple of numbers
    """

    while n > 0:
        A = (X**a) * cos(log(X, e) * b) - 1
        B = (X**a) * sin(log(X, e) * b)
        a = A
        b = B
        n = n - 1
    return a, b


def lim(X):
    """Calculates the limit of the tetrahedral function of X.

    Args:
        X: A number.

    Returns:
        The limit of the tetrahedral function of X.
    """

    A = BIGx(X)
    # if X < e:
    #     b = logwan(A, X, 400)
    # else:
    #     b = 0
    # return b
    return logwan(A, X, 400) if X < e else 0


def gamma(X):
    #TODO: if this is the standard gammma function, it is available in scipy.special.gammma()
    #Otherwise is an unfortunate name choice
    """Calculates the [gamma function?] of X.

    Args:
        X: A number.

    Returns:
        The gama function of X.
    """

    #A = (lim(X) + 1) * log(X, e)
    A = (lim(X) + 1) * log(X) #Log() is base e when the base is non specified
    return A


def NA(X):
    """Calculates a number of iterations .

    Args:
        X: A number.

    Returns:
        an integer
    """

    A = BIGx(X)
    B = lim(X)
    n = 0
    error_squared = (10 ** -6)**2
    while ((A - B) ** 2) > error_squared:
        n = n + 1
        A = logwan(A, X, 1)
    return n


def fin(X, p, b):
    """Calculates the [fin?] function of X, p, and b, where X is greater than e**(1/e).

    Args:
        X: A number.
        p: A number.
        b: A number.

    Returns:
        A tuple of numbers
    """

    E = decimal(1 - decimal(p))
    Z = entier(p)
    A = BIGx(X)
    B = logwan(A, X, NA(X))
    C = B - lim(X)
    D = (C / (gamma(X) ** E) * cos(log(gamma(X), e) * b)) + lim(X)
    W = C / (gamma(X) ** E) * sin(log(gamma(X), e) * b)
    F, U = Gn(D, W, X, NA(X))
    Y = BIGn(X) - E - p
    if Y >= 0:
        O = logan(F, U, X, Y)
    else:
        O = PUr(F, U, X, -Y), PUi(F, U, X, -Y)
    return O


def tetra(X, n, b):
    """Calculates [the tetration?] of X to n, and b.

    Args:
        X: A number.
        n: A number.
        b: A number.

    Returns:
        #TODO returns different types? Better would be to use math.complex() and always return complex
        A number when n >= -1 and decimal(n) <= 0 and b == 0:
        A tuple of numbers otherwise
    """

    if n < -2 and p(n) <= 0:
        # Z = "ERROR"
        raise ValueError("n must be greater than -2 and p(n) must be greater than 0.")
    #TODO: decimal() cannot return a value decimal(n) <= 0, so the check is redundant or there is some problem.
    elif n >= -1 and decimal(n) <= 0 and b == 0:
        Z = fn(X, n)
    else:
        if e ** (-e) <= X <= e ** (1 / e):
            Z = tetraa(X, n, b)
        elif X > e ** (1 / e):
            Z = fin(X, n, b)
        else:
            # Z = "ERROR"
            raise ValueError("X must satisfy e^-e <= X )
    return Z
Reply


Messages In This Thread
RE: Code to calculate tetration using my method - by marracco - 10/19/2023, 01:34 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Terse Schroeder & Abel function code Daniel 1 1,794 10/16/2022, 07:03 AM
Last Post: Daniel
  The beta method program JmsNxn 0 2,299 02/25/2022, 03:05 AM
Last Post: JmsNxn
  C++ code for tet, ate and hexp MorgothV8 0 6,578 07/10/2014, 04:24 PM
Last Post: MorgothV8
  Which method is currently "the best"? MorgothV8 2 10,907 11/15/2013, 03:42 PM
Last Post: MorgothV8
  "Kneser"/Riemann mapping method code for *complex* bases mike3 2 14,027 08/15/2011, 03:14 PM
Last Post: Gottfried
  An incremental method to compute (Abel) matrix inverses bo198214 3 17,469 07/20/2010, 12:13 PM
Last Post: Gottfried
  Single-exp series computation code mike3 0 6,093 04/20/2010, 08:59 PM
Last Post: mike3
  Toying with the Borel summation to calculate tetration mike3 11 37,552 03/25/2010, 09:00 PM
Last Post: mike3
  SAGE code for computing flow matrix for exp(z)-1 jaydfox 4 18,623 08/21/2009, 05:32 PM
Last Post: jaydfox
  Matrix-method: compare use of different fixpoints Gottfried 23 58,885 11/30/2007, 05:24 PM
Last Post: andydude



Users browsing this thread: 1 Guest(s)