次元堂

思い込みで数学してます

コラッツ予想 構造体 Python

Pythonを使ったコラッツ予想の視える化・動く化、その4弾
Pythonプログラミングで学んだこと
'numpy array'は'append','extend'ができない
そこで、'numpy array'を'list'に変換する
'.tolist()'を作用させればできる
numpy.linspace(int(Start),int(End),int(num)).tolist()


「コラッツ数列の構造」を知りたくて挑戦してきた
たどり着いたのが「らせん構造」
”次元”、”視点”、”時間”の3点セットで表現すると、全体を把握した気になれる
私は斜めに駆け上がるところが好きですね

コラッツ予想の視覚化と動画化

Pythonを使ったコラッツ予想の視える化・動く化、その3弾
プログラムテクニックも少しは向上した(と思う)
前回は視点を動かすことにより動画を構築した
今回はオブジェクトと視点を同時に動かす手法にもトライした

「次元堂の回答」の肝、コラッツ数列の再構築をアップする
コラッツ数列は全自然数に対して成り立つ
しかし偶数はいずれ奇数に写像されるので、省略可能である
「次元堂の回答」ではただ単に偶数を省略するのではなく、ある部分では奇数を追加している
この数列は縦の系列4n+2(逆順)、横の系列(2n+1)/2又は4n/3(逆順)で表すことができる
そのため、系統的な検討が可能になる

コラッツ問題 次元堂の回答 導入 Pythonで3D

 コラッツ問題;次元堂の回答を題材にPythonプログラミングを訓練中です。
 「自然数において、奇数は3倍して1を足し、偶数は2で割る。これを繰り返すと1になる。」というコラッツ予想を3Dグラフィックスにしてみました。
 GIFファイルとすることで、動画としてアップできました。
 このプログラムは、まず3D空間に固定した絵を描きます。
 その後視点を移動させることによって動画としました。
 例として、27を最初は選びました。
 再生時間は1分近くかかり、途中で飽きてしまいました。
 もう少し短く終わる数を選んでいます。
  

コラッツ問題 JIGENDHOの回答 3Dプログラミング with Python

Pythonを始めた;2023年11月2日

Python , Jupyter, Numpey, Pandas, Scipy, Matplotlib,

・・・訳も分からずインストールする一週間

わけあって無料のPyton e-Learning、数講座受けた二週間

class, for文, while文, if文, List, Matplotlib,・・・部品を試した一週間

JIGENDHOの回答、3Dプログラミングの一週間

めでたく完成;2023年12月6日

 

jigendho.hatenablog.com

 

JIGENDHOの回答3D



scriptを掲載する

よかったら自分のPCで試してほしい

※JIGENDHOの回答のアドレスをscript中に記載した、参照されたし

※掲載の記事に[]が反映されない部分がある

  Cell In[5], line 428
    CCLD=
         ^
SyntaxError: invalid syntax

このような場合CCLD=[](半角)としてほしい

ここでは反映の都合上全角で記載

 

# Collatz prediction
# コラッツ問題Jigendho回答のコラッツ構造体を3D化する
# その構造体はPillarとBeamで構成される
# PillarはHeaderおよびそれにつづく要素によって形成される
# その要素に4を乗算して 2を加算し次の要素が展開する
# BeamはHeaderを除くPillarの各要素から展開する
# その要素を3で割ったあまりによって3つの展開パターンをとる
# 余りが0のときの次の要素はこの要素を3で割って4倍する
# 余りが1のときは次の要素に展開しない
# 余りが2のときの次の要素はこの要素を2倍して1を引き3で割る
# 各要素は円柱座標系にプロットされる
# 高さは次の2つの条件で1上昇する
# Headerから次の要素に展開するとき
# Pillar要素からBeam要素に展開するとき
# 偏角はその要素の対数の大きさによって与えられる
# 距離はその要素の大きさによって与えられる
# https://jigendho.hatenablog.com/entry/2023/10/10/184313?_gl=1*gf1x80*_gcl_au*MTE1MDA4NjI2NS4xNjk5NTI2OTU1

# Parameters
ElapsedTimes=4   # Elapsed Times
# Pillar展開、Beam展開を1経過とする
# パラメータは展開数を表す

DCM='hsv'        # Data Color map
# 各要素のカラーマップを表す

PCM='Wistia'     # Pillar Color map
# Pillar展開のカラーマップを表す

BCM='hsv'        # Beam Color map
# Beam展開のカラーマップを表す

