[PHP][MATEMATYKA][GFX] Progresywny rozkład różnic liczb pierwszych

O wszystkim i o niczym ...
Regulamin forum
Nie dyskutujemy na tematy polityczne, religijne i inne tego typu mogące prowadzić do kłótni na forum, od tego są inne "wyspecjalizowane fora".
Awatar użytkownika
j23
Expert
Expert
Posty: 506
Rejestracja: czwartek 08 paź 2015, 18:40

[PHP][MATEMATYKA][GFX] Progresywny rozkład różnic liczb pierwszych

Postautor: j23 » wtorek 21 lis 2023, 14:29

Jak porobić testy nowych funkcji graficznych (PHP8 i GdImage) w taki sposób, żeby przez zabawę poszła w ruch nauka (no a przynajmniej jej namiastka)?
No można np. spróbować wykonać wizualizację graficzną progresywnego rozkładu różnic kolejnych liczb pierwszych. O co chodzi... No liczby pierwsze, wiadomo, takie które dzielą się przez 1 i przez samą siebie, zwyczajowo zaczynają się od cyfry 3, a kończą tam gdzie... następuje granica maksymalnego wykorzystania dostępnej rozporządzalnej pamięci operacyjnej ;) - z tym ostanim oczywiście żartuję - (chyba) nie ma końca bo ciągną się w nieskończoność tak długo dopóki istnieje taka liczba która spełnia warunki... Czemu ludzie tracą na to czas? hmm.. ja robię to dla zabawy i dla testów sprzętowo-programowych, ale niektórzy matematycy mają ambicję, bo coś tam jakiś instytut czy fundacja jakaś ogłosiła nagrodę pieniężną, już nie wspominając o prestiżu dla matematyka, który wpadnie na niekonwencjonalny sposób wyznaczania liczb pierwszych i ogólnie odnalezienia jakiejś logiki w systemie w jakim te liczby są rozlokowane...
W każdym razie.. Testując najnowsze możliwości PHP8 ( funkcje do generowania plików graficznych, funkcje do rysowania pixel po pixelu, etc) pomyślałem sobie żeby taki oto algorytm zaimplementować co by to narysował rozkład kolejnych różnic (czyli wyników odejmowania) pomiędzy kolejnymi liczbami pierwszymi, a progresywny dlatego, że z tych róźnic co to już powstaną powstają kolejne różnice i kolejne róźnice i tak aż do zera (co ładnie pokazuje wykres - o czym zara.. )... Acha, te różnice w mojej wizji są traktowane jako wartości bezwzględne, a więc wszystko jest dodatnie co ładnie tworzy dwuwymiarową grafikę ( bo na inne wymiary póki co nie mam czasu ).
Ogólnie pseudo-kod-algorytm wygląda tak, że np.
1. Mamy liczby pierwsze np. pierwszych osiem liczb (dla ułatwienia):
[3] [5] [7] [11] [13] [17] [19] [23]
2. ...i teraz wyznaczamy między nimi różnice czyli tak:
LICZBY PIERWSZE =>    [3]  [5]  [7]  [11]  [13]  [17]  [19]  [23]
RÓŻNICE ETAP 1    =>       [2]  [2]  [4]    [2]    [4]    [2]    [4]
RÓŻNICE ETAP 2    =>          [0]  [2]   [2]    [2]    [2]    [2]
RÓŻNICE ETAP 3    =>             [2]   [0]   [0]    [0]    [0]
ETC...
ETC...
ETC...

3. Poza tym wszystkie "wolne przestrzenie" także wypełniamy zerami, bo domyślnie za zero będzie odpowiadał kolor czarny, bo z rozkładu wyszło że jest go prawie najwięcej, prawie, bo "zero" pod względem częstości występowania przynajmniej dla pierwszych 1000 liczb pierwszych występuje na drugim miejscu, a na pierwszym najczęściej występującą różnicą bezwzględną jest "2". Zresztą rozkład dla powyższych 8 pierwszych liczb przedstawia się następująco:
Największa bezwzględna wartość roznicy = 4
krotnosc_roznicy[0] = 39
krotnosc_roznicy[2] = 14
krotnosc_roznicy[4] = 3
Najczęściej występująca krotność to "0" a jej ilość = 39
Tyle statystyki i teorii...

4. W PHP8 rolę wykreślania wykresu realizuje poniższy kod php (kod jest trochę niechlujny, proszę mi wybaczyć, ale robię to w ramach testów, gdzie estetyka i efektywność kodu jest na drugim miejscu):

Kod: Zaznacz cały

<?php
/* funkcja sprawdzająca czy dana liczba jest liczbą pierwszą */
function is_prime_number($number)
        {
        if ($number < 2) { return false; }
        for ($h = 2; $h < $number; ++$h)
            {
            if ($number % $h == 0) { return false; }
            }
        return true;
}

