ATOMIC MACHINE LEARNING (AML)

Atomic Machine Learning is a group of Machine Learning algorithms based on Atomic Functions and Atomic Strings.

AML theory is being developed in ResearchGate project https://www.researchgate.net/project/Atomic-Machine-Learning-and-Artificial-Intelligence-with-Atomic-Soliton-and-R-functions by Professor Sergei Yurievich Eremenko https://www.researchgate.net/profile/Sergei_Eremenko.

The file contains Python script for Atomic Function, Atomic String, Atomic Sigmoid and Atomic Gaussian.

Atomic Function (https://ru.wikipedia.org/w/index.php?oldid=82669103) discovered in 1970th by Academician of National Academy of Sciences of Ukraine Rvachev V.L. (https://ru.wikipedia.org/w/index.php?oldid=83948367) and Professor Rvachev V.A. and advanced by many followers notably Professor Kravchenko V.F. (https://ru.wikipedia.org/w/index.php?oldid=84521570).

Atomic String (AString) as a generalization/integral of an Atomic Function is introduced by the author, Professor Sergei Yu. Eremenko (https://www.researchgate.net/profile/Sergei_Eremenko, https://au.linkedin.com/in/sergei-eremenko-3862079), in paper "Atomic Strings and Fabric of Spacetime" https://www.researchgate.net/publication/320457739

Abstract of paper "Atomic Machine Learning"

The theory of atomic functions (AF) evolving since 1970th has found many applications in different branches of mathematics and physics, and now we explore its applicability for a data science domain of Machine Learning. Pulse-like AF can be used to build atomic kernel in Support Vector Machines to describe proximity to singular landmarks and ultimately define complex Decision Boundaries. Atomic local weighted regression can be build by introducing the AF weight function in locally weighted scatterplot smoothing (LOESS) technique. AString as an integral from AF can be the foundation of atomic regression and atomic activation function for Neural Networks. Unsuperwised Machine Learning algorithms like Principal Component Analysis, Dimensionality Reduction and Density Estimations can also use AF and AString which have unique properties of compact support, fast calculation of derivatives via themselves and ability to exactly represent sections of polynomials and other functions widely used in statistics. AF as a probabilistic weighted distribution of uniformly random variables is deeply related to Prouhet–Thue–Morse sequence which may have more relevance for some fair games and sequencing processes. Multiple real Matlab, R and Python examples calculate complex decision boundaries and regressions. The concepts of an atomic computer and calculus are also discussed. In combination, these methods compose Atomic Machine Learning theory which extends the 50 years’ history of AFs and their generalizations to new scientific domains.

Script for Atomic Function (introduced in 1971 by V.L.Rvachev and V.A.Rvachev)

In [1]:
##########################################################
##This script introduces Atomic Function and Atomic String
##########################################################
import numpy as np
import pylab as pl
################### One Pulse of atomic function
def up1(x: float) -> float:
    #Atomic function table
    up_y = [0.5, 0.48, 0.460000017,0.440000421,0.420003478,0.400016184, 0.380053256, 0.360139056, 0.340308139, 0.320605107,
           0.301083436, 0.281802850, 0.262826445, 0.244218000, 0.226041554, 0.208361009, 0.191239338, 0.174736305, 
           0.158905389, 0.143991189, 0.129427260, 0.115840866, 0.103044024, 0.9110444278e-01, 0.798444445e-01, 0.694444445e-01, 
           0.598444445e-01, 0.510444877e-01, 0.430440239e-01, 0.358409663e-01, 0.294282603e-01, 0.237911889e-01, 0.189053889e-01, 
           0.147363055e-01, 0.112393379e-01, 0.836100883e-02, 0.604155412e-02, 0.421800000e-02, 0.282644445e-02, 0.180999032e-02, 
           0.108343562e-02, 0.605106267e-03, 0.308138660e-03, 0.139055523e-03, 0.532555251e-04, 0.161841328e-04, 0.347816874e-05, 
           0.420576116e-05, 0.167693347e-07, 0.354008603e-10, 0]
    up_x = np.arange(0.5, 1.01, 0.01)

    res = 0.
    if ((x>=0.5) and (x<=1)):
        for i in range(len(up_x) - 1):
            if (up_x[i] >= x) and (x < up_x[i+1]):
                N1 = 1 - (x - up_x[i])/0.01
                res = N1 * up_y[i] + (1 - N1) * up_y[i+1]
                return res
    return res

############### Atomic Function Pulse with width, shift and scale #############
def upulse(t: float, a = 1., b = 0., c = 1., d = 0.) -> float:
    x = (t - b)/a
    res = 0.
    if (x >= 0.5) and (x <= 1):
        res = up1(x)
    elif (x >= 0.0) and (x < 0.5):
        res = 1 - up1(1 - x)
    elif (x >= -1 and x <= -0.5):
        res = up1(-x)
    elif (x > -0.5) and (x < 0):
        res = 1 - up1(1 + x)
    res = d + res * c
    return res

############### Atomic Function Applied to list with width, shift and scale #############
def up(x: list, a = 1., b = 0., c = 1., d = 0.) -> list:
    res: list = []
    for i in range(len(x)):
        res.append(upulse(x[i], a, b, c, d))
    return res
In [2]:
x = np.arange(-2.0, 2.0, 0.01)
pl.title('Atomic Function')
pl.plot(x, up(x), label='Atomic Function')
pl.grid(True)
pl.show()

Atomic String as an Integral of Atomic Function (introduced in 2017 by Prof S.Eremenko)

In [3]:
############### Atomic String #############
def AString1(x: float) -> float:
    res = 1 * (upulse(x/2.0 - 0.5) - 0.5)
    return res

############### Atomic String Pulse with width, shift and scale #############
def AStringPulse(t: float, a = 1., b = 0., c = 1., d = 0.) -> float:
    x = (t - b)/a
    if (x < -1):
        res = -0.5
    elif (x > 1):
        res = 0.5
    else:
        res = AString1(x)
    res = d + res * c
    return res

###### Atomic String Applied to list with width, shift and scale #############
def AString(x: list, a = 1., b = 0., c = 1., d = 0.) -> list:
    res: list = []
    for i in range(len(x)):
        res.append(AStringPulse(x[i], a, b, c, d))
        #res[i] = AStringPulse(x[i], a, b, c)
    return res

###### Summation of two lists #############
def Sum(x1: list, x2: list) -> list:
    res: list = []
    for i in range(len(x1)):
       res.append(x1[i] + x2[i])
    return res
In [4]:
pl.title('Atomic String')
pl.plot(x, AString(x, 1.0, 0, 1, 0), label='Atomic String')
pl.grid(True)
pl.show()

Atomic String, Atomic Function and Atomic Function Derivative plotted together

In [5]:
#This Calculates Derivative
dx = x[1] - x[0]
dydx = np.gradient(up(x), dx)
pl.plot(x, up(x), label='Atomic Function')
pl.plot(x, AString(x, 1.0, 0, 1, 0), label='Atomic String')
pl.plot(x, dydx, label='A-Function Derivative')

pl.title('Atomic Function and String')
pl.legend(loc='best', numpoints=1)
pl.grid(True)
pl.show()

Properties of atomic function Up(x)

1) Remarkably, Atomic Function Derivative can be exressed via Atomic Function itself - up'(x)= 2up(2x+1)-2up(2x-1) meaning the shape of pulses for derivative function can be represented by shifted and stratched Atomic Function itself - remarkable property

2) The Atomic Function pulses superposition set at points -2, -1, 0, +1, +2... can exactly represent a Unity (number 1): 1 = ... up(x-3) + up(x-2) + up(x-1) + up(x-0) + up(x+1) + up(x+2) + up(x+3) + ...