# それぞれ指標はElapsedTimesとする
# Color map; 
            # 'Wistia',
            # 'seismic',
            # 'YlGn',
            # 'hsv',
            # 'PuRd'

# Import Packages
import numpy as np
from fractions import Fraction
import pprint as ppr
import matplotlib.pyplot as plt

# ----Generate mapping for each pillar and beam------------------------
# pillar及びbeamを展開するクラス
# インスタンス化するクラスとそれを継承したクラス群で構成されている
# 引数は元要素、元高さ、元展開
# 戻り値は次の要素、次の高さ、次の展開、展開記号
# https://jigendho.hatenablog.com/entry/2023/10/10/184313?_gl=1*gf1x80*_gcl_au*MTE1MDA4NjI2NS4xNjk5NTI2OTU1

# Class; Mapping
# Version; V03.3
# Methods; Beam, BeamOrg, BeamCr, BeamStp, BeamStO, BeamAll,
#          Pillar, PillarOrg, PillarCr, PillarStp, PillarStO, PillarAll

# Class Mapping
class Mapping:
    def __init__(self, anm1, StepV, Prgrss):
        self.anm1 = anm1
        self.StepV = StepV
        self.Prgrss = Prgrss
    def mapping(self):
        pass
        
# Method Beam
class Beam(Mapping):
    def mapping(self):
        if self.anm1 % 3==0:
            return int(Fraction(4*self.anm1,3))
        elif self.anm1 % 3==2:
            return int(Fraction(2*self.anm1-1,3)) 
        else:
            pass
            
# Method BeamOrg            
class BeamOrg(Mapping):
    def mapping(self):
        if self.anm1 % 3==0:
            return int(self.anm1)
        elif self.anm1 % 3==2:
            return int(self.anm1) 
        else:
            pass

# Method BeamCr
class BeamCr(Mapping):
    def mapping(self):
        if self.anm1 % 3==0:
            return "c"
        elif self.anm1 % 3==2:
            return "d"
        else:
            pass

# Method BeamStp
class BeamStp(Mapping):
    def mapping(self):
        if self.anm1 % 3==1:
            pass
        else:
            if self.anm1 % 4==2:
                return int(self.StepV+1)     
            else:
                return int(self.StepV)

# Method BeamStO
class BeamStO(Mapping):
    def mapping(self):
        if self.anm1 % 3==1:
            pass
        else:
            return int(self.StepV)     

                
# Method BeamAll
class BeamAll(Mapping):
    def mapping(self):
        if self.anm1 % 3==0:
            if self.anm1 % 4==2:
                return ([int(Fraction(4*self.anm1,3)),
                         self.anm1,
                         "c", 
                         int(self.StepV+1),
                         int(self.StepV),
                         self.Prgrss+1]
                       )
            else:
                return ([int(Fraction(4*self.anm1,3)),
                         self.anm1,
                         "c",
                         int(self.StepV),
                         int(self.StepV),
                         self.Prgrss+1]
                       )
        elif self.anm1 % 3==2:
            if self.anm1 % 4==2:
                return ([int(Fraction(2*self.anm1-1,3)),
                         self.anm1,
                         "d",
                         int(self.StepV+1),
                         int(self.StepV),
                         self.Prgrss+1]
                       ) 
            else:
                return ([int(Fraction(2*self.anm1-1,3)),
                         self.anm1,
                         "d",
                         int(self.StepV),
                         int(self.StepV),
                         self.Prgrss+1]
                       )
        else:
            pass

# Method Pillar
class Pillar(Mapping):
    def mapping(self):
        return 4*self.anm1+2
        
# Method PillarOrg
class PillarOrg(Mapping):
    def mapping(self):
        return int(self.anm1)
        
# Method PillarCr
class PillarCr(Mapping):
    def mapping(self):
        return "b"

# Method PillarStp
class PillarStp(Mapping):
    def mapping(self):
        if self.anm1 % 4==2:
            return int(self.StepV)     
        else:
            return int(self.StepV+1)

# Method PillarStO
class PillarStO(Mapping):
    def mapping(self):
        return int(self.StepV)     
            
# Method PillarAll
class PillarAll(Mapping):
    def mapping(self):
        if self.anm1 % 4==2:
            return ([4*self.anm1+2,self.anm1,
                     "b",
                     int(self.StepV), int(self.StepV),
                     self.Prgrss+1])     
        else:
            return ([4*self.anm1+2,self.anm1,
                     "b",
                     int(self.StepV+1), int(self.StepV),
                     self.Prgrss+1])
            
