[PYTHON] Solving higher-order equations in a 4-unit cluster I (no multiple solutions)

Last time, we obtained the result that the calculation time of the simple loop can be reduced to 1/4 with a cluster of 4 Raspberry Pis. I wondered if I could calculate something with these four clusters. There were candidates for prime number calculation, multiprocessing, etc., but I decided to solve higher-order equations. Until now, when solving higher-order equations, we used Excel to draw scatter plots and line graphs, and zoomed in on the x-axis to obtain the solution. Let's get started with Python and ask for it programmatically.

I found that SciPy is the best way to solve equations. I have additionally installed NumPy and SciPy. However, I didn't understand how to use SciPy. After all, I decided to make my own Python program, which is not like a Python program again. This time we will solve the 10th order equation. Since the program is in the process of being created, we will use an expression that can be factored without multiple solutions. (There seems to be some discussion about significant figures and the number of digits, but I won't touch on this time.) The table below shows the calculation time of the program that solves the tenth-order equation created this time.

Model Raspberry Pi 4B Raspberry Pi 4B Raspberry Pi 4B
Number of units One One Cluster of 4
Number of threads 1 thread 4 threads 1 thread(各Pi)
processing time 52 seconds 53 seconds 13 seconds
import module time time threading time socket

At first, I compared 1 thread and 4 threads with one unit, but there is no difference between 52 seconds and 53 seconds. If you use 4 threads, the program will be a little complicated, but it will not reduce the calculation time. (Although the loop calculation time was exceptionally reduced by half last time), I decided to create a one-thread program this time. I created a program to solve a 10th-order equation of 1 thread each in a cluster of 4 Raspberry Pis. As a result, we were able to reduce the calculation time to 1/4 from 52 seconds to 13 seconds as shown in the table above. The cluster effect of 4 units is shown as it is. Since the calculation loop of the function of the 10th order equation with 6 significant digits is extremely rate-determining, the negative effect of LAN turnover of multiple clusters has not yet been found.

Example of a cubic equation without multiple solutions

Before solving the 10th-order equation, I made a program to solve a cubic equation that has no multiple solution and the answer is known. It is a cubic equation of y = 2.1 --2.1425x --2.3x ^ 2 + x ^ 3.

eq-3ji.py
import time

#Coefficient of cubic equation (no multiple solution)
a0 =  2.1
a1 = -2.1425
a2 = -2.3
a3 =  1.

answerszero = []

def y(R_f, R_w, X_init, X_end, A0, A1, A2, A3):
    for x0 in range(X_init, X_end):
        X = x0/R_f
        Y = A0 + A1*X**1 + A2*(X)**2 + A3*(X)**3
        if Y == 0.0:
            answerszero.append((X, Y))
        elif 0<Y and Y<R_w:
            answerszero.append((X, Y))
        elif 0>Y and Y>-R_w:
            answerszero.append((X, Y))

initial_time=time.time()
r_w=0.00002#Too few candidates or too many candidates

x_init=500000
x_end=2000000
r_f=-1000000
y(r_f,r_w,x_init,x_end,a0,a1,a2,a3)

x_init=500000
x_end=3000000
r_f=1000000
y(r_f,r_w,x_init,x_end,a0,a1,a2,a3)

print(f"Time :")
print(str(time.time() - initial_time))
print(f"Answers : (x, y)")
print(answerszero)
time.sleep(10)
# Time :
# 3.85....
# Answers : (x, y)
# (-1.150175, 4.698....e-06), (-1.150176, -2.418....e-06)
# (0.652651, 1.443....e-06), (0.652652, -2.422....e-06)
# (2.797524, -2.428....e-06), (2.797525, 6.038....e-06)

We are picking up candidates before and after the solution. The y value changes from positive to negative when x is from -1.150175 to -1.150176. The y value changes from positive to negative when x is from 0.652651 to 0.652652. The x is from 2.977524 to 2.797525 and the y value is changing from negative to positive. Since there is no multiple solution, the cubic curve crosses the x-axis at these three points. In other words, there are three solutions to the cubic equation y = 2.1 --2.1425x --2.3x ^ 2 + x ^ 3 = 0. --1.15017,0.65265,2.79752