In [6]:
pl.plot(x, up(x, 1, -1), linewidth=1, label='Atomic Function at x=-1')
pl.plot(x, up(x, 1, +0), linewidth=1, label='Atomic Function at x=0')
pl.plot(x, up(x, 1, -1), linewidth=1, label='Atomic Function at x=-1')
pl.plot(x, Sum(up(x, 1, -1), Sum(up(x), up(x, 1, 1))), linewidth=2, label='Atomic Function Compounding')
pl.title('Atomic Function Compounding represent 1')
pl.legend(loc='best', numpoints=1)
pl.grid(True)
pl.show()

3) Atomic Function (AF) is a 'finite' function (like spline) not equal to zero only on section |x|<=1

4) Atomic Function is a non-analytical function (can not be represented by Taylor's series), but with known Fourier Transformation allowing to exactly calculate AF in certain points, with tabular representation provided in script above.

Atomic String is a generalisation of an Atomic Function

1) Astring is an solition kink-like function - Integral of Atomic Function (AF) which can be expressed via AF itself: AString(x) = Integral(0,x)(Up(x)) = Up(x/2 - 1/2) - 1/2

2) Atomic Function can be represented via simple superposition of Atomic Strings: up(x) = AString(2x + 1) - AString(2x - 1)

In [7]:
#########   Presentation of Atomic Function via Atomic Strings ##########
x = np.arange(-2.0, 2.0, 0.01)