# ----Polar coordinate representation of pillars and beams-------------
# 極座標系への変換クラス
# インスタンス化するクラスとそれを継承したクラス群で構成されている
# 各パラメータは配列である
# 引数は次の要素と元の要素、展開記号、各高さ、次の展開
# 戻り値は元の要素の極座標、次の要素の極座標
# https://jigendho.hatenablog.com/entry/2023/10/10/184313?_gl=1*gf1x80*_gcl_au*MTE1MDA4NjI2NS4xNjk5NTI2OTU1


# Class; CollCon2
# Version; V02.0
# Methods; EndValue,StartValue,"character",EndStep,StartStep,ProgressV

class CollCon2:
    def __init__(self,
                 EndValue,
                 StartValue,
                 MapChar,
                 EndStep,
                 StartStep,
                 ProgressV
                ):
        
        self.EV = EndValue
        self.SV = StartValue
        self.MC = MapChar
        self.ES = EndStep
        self.SS = StartStep
        self.PV = ProgressV
        
    def CollCon2(self):
        pass

class EndPosi(CollCon2):
    def CollCon2(self):
        return ([[
            self.EV*np.cos(2*np.pi*(np.log(self.EV+2/3)/np.log(4))),
            self.EV*np.sin(2*np.pi*(np.log(self.EV+2/3)/np.log(4))),
            self.ES,
            self.PV,
        ]])

class StartPosi(CollCon2):
    def CollCon2(self):
        return ([          
            self.SV*np.cos(2*np.pi*(np.log(self.SV+2/3)/np.log(4))),
            self.SV*np.sin(2*np.pi*(np.log(self.SV+2/3)/np.log(4))),
            self.SS,
            self.PV,
            ])

class AuxiliaryPosi(CollCon2):
    def CollCon2(self):
        ALPosi=
        if self.MC != "b":
            for AL in np.linspace(self.SV, self.EV, 10):     
                ALPosi.append([
                self.EV*np.cos(2*np.pi*(np.log(AL+2/3)/np.log(4))),
                self.EV*np.sin(2*np.pi*(np.log(AL+2/3)/np.log(4))),
                self.ES,
                self.PV,
                ])
            return ALPosi
        else:
            pass

        
# ----Negative mapping data generation----------------------------------
# Class Mappingの戻り値から1経過分の要素データ配列を生成する
# https://jigendho.hatenablog.com/entry/2023/10/10/184313?_gl=1*gf1x80*_gcl_au*MTE1MDA4NjI2NS4xNjk5NTI2OTU1

# Collatz prediction

anNum=[0]                  # Natural number
anOrg=[0]                  # Original Natural number
anCr=[0]                   # Character
anStp=[0]                  # Step 
anStO=[0]                  # Step Original
anAll=[[0,0," ",0,0,0]]    # All data

anStIndx=0
anEnIndx=0
anIndCoun=0

for anPrg in range(ElapsedTimes):

    for PrtCoun in range(anStIndx,anEnIndx+1):
            
        # Pillar operation        
        anNum.append(Pillar(anNum[PrtCoun],
                            anStp[PrtCoun],
                            anPrg
                           ).mapping())
        
        anOrg.append(PillarOrg(anNum[PrtCoun],
                               anStp[PrtCoun],
                               anPrg
                              ).mapping())
        
        anCr.append(PillarCr(anNum[PrtCoun],
                             anStp[PrtCoun],
                             anPrg
                            ).mapping())
        
        anStp.append(PillarStp(anNum[PrtCoun],
                               anStp[PrtCoun],
                               anPrg
                              ).mapping())
        
        anStO.append(PillarStO(anNum[PrtCoun],
                               anStp[PrtCoun],
                               anPrg
                              ).mapping())
        
        anAll.append(PillarAll(anNum[PrtCoun],
                               anStp[PrtCoun],
                               anPrg
                              ).mapping())

        anIndCoun+=1

        while anNum[anIndCoun] != None:
            if (Beam(anNum[anIndCoun],
                     anStp[anIndCoun],
                     anPrg
                    ).mapping() == None):
                break
                
            # Beam operation
            anNum.append(Beam(anNum[anIndCoun],
                              anStp[anIndCoun],
                              anPrg
                             ).mapping())
            
            anOrg.append(BeamOrg(anNum[anIndCoun],
                                 anStp[anIndCoun],
                                 anPrg
                                ).mapping())
            
            anCr.append(BeamCr(anNum[anIndCoun],
                               anStp[anIndCoun],
                               anPrg
                              ).mapping())
            
            anStp.append(BeamStp(anNum[anIndCoun],
                                 anStp[anIndCoun],
                                 anPrg
                                ).mapping())
            
            anStO.append(BeamStO(anNum[anIndCoun],
                                 anStp[anIndCoun],
                                 anPrg
                                ).mapping())
            
            anAll.append(BeamAll(anNum[anIndCoun],
                                 anStp[anIndCoun],
                                 anPrg
                                ).mapping())
            
            anIndCoun+=1
            
            if (anIndCoun ==100000):
                print("b")
                break
                
    anStIndx=anEnIndx+1             # Next anStInd        
    anEnIndx=anIndCoun              # Next anEnIndx