/* wyznaczenie pierwszych 1000 liczb pierwszych i zapisanie do tablicy */
$licznik=1000;
$szer_max=$licznik;
$wys_max=$licznik;

// robimy dwuwymiarową tablicę 1000x1000 wypełnioną samymi zerami
// liczenie od 1
$tp = array_fill(1, $szer_max, array_fill(1, $wys_max, 0));

$liczba=3;
$szer=1;    $gfx_szer=$szer;
$wys=1;     $gfx_wys=$wys;

// wypełniamy liczbami pierwszymi tylko pierwszy rząd dla wys=1
for ($wys=1; $wys<=$wys_max; $wys++)
    {
    while ($licznik)
          {
          if (is_prime_number($liczba)==true)
             {
             $tp[$szer][$wys]=$liczba;
             $szer++;
             $licznik--;
             }
             $liczba++;
          }
    }

// liczenie różnic bezwzględnych przyrostowych, tzn. roznica = abs( n - (n+1) )
// pierwsze wyniki różnic rozpoczynają się od drugiego rzędu, dlatego "for ($wys=2; ..."
// składniki równania brane są zaś z rzędu pierwszego (poprzedniego) "$wys-1"
for ($wys=2; $wys<=$wys_max; $wys++)
    {
    for ($szer=1; $szer<=$szer_max-($wys-1); $szer++)
        {
        $roznica= abs( $tp[$szer][$wys-1] - $tp[$szer+1][$wys-1] );             
        $tp[$szer][$wys]=$roznica;
        }
    // wyznaczanie ostatniego elementu
    if ($szer==( $szer_max-($wys-1) ) ) { $tp[$szer][$wys]=0; }
    }
   
// analiza nr 1   
// jaka jest największa różnica między liczbami?
$najw_roznica=0;
for ($wys=2; $wys<=$wys_max; $wys++)
    {
    for ($szer=1; $szer<=$szer_max; $szer++)
        {
        if ($najw_roznica<$tp[$szer][$wys]) { $najw_roznica=$tp[$szer][$wys]; }
        }
    }

// analiza nr 2   
// krotnosc wystepowania roznic i wyznaczenie największej z wszystkich krotności
$krotnosc_roznicy = array_fill(0, $najw_roznica+1, 0);
$najw_krotnosc=0;
for ($wys=2; $wys<=$wys_max; $wys++)
    {
    for ($szer=1; $szer<=$szer_max; $szer++)
        {
        $krotnosc_roznicy[ $tp[$szer][$wys] ]++;
        if ( $najw_krotnosc<$krotnosc_roznicy[ $tp[$szer][$wys] ] )
           { $najw_krotnosc=$krotnosc_roznicy[ $tp[$szer][$wys] ]; }
        }
    }
   
// $tpgfx table - tablica dla reprezentacji graficznej
$gfx_szer_max   = $szer_max*2;
$gfx_wys_max    = $wys_max*2;
$tpgfx = array_fill(1, $gfx_szer_max, array_fill(1, $gfx_wys_max, 0));

// kopiowanie tablic i duplikowanie dwukierunkowe wartości dla t_gfx[][]
// analizowanie każdego elementu tablicy tp
for ($gfx_wys=1; $gfx_wys<=$gfx_wys_max; $gfx_wys++)
    {
    $wys= round($gfx_wys/2);
    for ($gfx_szer=1; $gfx_szer<=$gfx_szer_max; $gfx_szer++)
        {
        $szer= round($gfx_szer/2);
        if ($wys>1)
            {
            $tpgfx[$gfx_szer][$gfx_wys]=$tp[$szer][$wys];
            for ($i=1; $i<$wys; $i++)
                {                               
                $tpgfx[$i][$gfx_wys]=$tpgfx[$i+1][$gfx_wys];
                }
            }
            else
                {
                $tpgfx[$gfx_szer][$gfx_wys]=$tp[$szer][$wys];
                }
        }
    }

// przygotowanie wizualne tablicy (przesunięcie kolumn w prawo)
for ($gfx_wys=3; $gfx_wys<=$gfx_wys_max; $gfx_wys++)
    {
    for ($gfx_szer=$gfx_szer_max-2; $gfx_szer>=1; $gfx_szer--)
        {
        if ($gfx_szer==1)
           { $tpgfx[$gfx_szer][$gfx_wys]=0; }
           else
               {
               $tpgfx[$gfx_szer+1][$gfx_wys]=$tpgfx[$gfx_szer][$gfx_wys];
               }
        }       
    }     