pl.plot(x, AString(x, 1, 0, 1, 0),  '--', linewidth=1,  label='AString(x)')
pl.plot(x, AString(x, 0.5, -0.5, +1, 0), '--', linewidth=2, label='+AString(2x+1)')
pl.plot(x, AString(x, 0.5, +0.5, -1, 0), '--', linewidth=2, label='-AString(2x-1)')
#pl.plot(x, up(x, 1.0, 0, 1, 0),     '--', linewidth=1, label='Atomic Function')
AS2 = Sum(AString(x, 0.5, -0.5, +1, 0), AString(x, 0.5, +0.5, -1, 0))
pl.plot(x, AS2, linewidth=3, label='Up(x) via Strings')
pl.title('Atomic Function as a Combination of AStrings')
pl.legend(loc='center left', numpoints=1)
pl.grid(True)
pl.show()

3) All derivatives of AString can be represented via AString itself: AString'(x) = AString(2x + 1) - AString(2x - 1)

4) Combination of Atomic Strings can exactly represent a straight line: x = AString(x) + Astring(x+1) + Astring(x+2)...

In [8]:
x = np.arange(-40.0, 40.0, 0.01)

#pl.plot(x, ABline (x, 1, 0),            label='ABLine 1*x')
pl.plot(x, AString(x, 10.0,-15, 10, -15),   '--',  linewidth=1, label='AString 1')
pl.plot(x, AString(x, 10.0, -5, 10, -5),    '--',  linewidth=1, label='AString 2')
pl.plot(x, AString(x, 10.0, +5, 10, +5),    '--',  linewidth=1, label='AString 3')
pl.plot(x, AString(x, 10.0,+15, 10, +15),   '--',  linewidth=1, label='AString 4')

AS2 = Sum(AString(x, 10.0, -15, 10, -15), AString(x, 10., -5, 10, -5))
AS3 = Sum(AS2, AString(x, 10, +5, 10, +5))
AS4 = Sum(AS3, AString(x, 10,+15, 10, +15))
pl.plot(x, AS4,  label='AStrings Joins', linewidth=2)

pl.title('Atomic Strings Combinations')
pl.legend(loc='best', numpoints=1)
pl.grid(True)
pl.show()

Representing a Continuum (like Spacetime Fabric) by joining of Atomic Strings Quanta

In [9]:
x = np.arange(-30.0, 30.0, 0.01)
#pl.plot(x, ABline (x, 1, 0),            label='ABLine 1*x')
pl.plot(x, AString(x, 10.0,-15, 10, -15),   '--',  linewidth=1, label='AString Quantum 1')
pl.plot(x, AString(x, 10.0, -5, 10, -5),    '--',  linewidth=1, label='AString Quantum 2')
pl.plot(x, AString(x, 10.0, +5, 10, +5),    '--',  linewidth=1, label='AString Quantum 3')
pl.plot(x, AString(x, 10.0,+15, 10, +15),   '--',  linewidth=1, label='AString Quantum 4')

