kececinumbers 0.6.3__py3-none-any.whl → 0.6.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kececinumbers/__init__.py +18 -1
- kececinumbers/_version.py +1 -1
- kececinumbers/kececinumbers.py +445 -0
- {kececinumbers-0.6.3.dist-info → kececinumbers-0.6.5.dist-info}/METADATA +4 -2
- kececinumbers-0.6.5.dist-info/RECORD +10 -0
- kececinumbers-0.6.3.dist-info/RECORD +0 -10
- {kececinumbers-0.6.3.dist-info → kececinumbers-0.6.5.dist-info}/WHEEL +0 -0
- {kececinumbers-0.6.3.dist-info → kececinumbers-0.6.5.dist-info}/licenses/LICENSE +0 -0
- {kececinumbers-0.6.3.dist-info → kececinumbers-0.6.5.dist-info}/top_level.txt +0 -0
kececinumbers/__init__.py
CHANGED
@@ -22,7 +22,7 @@ import warnings
|
|
22
22
|
# importlib.reload(kececinumbers) # F821 undefined name 'kececinumbers'
|
23
23
|
|
24
24
|
# Paket sürüm numarası
|
25
|
-
__version__ = "0.6.
|
25
|
+
__version__ = "0.6.5"
|
26
26
|
__author__ = "Mehmet Keçeci"
|
27
27
|
__email__ = "mkececi@yaani.com"
|
28
28
|
|
@@ -42,6 +42,14 @@ __all__ = [
|
|
42
42
|
'_get_integer_representation',
|
43
43
|
'_parse_quaternion_from_csv',
|
44
44
|
'generate_kececi_vectorial',
|
45
|
+
'_plot_comparison',
|
46
|
+
'_find_kececi_zeta_zeros',
|
47
|
+
'_compute_gue_similarity',
|
48
|
+
'_load_zeta_zeros',
|
49
|
+
'analyze_all_types',
|
50
|
+
'analyze_pair_correlation',
|
51
|
+
'_gue_pair_correlation',
|
52
|
+
'_pair_correlation',
|
45
53
|
|
46
54
|
# --- Core Generation and Analysis ---
|
47
55
|
'unified_generator',
|
@@ -95,6 +103,15 @@ try:
|
|
95
103
|
find_kececi_prime_number,
|
96
104
|
plot_numbers,
|
97
105
|
print_detailed_report,
|
106
|
+
_plot_comparison,
|
107
|
+
_find_kececi_zeta_zeros,
|
108
|
+
_compute_gue_similarity,
|
109
|
+
_load_zeta_zeros,
|
110
|
+
analyze_all_types,
|
111
|
+
analyze_pair_correlation,
|
112
|
+
_gue_pair_correlation,
|
113
|
+
_pair_correlation,
|
114
|
+
|
98
115
|
|
99
116
|
# Constants
|
100
117
|
TYPE_POSITIVE_REAL,
|
kececinumbers/_version.py
CHANGED
kececinumbers/kececinumbers.py
CHANGED
@@ -39,6 +39,9 @@ import numpy as np
|
|
39
39
|
import quaternion
|
40
40
|
import random
|
41
41
|
import re
|
42
|
+
from scipy.fft import fft, fftfreq
|
43
|
+
from scipy.signal import find_peaks
|
44
|
+
from scipy.stats import ks_2samp
|
42
45
|
import sympy
|
43
46
|
from typing import Any, Dict, List, Optional, Tuple
|
44
47
|
|
@@ -544,6 +547,448 @@ def _parse_quaternion_from_csv(s: str) -> np.quaternion:
|
|
544
547
|
except (ValueError, IndexError) as e:
|
545
548
|
raise ValueError(f"Geçersiz virgülle ayrılmış kuaterniyon formatı: '{s}'.") from e
|
546
549
|
|
550
|
+
def _load_zeta_zeros(filename="zeta.txt"):
|
551
|
+
"""
|
552
|
+
Loads Riemann zeta zeros from a text file.
|
553
|
+
Each line should contain one floating-point number representing the imaginary part of a zeta zero.
|
554
|
+
Lines that are empty or start with '#' are ignored.
|
555
|
+
Returns:
|
556
|
+
numpy.ndarray: Array of zeta zeros, or empty array if file not found.
|
557
|
+
"""
|
558
|
+
try:
|
559
|
+
with open(filename, 'r', encoding='utf-8') as file:
|
560
|
+
lines = file.readlines()
|
561
|
+
zeta_zeros = []
|
562
|
+
for line in lines:
|
563
|
+
line = line.strip()
|
564
|
+
if not line or line.startswith("#"):
|
565
|
+
continue
|
566
|
+
try:
|
567
|
+
zeta_zeros.append(float(line))
|
568
|
+
except ValueError:
|
569
|
+
print(f"Invalid line skipped: {line}")
|
570
|
+
print(f"{len(zeta_zeros)} zeta zeros loaded.")
|
571
|
+
return np.array(zeta_zeros)
|
572
|
+
except FileNotFoundError:
|
573
|
+
print(f"'{filename}' not found.")
|
574
|
+
return np.array([])
|
575
|
+
|
576
|
+
|
577
|
+
def _compute_gue_similarity(sequence, tolerance=0.5):
|
578
|
+
"""
|
579
|
+
Measures how closely the frequency spectrum of a Keçeci sequence matches the GUE (Gaussian Unitary Ensemble) statistics.
|
580
|
+
Uses Kolmogorov-Smirnov test against Wigner-Dyson distribution.
|
581
|
+
Args:
|
582
|
+
sequence (list): The Keçeci number sequence.
|
583
|
+
tolerance (float): Not used here; kept for interface consistency.
|
584
|
+
Returns:
|
585
|
+
tuple: (similarity_score, p_value)
|
586
|
+
"""
|
587
|
+
from . import _get_integer_representation
|
588
|
+
|
589
|
+
values = [val for z in sequence if (val := _get_integer_representation(z)) is not None]
|
590
|
+
if len(values) < 10:
|
591
|
+
return 0.0, 0.0
|
592
|
+
|
593
|
+
values = np.array(values) - np.mean(values)
|
594
|
+
N = len(values)
|
595
|
+
powers = np.abs(fft(values))**2
|
596
|
+
freqs = fftfreq(N)
|
597
|
+
|
598
|
+
mask = (freqs > 0)
|
599
|
+
freqs_pos = freqs[mask]
|
600
|
+
powers_pos = powers[mask]
|
601
|
+
|
602
|
+
if len(powers_pos) == 0:
|
603
|
+
return 0.0, 0.0
|
604
|
+
|
605
|
+
peaks, _ = find_peaks(powers_pos, height=np.max(powers_pos)*1e-7)
|
606
|
+
strong_freqs = freqs_pos[peaks]
|
607
|
+
|
608
|
+
if len(strong_freqs) < 2:
|
609
|
+
return 0.0, 0.0
|
610
|
+
|
611
|
+
# Scale so the strongest peak aligns with the first Riemann zeta zero
|
612
|
+
peak_freq = strong_freqs[np.argmax(powers_pos[peaks])]
|
613
|
+
scale_factor = 14.134725 / peak_freq
|
614
|
+
scaled_freqs = np.sort(strong_freqs * scale_factor)
|
615
|
+
|
616
|
+
# Compute level spacings
|
617
|
+
if len(scaled_freqs) < 2:
|
618
|
+
return 0.0, 0.0
|
619
|
+
diffs = np.diff(scaled_freqs)
|
620
|
+
if np.mean(diffs) == 0:
|
621
|
+
return 0.0, 0.0
|
622
|
+
diffs_norm = diffs / np.mean(diffs)
|
623
|
+
|
624
|
+
# Generate GUE sample using Wigner-Dyson distribution
|
625
|
+
def wigner_dyson(s):
|
626
|
+
return (32 / np.pi) * s**2 * np.exp(-4 * s**2 / np.pi)
|
627
|
+
|
628
|
+
s_gue = np.linspace(0.01, 3.0, 1000)
|
629
|
+
p_gue = wigner_dyson(s_gue)
|
630
|
+
p_gue = p_gue / np.sum(p_gue)
|
631
|
+
sample_gue = np.random.choice(s_gue, size=1000, p=p_gue)
|
632
|
+
|
633
|
+
# Perform KS test
|
634
|
+
ks_stat, ks_p = ks_2samp(diffs_norm, sample_gue)
|
635
|
+
similarity_score = 1.0 - ks_stat
|
636
|
+
|
637
|
+
return similarity_score, ks_p
|
638
|
+
|
639
|
+
|
640
|
+
def _find_kececi_zeta_zeros(sequence, tolerance=0.5):
|
641
|
+
"""
|
642
|
+
Estimates the zeros of the Keçeci Zeta Function from the spectral peaks of the sequence.
|
643
|
+
Compares them to known Riemann zeta zeros.
|
644
|
+
Args:
|
645
|
+
sequence (list): The Keçeci number sequence.
|
646
|
+
tolerance (float): Maximum distance for a match between Keçeci and Riemann zeros.
|
647
|
+
Returns:
|
648
|
+
tuple: (list of Keçeci zeta zeros, matching score)
|
649
|
+
"""
|
650
|
+
from . import _get_integer_representation
|
651
|
+
|
652
|
+
values = [val for z in sequence if (val := _get_integer_representation(z)) is not None]
|
653
|
+
if len(values) < 10:
|
654
|
+
return [], 0.0
|
655
|
+
|
656
|
+
values = np.array(values) - np.mean(values)
|
657
|
+
N = len(values)
|
658
|
+
powers = np.abs(fft(values))**2
|
659
|
+
freqs = fftfreq(N)
|
660
|
+
|
661
|
+
mask = (freqs > 0)
|
662
|
+
freqs_pos = freqs[mask]
|
663
|
+
powers_pos = powers[mask]
|
664
|
+
|
665
|
+
if len(powers_pos) == 0:
|
666
|
+
return [], 0.0
|
667
|
+
|
668
|
+
peaks, _ = find_peaks(powers_pos, height=np.max(powers_pos)*1e-7)
|
669
|
+
strong_freqs = freqs_pos[peaks]
|
670
|
+
|
671
|
+
if len(strong_freqs) < 2:
|
672
|
+
return [], 0.0
|
673
|
+
|
674
|
+
# Scale so the strongest peak aligns with the first Riemann zeta zero
|
675
|
+
peak_freq = strong_freqs[np.argmax(powers_pos[peaks])]
|
676
|
+
scale_factor = 14.134725 / peak_freq
|
677
|
+
scaled_freqs = np.sort(strong_freqs * scale_factor)
|
678
|
+
|
679
|
+
# Find candidate zeros by analyzing the Keçeci Zeta Function
|
680
|
+
t_vals = np.linspace(0, 650, 10000)
|
681
|
+
zeta_vals = np.array([sum((scaled_freqs + 1e-10)**(- (0.5 + 1j * t))) for t in t_vals])
|
682
|
+
minima, _ = find_peaks(-np.abs(zeta_vals), height=-0.5*np.max(np.abs(zeta_vals)), distance=5)
|
683
|
+
kececi_zeta_zeros = t_vals[minima]
|
684
|
+
|
685
|
+
# Load Riemann zeta zeros for comparison
|
686
|
+
zeta_zeros_imag = _load_zeta_zeros("zeta.txt")
|
687
|
+
if len(zeta_zeros_imag) == 0:
|
688
|
+
return kececi_zeta_zeros, 0.0
|
689
|
+
|
690
|
+
# Calculate matching score
|
691
|
+
close_matches = [kz for kz in kececi_zeta_zeros if min(abs(kz - zeta_zeros_imag)) < tolerance]
|
692
|
+
score = len(close_matches) / len(kececi_zeta_zeros) if kececi_zeta_zeros.size > 0 else 0.0
|
693
|
+
|
694
|
+
return kececi_zeta_zeros, score
|
695
|
+
|
696
|
+
|
697
|
+
def analyze_all_types(iterations=120):
|
698
|
+
"""
|
699
|
+
Performs automated analysis on all 11 Keçeci number types.
|
700
|
+
For each type, it tests multiple parameter sets, computes similarity to Riemann zeta zeros and GUE statistics,
|
701
|
+
then reports and plots the results.
|
702
|
+
Args:
|
703
|
+
iterations (int): Number of Keçeci steps to generate for each sequence.
|
704
|
+
Returns:
|
705
|
+
tuple: (sorted_by_zeta, sorted_by_gue) - Lists of results sorted by performance.
|
706
|
+
"""
|
707
|
+
from . import (
|
708
|
+
get_with_params,
|
709
|
+
TYPE_POSITIVE_REAL,
|
710
|
+
TYPE_NEGATIVE_REAL,
|
711
|
+
TYPE_COMPLEX,
|
712
|
+
TYPE_FLOAT,
|
713
|
+
TYPE_RATIONAL,
|
714
|
+
TYPE_QUATERNION,
|
715
|
+
TYPE_NEUTROSOPHIC,
|
716
|
+
TYPE_NEUTROSOPHIC_COMPLEX,
|
717
|
+
TYPE_HYPERREAL,
|
718
|
+
TYPE_BICOMPLEX,
|
719
|
+
TYPE_NEUTROSOPHIC_BICOMPLEX
|
720
|
+
)
|
721
|
+
|
722
|
+
print("Automated Analysis for 11 Keçeci Types")
|
723
|
+
print("=" * 80)
|
724
|
+
|
725
|
+
include_intermediate = True
|
726
|
+
results = []
|
727
|
+
|
728
|
+
# Parameter sets to test
|
729
|
+
param_sets = [
|
730
|
+
('0.0', '9.0'),
|
731
|
+
('1.0', '7.0'),
|
732
|
+
('2.0', '5.0'),
|
733
|
+
('3.0', '11.0'),
|
734
|
+
('1+1j', '9.0'),
|
735
|
+
('0.0001412', '0.037')
|
736
|
+
]
|
737
|
+
|
738
|
+
type_names = {
|
739
|
+
1: "Positive Real",
|
740
|
+
2: "Negative Real",
|
741
|
+
3: "Complex",
|
742
|
+
4: "Float",
|
743
|
+
5: "Rational",
|
744
|
+
6: "Quaternion",
|
745
|
+
7: "Neutrosophic",
|
746
|
+
8: "Neutro-Complex",
|
747
|
+
9: "Hyperreal",
|
748
|
+
10: "Bicomplex",
|
749
|
+
11: "Neutro-Bicomplex"
|
750
|
+
}
|
751
|
+
|
752
|
+
for kececi_type in range(1, 12):
|
753
|
+
name = type_names[kececi_type]
|
754
|
+
best_zeta_score = 0.0
|
755
|
+
best_gue_score = 0.0
|
756
|
+
best_params = None
|
757
|
+
|
758
|
+
print(f"Analyzing type {kececi_type} ({name})...")
|
759
|
+
|
760
|
+
for start, add in param_sets:
|
761
|
+
try:
|
762
|
+
# Special formatting for complex types
|
763
|
+
if kececi_type == 3 and '+' not in start:
|
764
|
+
start = f"{start}+{start}j"
|
765
|
+
if kececi_type == 10 and '+' not in start:
|
766
|
+
start = f"{start}+{start}j"
|
767
|
+
|
768
|
+
sequence = get_with_params(
|
769
|
+
kececi_type_choice=kececi_type,
|
770
|
+
iterations=iterations,
|
771
|
+
start_value_raw=start,
|
772
|
+
add_value_raw=add,
|
773
|
+
include_intermediate_steps=include_intermediate
|
774
|
+
)
|
775
|
+
|
776
|
+
if not sequence or len(sequence) < 50:
|
777
|
+
continue
|
778
|
+
|
779
|
+
_, zeta_score = _find_kececi_zeta_zeros(sequence, tolerance=0.5)
|
780
|
+
_, gue_score = _compute_gue_similarity(sequence)
|
781
|
+
|
782
|
+
if zeta_score > best_zeta_score:
|
783
|
+
best_zeta_score = zeta_score
|
784
|
+
best_gue_score = gue_score
|
785
|
+
best_params = (start, add)
|
786
|
+
|
787
|
+
except Exception as e:
|
788
|
+
continue
|
789
|
+
|
790
|
+
if best_params:
|
791
|
+
results.append({
|
792
|
+
'type': kececi_type,
|
793
|
+
'name': name,
|
794
|
+
'start': best_params[0],
|
795
|
+
'add': best_params[1],
|
796
|
+
'zeta_score': best_zeta_score,
|
797
|
+
'gue_score': best_gue_score
|
798
|
+
})
|
799
|
+
|
800
|
+
# Sort results
|
801
|
+
sorted_by_zeta = sorted(results, key=lambda x: x['zeta_score'], reverse=True)
|
802
|
+
sorted_by_gue = sorted(results, key=lambda x: x['gue_score'], reverse=True)
|
803
|
+
|
804
|
+
print("\n" + "=" * 100)
|
805
|
+
print("HIGHEST RIEMANN ZETA MATCHING SCORES (TOP 11)")
|
806
|
+
print("=" * 100)
|
807
|
+
print(f"{'Type':<20} {'Score':<8} {'Start':<12} {'Increment':<12}")
|
808
|
+
print("-" * 100)
|
809
|
+
for r in sorted_by_zeta:
|
810
|
+
print(f"{r['name']:<20} {r['zeta_score']:<8.3f} {r['start']:<12} {r['add']:<12}")
|
811
|
+
|
812
|
+
print("\n" + "=" * 100)
|
813
|
+
print("HIGHEST GUE SIMILARITY SCORES (TOP 11)")
|
814
|
+
print("=" * 100)
|
815
|
+
print(f"{'Type':<20} {'Score':<8} {'Start':<12} {'Increment':<12}")
|
816
|
+
print("-" * 100)
|
817
|
+
for r in sorted_by_gue:
|
818
|
+
print(f"{r['name']:<20} {r['gue_score']:<8.3f} {r['start']:<12} {r['add']:<12}")
|
819
|
+
|
820
|
+
# Plot results
|
821
|
+
_plot_comparison(sorted_by_zeta, sorted_by_gue)
|
822
|
+
|
823
|
+
return sorted_by_zeta, sorted_by_gue
|
824
|
+
|
825
|
+
|
826
|
+
def _plot_comparison(zeta_results, gue_results):
|
827
|
+
"""
|
828
|
+
Creates bar charts comparing the performance of Keçeci types in matching Riemann zeta zeros and GUE statistics.
|
829
|
+
Args:
|
830
|
+
zeta_results (list): Results sorted by zeta matching score.
|
831
|
+
gue_results (list): Results sorted by GUE similarity score.
|
832
|
+
"""
|
833
|
+
# Riemann Zeta Matching Plot
|
834
|
+
plt.figure(figsize=(14, 7))
|
835
|
+
types = [r['name'] for r in zeta_results]
|
836
|
+
scores = [r['zeta_score'] for r in zeta_results]
|
837
|
+
colors = ['skyblue'] * len(scores)
|
838
|
+
if scores:
|
839
|
+
colors[0] = 'red'
|
840
|
+
bars = plt.bar(types, scores, color=colors, edgecolor='black', alpha=0.8)
|
841
|
+
plt.xticks(rotation=45, ha='right')
|
842
|
+
plt.ylabel("Riemann Zeta Matching Score")
|
843
|
+
plt.title("Keçeci Types vs Riemann Zeta Zeros")
|
844
|
+
plt.grid(True, alpha=0.3)
|
845
|
+
if bars:
|
846
|
+
bars[0].set_edgecolor('darkred')
|
847
|
+
bars[0].set_linewidth(1.5)
|
848
|
+
plt.tight_layout()
|
849
|
+
plt.show()
|
850
|
+
|
851
|
+
# GUE Similarity Plot
|
852
|
+
plt.figure(figsize=(14, 7))
|
853
|
+
types = [r['name'] for r in gue_results]
|
854
|
+
scores = [r['gue_score'] for r in gue_results]
|
855
|
+
colors = ['skyblue'] * len(scores)
|
856
|
+
if scores:
|
857
|
+
colors[0] = 'red'
|
858
|
+
bars = plt.bar(types, scores, color=colors, edgecolor='black', alpha=0.8)
|
859
|
+
plt.xticks(rotation=45, ha='right')
|
860
|
+
plt.ylabel("GUE Similarity Score")
|
861
|
+
plt.title("Keçeci Types vs GUE Statistics")
|
862
|
+
plt.grid(True, alpha=0.3)
|
863
|
+
if bars:
|
864
|
+
bars[0].set_edgecolor('darkred')
|
865
|
+
bars[0].set_linewidth(1.5)
|
866
|
+
plt.tight_layout()
|
867
|
+
plt.show()
|
868
|
+
|
869
|
+
def _pair_correlation(ordered_zeros, max_gap=3.0, bin_size=0.1):
|
870
|
+
"""
|
871
|
+
Computes the pair correlation of a list of ordered zeros.
|
872
|
+
This function calculates the normalized spacings between all pairs of zeros
|
873
|
+
and returns a histogram of their distribution.
|
874
|
+
Args:
|
875
|
+
ordered_zeros (numpy.ndarray): Sorted array of zero locations (e.g., Keçeci or Riemann zeta zeros).
|
876
|
+
max_gap (float): Maximum normalized gap to consider.
|
877
|
+
bin_size (float): Size of bins for the histogram.
|
878
|
+
Returns:
|
879
|
+
tuple: (bin_centers, histogram) - The centers of the bins and the normalized histogram values.
|
880
|
+
"""
|
881
|
+
n = len(ordered_zeros)
|
882
|
+
if n < 2:
|
883
|
+
return np.array([]), np.array([])
|
884
|
+
|
885
|
+
# Compute average spacing for normalization
|
886
|
+
avg_spacing = np.mean(np.diff(ordered_zeros))
|
887
|
+
normalized_zeros = ordered_zeros / avg_spacing
|
888
|
+
|
889
|
+
# Compute all pairwise gaps within max_gap
|
890
|
+
gaps = []
|
891
|
+
for i in range(n):
|
892
|
+
for j in range(i + 1, n):
|
893
|
+
gap = abs(normalized_zeros[j] - normalized_zeros[i])
|
894
|
+
if gap <= max_gap:
|
895
|
+
gaps.append(gap)
|
896
|
+
|
897
|
+
# Create histogram
|
898
|
+
bins = np.arange(0, max_gap + bin_size, bin_size)
|
899
|
+
hist, _ = np.histogram(gaps, bins=bins, density=True)
|
900
|
+
bin_centers = (bins[:-1] + bins[1:]) / 2
|
901
|
+
|
902
|
+
return bin_centers, hist
|
903
|
+
|
904
|
+
|
905
|
+
def _gue_pair_correlation(s):
|
906
|
+
"""
|
907
|
+
Theoretical pair correlation function for the Gaussian Unitary Ensemble (GUE).
|
908
|
+
This function is used as a reference for comparing the statistical distribution
|
909
|
+
of eigenvalues (or zeta zeros) in quantum chaotic systems.
|
910
|
+
Args:
|
911
|
+
s (numpy.ndarray or float): Normalized spacing(s).
|
912
|
+
Returns:
|
913
|
+
numpy.ndarray or float: The GUE pair correlation value(s) at s.
|
914
|
+
"""
|
915
|
+
return 1 - np.sinc(s)**2
|
916
|
+
|
917
|
+
|
918
|
+
def analyze_pair_correlation(sequence, title="Pair Correlation of Keçeci Zeta Zeros"):
|
919
|
+
"""
|
920
|
+
Analyzes and plots the pair correlation of Keçeci Zeta zeros derived from a Keçeci sequence.
|
921
|
+
Compares the empirical pair correlation to the theoretical GUE prediction.
|
922
|
+
Performs a Kolmogorov-Smirnov test to quantify the similarity.
|
923
|
+
Args:
|
924
|
+
sequence (list): A Keçeci number sequence.
|
925
|
+
title (str): Title for the resulting plot.
|
926
|
+
"""
|
927
|
+
from . import _get_integer_representation
|
928
|
+
|
929
|
+
# Extract integer representations and remove DC component
|
930
|
+
values = [val for z in sequence if (val := _get_integer_representation(z)) is not None]
|
931
|
+
if len(values) < 10:
|
932
|
+
print("Insufficient data.")
|
933
|
+
return
|
934
|
+
|
935
|
+
values = np.array(values) - np.mean(values)
|
936
|
+
N = len(values)
|
937
|
+
powers = np.abs(fft(values))**2
|
938
|
+
freqs = fftfreq(N)
|
939
|
+
|
940
|
+
# Filter positive frequencies
|
941
|
+
mask = (freqs > 0)
|
942
|
+
freqs_pos = freqs[mask]
|
943
|
+
powers_pos = powers[mask]
|
944
|
+
|
945
|
+
if len(powers_pos) == 0:
|
946
|
+
print("No positive frequencies found.")
|
947
|
+
return
|
948
|
+
|
949
|
+
# Find spectral peaks
|
950
|
+
peaks, _ = find_peaks(powers_pos, height=np.max(powers_pos)*1e-7)
|
951
|
+
strong_freqs = freqs_pos[peaks]
|
952
|
+
|
953
|
+
if len(strong_freqs) < 2:
|
954
|
+
print("Insufficient frequency peaks.")
|
955
|
+
return
|
956
|
+
|
957
|
+
# Scale frequencies so the strongest peak aligns with the first Riemann zeta zero
|
958
|
+
peak_freq = strong_freqs[np.argmax(powers_pos[peaks])]
|
959
|
+
scale_factor = 14.134725 / peak_freq
|
960
|
+
scaled_freqs = np.sort(strong_freqs * scale_factor)
|
961
|
+
|
962
|
+
# Estimate Keçeci Zeta zeros by finding minima of |ζ_Kececi(0.5 + it)|
|
963
|
+
t_vals = np.linspace(0, 650, 10000)
|
964
|
+
zeta_vals = np.array([sum((scaled_freqs + 1e-10)**(- (0.5 + 1j * t))) for t in t_vals])
|
965
|
+
minima, _ = find_peaks(-np.abs(zeta_vals), height=-0.5*np.max(np.abs(zeta_vals)), distance=5)
|
966
|
+
kececi_zeta_zeros = t_vals[minima]
|
967
|
+
|
968
|
+
if len(kececi_zeta_zeros) < 2:
|
969
|
+
print("Insufficient Keçeci zeta zeros found.")
|
970
|
+
return
|
971
|
+
|
972
|
+
# Compute pair correlation
|
973
|
+
bin_centers, hist = _pair_correlation(kececi_zeta_zeros, max_gap=3.0, bin_size=0.1)
|
974
|
+
gue_corr = _gue_pair_correlation(bin_centers)
|
975
|
+
|
976
|
+
# Plot results
|
977
|
+
plt.figure(figsize=(12, 6))
|
978
|
+
plt.plot(bin_centers, hist, 'o-', label="Keçeci Zeta Zeros", linewidth=2)
|
979
|
+
plt.plot(bin_centers, gue_corr, 'r-', label="GUE (Theoretical)", linewidth=2)
|
980
|
+
plt.title(title)
|
981
|
+
plt.xlabel("Normalized Spacing (s)")
|
982
|
+
plt.ylabel("Pair Correlation Density")
|
983
|
+
plt.legend()
|
984
|
+
plt.grid(True, alpha=0.3)
|
985
|
+
plt.tight_layout()
|
986
|
+
plt.show()
|
987
|
+
|
988
|
+
# Perform Kolmogorov-Smirnov test
|
989
|
+
ks_stat, ks_p = ks_2samp(hist, gue_corr)
|
990
|
+
print(f"Pair Correlation KS Test: Statistic={ks_stat:.4f}, p-value={ks_p:.4f}")
|
991
|
+
|
547
992
|
# ==============================================================================
|
548
993
|
# --- CORE GENERATOR ---
|
549
994
|
# ==============================================================================
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: kececinumbers
|
3
|
-
Version: 0.6.
|
3
|
+
Version: 0.6.5
|
4
4
|
Summary: Keçeci Numbers: An Exploration of a Dynamic Sequence Across Diverse Number Sets
|
5
5
|
Home-page: https://github.com/WhiteSymmetry/kececinumbers
|
6
6
|
Author: Mehmet Keçeci
|
@@ -42,6 +42,7 @@ License-File: LICENSE
|
|
42
42
|
Requires-Dist: numpy
|
43
43
|
Requires-Dist: matplotlib
|
44
44
|
Requires-Dist: numpy-quaternion
|
45
|
+
Requires-Dist: scipy
|
45
46
|
Requires-Dist: sympy
|
46
47
|
Provides-Extra: test
|
47
48
|
Requires-Dist: pytest; extra == "test"
|
@@ -51,6 +52,7 @@ Requires-Dist: ruff; extra == "test"
|
|
51
52
|
Requires-Dist: numpy; extra == "test"
|
52
53
|
Requires-Dist: matplotlib; extra == "test"
|
53
54
|
Requires-Dist: numpy-quaternion; extra == "test"
|
55
|
+
Requires-Dist: scipy; extra == "test"
|
54
56
|
Requires-Dist: sympy; extra == "test"
|
55
57
|
Dynamic: author
|
56
58
|
Dynamic: home-page
|
@@ -209,7 +211,7 @@ import kececinumbers as kn
|
|
209
211
|
sequence = kn.get_with_params(
|
210
212
|
kececi_type_choice=kn.TYPE_POSITIVE_REAL,
|
211
213
|
iterations=30,
|
212
|
-
start_value_raw="0",
|
214
|
+
start_value_raw="0.0",
|
213
215
|
add_value_raw="9.0",
|
214
216
|
include_intermediate_steps=True
|
215
217
|
)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
docs/conf.py,sha256=jkpH_TchRJcC_EspKeY1E_rml2ODmIWhWoqvyCPu_ok,1116
|
2
|
+
kececinumbers/__init__.py,sha256=s2_zWrTMEhl--tBf2xp981CSG6Perq4-lUs4zYlaAYY,4225
|
3
|
+
kececinumbers/_version.py,sha256=pzo7Vd3ivKiGiCuF1pOxJt2NbhNXjLrSr8afRu5Wr7o,453
|
4
|
+
kececinumbers/kececinumbers.py,sha256=n7o4NDZlzneIfCTa9j-aXQTX5f_8OpQfMlWprgmnPdk,59763
|
5
|
+
kececinumbers-0.6.5.dist-info/licenses/LICENSE,sha256=NJZsJEbQuKzxn1mWPWCbRx8jRUqGS22thl8wwuRQJ9c,1071
|
6
|
+
tests/test_sample.py,sha256=qMWUBGQtlF1gZHZ_e6Gye1vHtyNnUWH7iXK72a1y6VQ,9728
|
7
|
+
kececinumbers-0.6.5.dist-info/METADATA,sha256=qc2oK-7YzshCBJ64nOL76LKtmWcIF7fK_LDRzTJsLdM,33720
|
8
|
+
kececinumbers-0.6.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
9
|
+
kececinumbers-0.6.5.dist-info/top_level.txt,sha256=ABQEKRH9iYb4sWnFdx7gIx7Hg899YktRkQpbRlSSqwU,25
|
10
|
+
kececinumbers-0.6.5.dist-info/RECORD,,
|
@@ -1,10 +0,0 @@
|
|
1
|
-
docs/conf.py,sha256=jkpH_TchRJcC_EspKeY1E_rml2ODmIWhWoqvyCPu_ok,1116
|
2
|
-
kececinumbers/__init__.py,sha256=BppueKxmKzWlPR0VUdq-0RiJyJOvEH3mbGqClov0mjw,3758
|
3
|
-
kececinumbers/_version.py,sha256=mXoGDVZCtP2YgLFmkRSkSIWnem5vexg9IHGcMAOgmDM,453
|
4
|
-
kececinumbers/kececinumbers.py,sha256=jf0z5I-mJ2speU6Dyqd9GTIS9Phk5GVItjY2Eaaphis,44569
|
5
|
-
kececinumbers-0.6.3.dist-info/licenses/LICENSE,sha256=NJZsJEbQuKzxn1mWPWCbRx8jRUqGS22thl8wwuRQJ9c,1071
|
6
|
-
tests/test_sample.py,sha256=qMWUBGQtlF1gZHZ_e6Gye1vHtyNnUWH7iXK72a1y6VQ,9728
|
7
|
-
kececinumbers-0.6.3.dist-info/METADATA,sha256=CUsBABtdWjq40sYHfJSdbVZbzwQUvL-7Tx9SyzPFFJI,33659
|
8
|
-
kececinumbers-0.6.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
9
|
-
kececinumbers-0.6.3.dist-info/top_level.txt,sha256=ABQEKRH9iYb4sWnFdx7gIx7Hg899YktRkQpbRlSSqwU,25
|
10
|
-
kececinumbers-0.6.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|