aVlue=anAll

# ----Psition Date-------------------------------------------------------
# 各要素の極座標データを配列にまとめる
# https://jigendho.hatenablog.com/entry/2023/10/10/184313?_gl=1*gf1x80*_gcl_au*MTE1MDA4NjI2NS4xNjk5NTI2OTU1

CCPD=         
for i in range(1,len(aVlue)-1):
    CCPD.extend(EndPosi(*aVlue[i]).CollCon2())      
    
# ----Line Date----------------------------------------------------------
# 元要素と次の要素の繋がりの極座標データを経過単位で配列にまとめる
# https://jigendho.hatenablog.com/entry/2023/10/10/184313?_gl=1*gf1x80*_gcl_au*MTE1MDA4NjI2NS4xNjk5NTI2OTU1

CCLD=
for i in range(1,len(aVlue)-1):
    CCLD=[StartPosi(*aVlue[i]).CollCon2()]
    if aVlue[i][2]!='b':                
        CCLD.extend(AuxiliaryPosi(*aVlue[i]).CollCon2())
    else:
        CCLD.extend(EndPosi(*aVlue[i]).CollCon2())

# ----Psition data plot--------------------------------------------------
# 3Dプロット;枠の作成、各要素のプロット
# https://jigendho.hatenablog.com/entry/2023/10/10/184313?_gl=1*gf1x80*_gcl_au*MTE1MDA4NjI2NS4xNjk5NTI2OTU1

%matplotlib tk

xPs=[0]
yPs=[0]
zPs=[0]
Prg=[0]
for id in range(len(CCPD)):
    xPs.append(CCPD[id][0])
    yPs.append(CCPD[id][1])
    zPs.append(CCPD[id][2])
    Prg.append(CCPD[id][3])
    
fig=plt.figure()
ax=fig.add_subplot(projection="3d")

mappable = ax.scatter(
    xPs,yPs,zPs,
    c=Prg,
    vmin=0, vmax=max(Prg),
    s=5,
    cmap=plt.colormaps[DCM]   
)

fig.colorbar(mappable, ax=ax)


# ----Line date generate and plotte--------------------------------------
# 経過のプロット
# https://jigendho.hatenablog.com/entry/2023/10/10/184313?_gl=1*gf1x80*_gcl_au*MTE1MDA4NjI2NS4xNjk5NTI2OTU1

color_map_b = plt.get_cmap(PCM)
color_map_cd = plt.get_cmap(BCM)

for i in range(1,len(aVlue)-1):
    CCLD=
    xLn=
    yLn=

    zLn= []
    CCLD=[StartPosi(*aVlue[i]).CollCon2()]
    if aVlue[i][2]!='b':                
        CCLD.extend(AuxiliaryPosi(*aVlue[i]).CollCon2())
        CCLD.extend(EndPosi(*aVlue[i]).CollCon2())
        for il in range(0,len(CCLD)):
            xLn.append(CCLD[il][0])
            yLn.append(CCLD[il][1])
            zLn.append(CCLD[il][2])        
        ax.plot(xLn,yLn,zLn,
                color=color_map_cd(CCLD[0][3]/(max(Prg))),
                linewidth=1,alpha=0.5) 
    else:
        CCLD.extend(EndPosi(*aVlue[i]).CollCon2())
    
        for il in range(0,len(CCLD)):
            xLn.append(CCLD[il][0])
            yLn.append(CCLD[il][1])
            zLn.append(CCLD[il][2])
        ax.plot(xLn,yLn,zLn,
                color=color_map_b(CCLD[0][3]/(max(Prg))),
                linewidth=1) 
        
plt.show()