// test - wypisanie tablicy gfx w wersji graficznej   
$szer_obrazka = $gfx_szer_max;
$wys_obrazka = $gfx_wys_max;
$gd = imagecreatetruecolor($szer_obrazka, $wys_obrazka);
$r=0;
$g=0;
$b=0;
for ($gfx_wys=2; $gfx_wys<=$gfx_wys_max; $gfx_wys++)
    {
    for ($gfx_szer=1; $gfx_szer<=$gfx_szer_max; $gfx_szer++)
        {       
        if ( $tpgfx[$gfx_szer][$gfx_wys]==0 )
           { 
           $r = 0; $g = 0; $b = 0;
           }
           else
               {
               $mnoznik = (((( $krotnosc_roznicy[ $tpgfx[$gfx_szer][$gfx_wys] ] ) /3 ) *100 ) /$najw_krotnosc ) /100;
               $rgb_switch = ($tpgfx[$gfx_szer][$gfx_wys]) % 3;
               switch ($rgb_switch)
                       {
                       case 1: { $r = (int)( 255 * $mnoznik );
                                 $g = (int)( 255 * $mnoznik );
                                 $b = (int)( 255 - ( 255 * $mnoznik ) );
                                } break;
                       case 2: { $r = (int)( 255 * $mnoznik );
                                 $g = (int)( 255 - ( 255 * $mnoznik ) );
                                 $b = (int)( 255 * $mnoznik );
                                } break;
                       case 3: { $r = (int)( 255 - ( 255 * $mnoznik ) );
                                 $g = (int)( 255 * $mnoznik );
                                 $b = (int)( 255 * $mnoznik );
                                } break;
                       }
                }               
        $color_set_to = imagecolorallocate($gd, $r, $g, $b);
        imagesetpixel($gd, $gfx_szer, $gfx_wys, $color_set_to);
        //echo '['.$r.':'.$g.':'.$b.']&nbsp&nbsp';
        }
    //echo '<br>';
    }   
header('Content-Type: image/png');
imagepng($gd);
imagedestroy($gd);
?>


A oto obrazek jaki z niego powstaje (wykres)...
testy_pierw_gfx_05.png


Może ktoś dostrzeże w tym jakąś logikę... kto wie... Niech mu będzie na zdrowie. :like:

Ja póki co widzę piękno matematyki i Art Deco 8-)
Pozdrawiam! Jarek

Edit_1: Mam świadomość, że w kodzie PHP nie ma komentarzy w starej konwencji programistów czyli linia komentarza do linii kodu, ale z drugiej strony gdybym tak każdą jedną linią komentował to nieco "zaciemniłbym" i wydłużył cały listing kodu, więc skupiłem się nad tym, żeby zmienne były względnie jasno zdefiniowane i nazwane w sposób możliwie najbardziej zbliżony do roli jaką mają pełnić. Dla mnie ten kod jest jasny, ale jeżeli Ktoś z Koleżanek lub Kolegów Forum Microgeek ma pytania co do którejś linii (jakiekolwiek niejasności) to proszę pytać. O ile nie wkroczy to za bardzo w zakres matematyki wyższej (i w tematykę której nie rozumiem) to z chęcią odpowiem na wszelkie pytania, a przynajmniej postaram się.

P.S. Algorytm wyznaczania liczb pierwszych zaczerpnąłem ze strony:
http://www.capaciouscore.pl/artykuly/sito-eratostenesa-czyli-algorytm-w-php-do-wyznaczania-liczb-pierwszych/
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Internet łączy ludzi, którzy dzielą się swoimi zainteresowaniami, pomysłami i potrzebami, bez względu na geograficzne (przeciwności).
BOB TAYLOR, PARC

Awatar użytkownika
piotrek
User
User
Posty: 155
Rejestracja: niedziela 05 lis 2017, 02:46

Re: [PHP][MATEMATYKA][GFX] Progresywny rozkład różnic liczb pierwszych

Postautor: piotrek » czwartek 04 sty 2024, 13:20

Co do porządku rozkładu LP, dotyczy tego w jakiś sposób hipoteza Riemanna, jeden z największych nierozwiązanych jeszcze problemów matematyki.
Krótko mówiąc wykres funkcji liczby liczb pierwszych mniejszych od x ma postać schodków i bardzo przypomina kształtem funkcję logarytmiczną.
Podobieństwo jest znaczne ale nie jest znany sposób w jaki sposób wyznaczać kolejne liczby pierwsze w krótkim czasie.
Wykorzystując metody jakie udostępnia analiza matematyczna, transformata Fouriera Riemann uzyskał słynną funkcję dzeta, której miejsca zerowe są szczególnie interesujące w dziedzinie teorii liczb.


Wróć do „Hyde Park”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 3 gości