This time I got the final solution visually. An algorithm that automatically determines this solution is Newton's method. We are thinking of higher-order equations that have multiple solutions in the next II, so we plan to try them together at that time. This time visually.

Steps to a tenth-order equation without multiple solutions

◇ Quadratic equation (with solution formula) (x-1)(x-2) = x2 - 3*x + 2 = 0 ◇ Third-order equation (with solution formula) (x-1)(x-2)(x-3) = (x-1) * (x2 - 5* x + 6) = x3 - 6*x2 + 11* x - 6 = 0 ◇ Quartic equation (with solution formula) (x-1)(x-2)(x-3)(x-4) = (x2 - 3*x + 2) * (x2 - 7* x + 12) = x4 - 10*x3 + 35x**2 - 50 x + 24 = 0 ◇ Fifth equation (x-1)(x-2)(x-3)(x-4)(x-5) = (x4 - 10*x3 + 35x**2 - 50 x + 24)(x-5) = x5 - 15*x4 + 85x**3 - 225x2 + 274* x - 120 = 0 ◇ Sextic equation (Excel approximation up to 6th equation) (x-1)(x-2)(x-3)(x-4)(x-5)(x-6) = (x5 - 15x**4 + 85x3 - 225*x2 + 274* x - 120)(x-6) = x6 - 21*x5 + 175x**4 - 735x3 +1624*x2 - 1764* x + 720 = 0 ◇ Septic equation (x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7) = (x6 - 21*x5 + 175x**4 - 735x3 +1624*x2 - 1764* x + 720)(x-7) = x7- 28*x6 + 322x**5 - 1960x4 + 6769*x3 - 13132x**2 + 13068x - 5040 = 0 ◇ octic equation (x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)(x-8) = (x7- 28*x6 + 322x**5 - 1960x4 + 6769*x3 - 13132x**2 + 13068x - 5040)(x-8) = x8 - 36*x7+ 546x**6 - 4536x5 + 22449*x4 - 67284x**3 + 118124x2 - 109584* x + 40320 = 0 ◇ Ninth-order equation (x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)(x-8)(x-9) = (x8 - 36x**7+ 546x6 - 4536*x5 + 22449x**4 - 67284x3 + 118124*x2 - 109584* x + 40320 )(x-9) = x9- 45*x8 + 870x**7 - 9450x6 + 63273*x5 - 269325x**4 + 723680x3 - 1172700*x2 + 1026576x - 362880 = 0 ◇ 10th-order equation (x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)(x-8)(x-9)(x-10) = (x**9- 45x8 + 870*x7 - 9450x**6 + 63273x5 - 269325*x4 + 723680x**3 - 1172700x2 + 1026576*x - 362880)(x-10) = x10 - 55x**9 + 1320x8 - 18150*x7 + 157773x**6 - 902055x5 + 3416930*x4 - 8409500x**3 + 12753576x**2 - 10628640*x + 3628800 = 0

It was a long way to the tenth-order equation, but I managed to get some coefficients for the calculation. And I made a program to solve the 10th order equation. Since the number of significant figures has been increased from 6 digits to 7 digits after the decimal point, it takes 480 seconds for one Raspberry Pi 4B. It takes about 8 minutes. The heat sink is warm.

eq-10ji-option-jit.py
import time
#from numba import njit

answersX  = []
answersY  = []

#@njit(cache=True)
def calc_2s(thread_NO,R_F,R_W,X_init,X_end,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10):
    totalsX=[6]
    totalsY=[6]
    for x in range(X_init, X_end):
        X = x/R_F
        Y =A0+A1*(X)**1+A2*(X)**2+A3*(X)**3+A4*(X)**4+A5*(X)**5+A6*(X)**6+A7*(X)**7+A8*(X)**8+A9*(X)**9+A10*(X)**10
        if Y == 0.0:
            totalsX.append(X)
            totalsY.append(Y)
        elif 0 < Y and Y <  R_W:
            totalsX.append(X)
            totalsY.append(Y)
        elif 0 > Y and Y > -R_W:
            totalsX.append(X)
            totalsY.append(Y)
    return totalsX, totalsY