AS2 = Sum(AString(x, 10.0, -15, 10, -15), AString(x, 10., -5, 10, -5))
AS3 = Sum(AS2, AString(x, 10, +5, 10, +5))
AS4 = Sum(AS3, AString(x, 10,+15, 10, +15))
pl.plot(x, AS4,  label='Spacetime Dimension', linewidth=2)

pl.title('Representing of a Continuuum by joining of AStrings')
pl.legend(loc='best', numpoints=1)
pl.grid(True)
pl.show()
In [10]:
x = np.arange(-50.0, 50.0, 0.1)
dx = x[1] - x[0]

CS6 = Sum(up(x, 5, -30, 5, 5), up(x, 15, 0, 15, 5))
CS6 = Sum(CS6, up(x, 10, +30, 10, 5))
pl.plot(x, CS6,  label='Continuum Density')

IntC6 = np.cumsum(CS6)*dx/50
pl.plot(x, IntC6, label='Continuum Shape')

DerC6 = np.gradient(CS6, dx)
pl.plot(x, DerC6, label='Continuum Curvature')

pl.title('Curved Continuum')
pl.legend(loc='best', numpoints=1)
pl.grid(True)
pl.show()

Gaussian and Atomic Gaussian representing Atomic Kernels in Support Vector Machines, Density Estimation and Principal Component Analysis AML Algorithms

In [11]:
# Plot combined function
x = np.arange(-6.0, 6.0, 0.01)

gaussian = np.exp(-x*x/2)
pl.plot(x, gaussian, label='Gaussian')
pl.plot(x, up(x,3), label='Atomic Function')

pl.title('Gaussian and Atomic Function')
pl.legend(loc='best', numpoints=1)
pl.grid(True)
pl.show()

Sigmoid and Atomic Sigmoid representing Atomic Logistic Function in Atomic Logistic Regression and Atomic Activation Function in Neural Networks AML Algorithms

In [12]:
# Plot combined function
x = np.arange(-6.0, 6.0, 0.01)
sigmoid = 1./(1.+ np.exp(-x))
pl.plot(x, sigmoid, label='Sigmoid')
pl.plot(x, AString(x, 4.0, 0, 1, 0.5), label='Atomic String')
pl.title('Sigmoid and Atomic String Functions')
pl.legend(loc='best', numpoints=1)
pl.grid(True)
pl.show()

Atomic Function representing Three-Cube Kernel Function in Atomic Locally Weighted Regression ALOESS AML Algorithm

In [13]:
# Plot combined function
x = np.arange(-1.0, 1.0, 0.01)

cubic = np.power(1.-np.abs(x*x*x), 3);
pl.plot(x, cubic, label='Three-Cube Function')
pl.plot(x, up(x,1), label='Atomic Function')

pl.title('Three-Cube and Atomic Function')
pl.legend(loc='best', numpoints=1)
pl.grid(True)
pl.show()

Atomic String to represent Fabius Function

In [14]:
###### Fabius Function Applied to list with width, shift and scale #############
def Fabius(x: list, a = 1.0, b = 0, c = 1., d = 0) -> list:
    res: list = []
    for i in range(len(x)):
        res.append(AStringPulse(x[i], 0.5*a, 0.5 + b, 1.0*c, 0.5 + d))
    return res


###############   Plotting Atomic and String Functions ##############
x = np.arange(0.0, 1.01, 0.01)

#pl.plot(x, AString(x, 0.5, 0.5, 1, 0.5),   label='Atomic String 0.5, 0.5, 1, 0.5')
pl.plot(x,  Fabius(x), label='Fabius Function via AString')

pl.title('Fabius Function via AString')
pl.legend(loc='best', numpoints=1)
pl.grid(True)
pl.show()

Apart from standard Python code, this script and material is the intellectual property of Professor Sergei Yu. Eremenko (https://au.linkedin.com/in/sergei-eremenko-3862079). You may not reproduce, edit, translate, distribute, publish or host this document in any way without the permission of Professor Eremenko.