n=0
print(f"pre-cache")
x_init=0
x_end=5
r_f=1
r_w=0.000000001
a0=1.0
a1=-3.0
a2=2.0
a3=0.
a4=0.0
a5=0.0
a6=0.0
a7=0.0
a8=10.0
a9=0.0
a10=0.0
answersX, answersY = calc_2s(n,r_f,r_w,x_init,x_end,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
answersX.clear()
answersY.clear()
print(f"Calculation Start")
x_init=0
x_end=120000001
r_f=10000000
r_w=0.011
a0=3628800.0
a1=-10628640.0
a2=12753576.0
a3=-8409500.0
a4=3416930.0
a5=-902055.0
a6=157773.0
a7=-18150.0
a8=1320.0
a9=-55.0
a10=1.0
initial_time=time.time()
answersX, answersY = calc_2s(n,r_f,r_w,x_init,x_end,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
print(f"Calculation Finished")
answersX.remove(answersX[0])
answersY.remove(answersY[0])
answersXY=[]
for i in range(len(answersX)):
    answersXY.append((answersX[i], answersY[i]))
print(f"Time :")
print(str(time.time() - initial_time))
print(f"Answers :")
print(answersXY)
time.sleep(10)

Basic option @njit

If you remove the'#' in the program, the program will run on the Raspberry Pi using @njit in numba. It's 3.9 seconds. The calculation time is reduced to 1/120 when compared to @njit None. @njit only supports some of the functions that are included in Raspberry Pi OS from the beginning, but it seems that the support will be expanded further in the future. Version of each module of Raspberry Pi 4B (2020DEC24) OS : Raspberry Pi OS with desktop : 2020-12-02-raspios-buster-armhf.img Numpy : 1.19.4 LLvmlite : 0.27.0 Numba : 0.39.0 Cython : 0.29.21 (Scipy : 1.5.4)

Finally, according to the warning msg, when the versions of each module are matched, @jit accidentally started to move on Raspberry Pi 4B. Also, numba is displayed as required: numpy, llvmlite, but it did not work on Windows 10 (x64) even if the version was matched. As of 2020DEC25 for Windows 10 (x64), @njit started working immediately for Python 3.8 + Anaconda's Jupiter Notebook. For reference, the pip3 list for Raspberry Pi 4B of Raspberry Pi OS with desktop (2020DEC02) is attached.

pi@raspberrypi:~ $ pip3 list 
Package   Version
- - - - -    - - - - - 
asnicrypto   0.24.0 
astroid    2.1.0 
asttokens    1.1.13 
automationhat   0.2.0 
beautifulsoup4   4.7.1 
blinker     1.4 
blinkt 	    0.1.2 
buttonshim    0.0.2
cairocffi    1.2.0
capixxx     0.1.3 
certifi     2018.8.24 
cffi           1.14.4
chardet     3.0.4 
Click 	    7.0 
colorama    0.3.7
colorzero    1.1
cookies     2.2.1 
cryptography   2.6.1 
cupshelpers   1.0 
cycler     0.10.0 
cython     0.29.21 
decorator     4.3.0 
docutils    0.14
drumhat   0.1.0 
entrypoints   0.3 
envirophat   1.0.0 
Explorer HAT    0.4.2 
Flask     1.0.2 
fourletterphat   0.1.0 
gpiozero    1.5.1 
html5lib    1.0.1 
idna    2.6 
isort     4.3.4 
itsdangerous   0.24 
jedi    0.13.2 
Jinja2    2.10 
keyring    17.1.1 
keyrings.alt     3.1.1 
kiwisolver    1.3.1 
lazy-object-proxy   1.3.1 
llvmlite    0.27.0 
logilab-common    1.4.2 
lxml     4.3.2 
MarkupSafe    1.1.0 
matplolib         3.3.3
mccabe       0.6.1 
microdotphat    0.2.1 
mote    0.0.4
motephat    0.0.3 
mypy     0.670 
mypy-extensions  0.4.1 
numba    0.39.0 
numpy    1.19.4 
oauthlib    2.1.0 
olefile    0.46 
pantilthat   0.0.7 
parso    0.3.1 
pexpect   4.6.0 
pgzero    1.2 
phatbeat   0.1.1 
pianohat   0.1.0 
picamera   1.13 
piglow    1.2.5 
pigpio    1.44 
Pillow    8.0.1 
pip     18.1 
psutil    5.5.1 
pycairo   1.16.2
pycparser    2.20
pycrypto   2.6.1 
pycups   1.9.73 
pygame   1.9.4.post1 
Pygments   2.3.1 
PyGObject   3.30.4 
pyinotify   0.9.6 
PyJWT   1.7.0 
pylint   2.2.2 
pyOpenSSL   19.0.0 
pyparsing   2.4.7 
pyserial   3.4 
pysmbc    1.0.15.6 
python-apt   1.8.4.1 
python-dateutil   2.8.1 
pyxdg    0.25 
rainbowhat  0.1.0 
report lab    3.5.13 
requests    2.21.0 
requests-oauthlib   1.0.0 
responses    0.9.0 
roman    2.0.0 
RPi.GPIO    0.7.0 
RTIMULib    7.2.1 
scipy    1.5.4 
scrollphat   0.0.7
scrollphathd  1.2.1 
Secret Storage  2.3.1 
Send2Trash  1.5.0 
sense-hat  2.2.0 
setuptools  40.8.0 
simplejson  3.16.0 
six    1.12.0 
skywriter  0.0.7 
sn3218   1.2.7 
soupsieve  1.8 
spidev   3.4 
ssh-import.id  5.7 
thonny   3.3.0 
touchphat  0.0.1 
twython   3.7.0 
typed-ast  1.3.1 
unicornhathd  0.0.4 
urllib3   1.24.1 
webencodings   0.5.1 
Werkzeug   0.14.1 
wheel   0.32.3 
wrapt   1.10.11 
pi@raspberrypi:~ $

Basic option multiprocessing

eq-10ji-multiprocessing-option-jit.py
import time
from multiprocessing import Pool
#from numba import njit

#@njit(cache=True)
def calc_2s(n0,R_f,R_w,X_init,X_end,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10):
    totalsXY=[6]
    for x0 in range(int(X_init), int(X_end)):
        X = x0/R_f
        Y = A0+A1*(X)**1+A2*(X)**2+A3*(X)**3+A4*(X)**4+A5*(X)**5+A6*(X)**6+A7*(X)**7+A8*(X)**8+A9*(X)**9+A10*(X)**10
        if Y == 0.0:
            totalsXY.append(X)
            totalsXY.append(Y)
        elif 0 < Y and Y <  R_w:
            totalsXY.append(X)
            totalsXY.append(Y)
        elif 0 > Y and Y > -R_w:
            totalsXY.append(X)
            totalsXY.append(Y)
    return totalsXY


def wrapper_func(args):
    return calc_2s(*args)

def multi_processing_pool(Args_Lists):
    p = Pool(4)
    process_XY = p.map(wrapper_func, Args_Lists)
    p.close()
    return process_XY

if __name__=="__main__":


    print(f"pre-cache")
    n=0
    x_Range_to   = 12
    r_f = 10
    r_w = 0.1
    f_range = x_Range_to * r_f
    a0=1.
    a1=0.
    a2=0.
    a3=0.
    a4=0.
    a5=0.
    a6=0.
    a7=0.
    a8=0.
    a9=0.
    a10=0.
    ArgsLists= [(n,r_f,r_w,i*f_range/4,(i+1)*f_range/4,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) for i in range(4)]
    processXY = multi_processing_pool(ArgsLists)
    processXY.clear()
    
    print(f"Calculation Start")
    x_Range_to   = 12
    r_f = 10000000
    r_w = 0.011
    f_range = x_Range_to * r_f
    a0 = 3628800.0
    a1 =-10628640.0
    a2 = 12753576.0
    a3 =-8409500.0
    a4 = 3416930.0
    a5 =-902055.0
    a6 = 157773.0
    a7 =-18150.0
    a8 = 1320.0
    a9 =-55.0
    a10= 1.0
    initial_time=time.time()
    ArgsLists= [(n,r_f,r_w,i*f_range/4,(i+1)*f_range/4,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) for i in range(4)]
    processXY = multi_processing_pool(ArgsLists)
    print(f"Calculation Finished")
   
    processXYstr = str(processXY)
    processXYstr = processXYstr.replace('[[', '')
    processXYstr = processXYstr.replace(']]', '')
    processesXYstr=processXYstr.split('], [')
    process0XYstr=processesXYstr[0]
    process1XYstr=processesXYstr[1]
    process2XYstr=processesXYstr[2]
    process3XYstr=processesXYstr[3]
    process0sXYstr=process0XYstr.split(', ')
    process0sXYstr.remove(process0sXYstr[0])
    process1sXYstr=process1XYstr.split(', ')
    process1sXYstr.remove(process1sXYstr[0])
    process2sXYstr=process2XYstr.split(', ')
    process2sXYstr.remove(process2sXYstr[0])
    process3sXYstr=process3XYstr.split(', ')
    process3sXYstr.remove(process3sXYstr[0])
    answersXY=[]
    for i in range(int(len(process0sXYstr)/2)):
        answersXY.append((float(process0sXYstr[2*i]), float(process0sXYstr[2*i+1])))
    for i in range(int(len(process1sXYstr)/2)):
        answersXY.append((float(process1sXYstr[2*i]), float(process1sXYstr[2*i+1])))
    for i in range(int(len(process2sXYstr)/2)):
        answersXY.append((float(process2sXYstr[2*i]), float(process2sXYstr[2*i+1])))
    for i in range(int(len(process3sXYstr)/2)):
        answersXY.append((float(process3sXYstr[2*i]), float(process3sXYstr[2*i+1])))

    print(f"Time :")
    print(str(time.time() - initial_time))
    print(f"Answers :")
    print(answersXY)

A multi-process program that runs on a 4core Raspberry Pi 4B. It works with all 4 cores. The calculation time is 120 seconds for one Raspberry Pi 4B. Since it took 480 seconds to run only 1 core on one Raspberry Pi 4B with a single process, the calculation time is reduced to 1/4. Furthermore, if you remove the'#' in the program, the program will run on the Raspberry Pi using @njit of numba. It takes 1.4 seconds on the Raspberry Pi 4B. There are two lines such as * args that seem to be derived from C language, which is not familiar to python, but copy the functions other than the function names calc_2s and wrapper_func. Because it's a spell (originally the wrapper function allows you to use multiple arguments in a map, but I'm not sure what jit really is). This will make the multi-process unaffected by @njit. The calculation time is reduced to about 1/3 of 1.4 seconds with @njit for multi-process compared to 3.9 seconds with @njit for single process. Since it is 4 core, I expected it to be shortened by 1/4, but it can not be helped because the multi-process processing part does not support @njit conversion. Even so, it was reduced to about 1/3 by multi-processing. Compared to the 480 seconds of a single process without @njit, which is not accelerated at all, the calculation time is reduced to 1/340.

Next is a parallel processing program for 4 clusters. Almost all of the previous programs were ported, so there were no "unresolvable errors" like last time. (It seems a little difficult if there is a II multiple solution next time) The program created this time is shown below (it still does not work with @jit of numba or multiprocessing).

Created 4-cluster python program for 10th-order equations without multiple solutions

Put cluster2s-21.py in the Pi folder, run it in python3 and wait. The other three copy cluster2s-21.py and change it to 22, 23 and 24, respectively. Similarly, put it in the Pi folder, run it with python3, and wait. This time as well, it is a python program that does not look like a python program, but I will publish it.

cluster2s-21.py
import time
import socket

######  Change manually 2 Points to program NO  ########

answerszero = []

def calc_2s(n0,R_f,R_w,X_init,X_end,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10):
    print(f"START_CPU")
    for x0 in range(X_init, X_end):
        X = x0/R_f
        Y = A0+A1*(X)**1+A2*(X)**2+A3*(X)**3+A4*(X)**4+A5*(X)**5+A6*(X)**6+A7*(X)**7+A8*(X)**8+A9*(X)**9+A10*(X)**10
        if Y == 0.0:
            answerszero.append((X,Y))
        elif 0 < Y and Y <  R_w:
            answerszero.append((X,Y))
        elif 0 > Y and Y > -R_w:
            answerszero.append((X,Y))
    print(f"END_OF_CPU")

socket00 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket00.bind(('192.168.2.21', 60021))######## Point 1 : Change IP address and port to program NO ########
socket00.listen(5)
clientsocket, address = socket00.accept()
liststrEncode = b''
liststrEncode = clientsocket.recv(1016)
liststr=liststrEncode.decode("utf-8")
print(liststr)
# [[3628800.0, -10628640.0, 12753576.0, -8409500.0, 3416930.0, -902055.0, 157773.0, -18150.0, 1320.0, -55.0, 1.0],\
# [2, 1000000, 0.01, 0, 3000001]]
liststr = liststr.replace('[[', '')
liststr = liststr.replace(']]', '')
listsstr=[]
listsstr=liststr.split('], [')
list00str=listsstr[0]
listCLUSTERstr=listsstr[1]

lists00str=[]
lists00str=list00str.split(', ')
a0 =float(lists00str[0])
a1 =float(lists00str[1])
a2 =float(lists00str[2])
a3 =float(lists00str[3])
a4 =float(lists00str[4])
a5 =float(lists00str[5])
a6 =float(lists00str[6])
a7 =float(lists00str[7])
a8 =float(lists00str[8])
a9 =float(lists00str[9])
a10=float(lists00str[10])

listsCLUSTERstr=[]
listsCLUSTERstr=listCLUSTERstr.split(', ')
calc_Number=int(listsCLUSTERstr[0])
r_f        =int(listsCLUSTERstr[1])
r_w      =float(listsCLUSTERstr[2])
x_init     =int(listsCLUSTERstr[3])
x_end      =int(listsCLUSTERstr[4])

print(lists00str)
print(listsCLUSTERstr)

clientsocket.send(bytes("OK  Start ....", 'utf-8'))
clientsocket.close()
socket00.close()

if calc_Number == 2:
    initial_time = time.time()
    print(f"CPU is calculating now !")
    n=0
    calc_2s(n,r_f,r_w,x_init,x_end,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
    print(f"TIME :")
    print(str(time.time() - initial_time))
    print(f"ANSWER :")
    print(answerszero)

    socket00 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket00.connect(('192.168.2.20', 60021))######## Point 2 : Change only port to program NO ########
    Answerszerostr = str(answerszero)
    socket00.send(bytes(answerszerostr, 'utf-8'))
    msg = b''
    msg = socket00.recv(16)
    socket00.close()
    print(msg.decode("utf-8"))

time.sleep(10)
cluster2s-20total.py
import time
import threading
import socket

##Common (coefficient of 10th order equation)
list00 = [3628800.0, -10628640.0, 12753576.0, -8409500.0, 3416930.0, -902055.0, 157773.0, -18150.0, 1320.0, -55.0, 1.0]
##4 Raspberry Pi 4B
list21 = [2, 1000000, 0.01, 0, 3000001]
list22 = [2, 1000000, 0.01, 3000001, 6000001]
list23 = [2, 1000000, 0.01, 6000001, 9000001]
list24 = [2, 1000000, 0.01, 9000001, 12000001]

lists21 = []
lists21.append(list00)
lists21.append(list21)
lists22 = []
lists22.append(list00)
lists22.append(list22)
lists23 = []
lists23.append(list00)
lists23.append(list23)
lists24 = []
lists24.append(list00)
lists24.append(list24)

total = 0

##Totals for each Pi
totals21 = []
totals22 = []
totals23 = []
totals24 = []

def connectto_ipports(n):
    if n == 60021:
        print(n)
        socket21 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socket21.connect(('192.168.2.21', 60021))
        list21str=''
        list21str=str(lists21)
        socket21.send(bytes(list21str, 'utf-8'))
        msg21 = b''
        msg21 = socket21.recv(16)
        socket21.close()
        print(msg21.decode("utf-8"))
    elif n == 60022:
        print(n)
        socket22 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socket22.connect(('192.168.2.22', 60022))
        list22str=''
        list22str=str(lists22)
        socket22.send(bytes(list22str, 'utf-8'))
        msg22 = b''
        msg22 = socket22.recv(16)
        socket22.close()
        print(msg22.decode("utf-8"))
    elif n == 60023:
        print(n)
        socket23 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socket23.connect(('192.168.2.23', 60023))
        list23str=''
        list23str=str(lists23)
        socket23.send(bytes(list23str, 'utf-8'))
        msg23 = b''
        msg23 = socket23.recv(16)
        socket23.close()
        print(msg23.decode("utf-8"))
    elif n == 60024:
        print(n)
        socket24 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socket24.connect(('192.168.2.24', 60024))
        list24str=''
        list24str=str(lists24)
        socket24.send(bytes(list24str, 'utf-8'))
        msg24 = b''
        msg24 = socket24.recv(16)
        socket24.close()
        print(msg24.decode("utf-8"))

def accept_ports(n):
    if n == 60021:
        print(n)
        socket21 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socket21.bind(('192.168.2.20', 60021))
        socket21.listen(5)
        clientsocket21, address21 = socket21.accept()
        total21en = b''
        total21en = clientsocket21.recv(1016)
        total21str = total21en.decode("utf-8")
        totals21.append(total21str)
        print(total21str)
        clientsocket21.send(bytes("Thank you ......", 'utf-8'))
        clientsocket21.close()
        socket21.close()
    elif n == 60022:
        print(n)
        socket22 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socket22.bind(('192.168.2.20', 60022))
        socket22.listen(5)
        clientsocket22, address22 = socket22.accept()
        total22en = b''
        total22en = clientsocket22.recv(1016)
        total22str = total22en.decode("utf-8")
        totals22.append(total22str)
        print(total22str)
        clientsocket22.send(bytes("Thank you ......", 'utf-8'))
        clientsocket22.close()
        socket22.close()
    elif n == 60023:
        print(n)
        socket23 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socket23.bind(('192.168.2.20', 60023))
        socket23.listen(5)
        clientsocket23, address23 = socket23.accept()
        total23en = b''
        total23en = clientsocket23.recv(1016)
        total23str = total23en.decode("utf-8")
        totals23.append(total23str)
        print(total23str)
        clientsocket23.send(bytes("Thank you ......", 'utf-8'))
        clientsocket23.close()
        socket23.close()
    elif n == 60024:
        print(n)
        socket24 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socket24.bind(('192.168.2.20', 60024))
        socket24.listen(5)
        clientsocket24, address24 = socket24.accept()
        total24en = b''
        total24en = clientsocket24.recv(1016)
        total24str = total24en.decode("utf-8")
        totals24.append(total24str)
        print(total24str)
        clientsocket24.send(bytes("Thank you ......", 'utf-8'))
        clientsocket24.close()
        socket24.close()

threads = []

# Thread Client Start
for n in range(60021, 60025):
    thread = threading.Thread(target=connectto_ipports, args=(n,))
    thread.start()
    threads.append(thread)
# Wait Threads
for thread in threads:
    thread.join()
# Result Display
print("All Clusters Calculation Start")

threads.clear()

# Accept Thread Server Start
for n in range(60021, 60025):
    thread = threading.Thread(target=accept_ports, args=(n,))
    thread.start()
    threads.append(thread)
# Wait Threads
for thread in threads:
    thread.join()

# Result Display
print("Calculation Result:")
print(totals21)
print(totals22)
print(totals23)
print(totals24)

time.sleep(10) # for display

# cluster2s-20total.py fixed IP address 192.168.2.20 (Execute py last, start calculation)
# cluster2s-21.py fixed IP address 192.168.2.21 (Run py first and wait)
# cluster2s-22.py fixed IP address 192.168.2.22 (Run py first and wait)
# cluster2s-23.py fixed IP address 192.168.2.23 (Run py first and wait)
# cluster2s-24.py fixed IP address 192.168.2.24 (Run py first and wait)
##All OS is Raspberry Pi OS with desktop: 2020-12-02-raspios-buster-armhf.img

Thank you for watching until the end.

Next time, I plan to solve higher-order equations with multiple solutions. Also, since I agree with the purpose of Qiita and post it, I am free to copy or modify the published program. There are no copyright issues.

However, when using the Raspberry Pi 4B, a particularly large heat sink is required for the CPU. In the case of this program, where LAN communication is infrequent, the LAN chip does not get hot. However, if the calculation time continues, a considerable amount of power is used as can be seen from the intense heat generated by the CPU. The small black chip behind the power USB C type also gets hot, so you also need a fan flow.

Recommended Posts

Solving higher-order equations in a 4-unit cluster I (no multiple solutions)
Solve higher-order equations with integer type (no multiple solutions)
Solving higher-order equations in a 4-unit cluster I (no multiple solutions)
Solving higher-order equations with integer type (no multiple solution) Manager
Solve higher-order equations with integer type (no multiple solutions)
Solving higher-order equations with integer type (no multiple solution) Manager
I get a KeyError in pyclustering.xmeans