kececinumbers 0.3.3__py3-none-any.whl → 0.3.4__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 +89 -9
- kececinumbers/_version.py +1 -1
- kececinumbers/kececinumbers.py +288 -638
- {kececinumbers-0.3.3.dist-info → kececinumbers-0.3.4.dist-info}/METADATA +3 -2
- kececinumbers-0.3.4.dist-info/RECORD +8 -0
- kececinumbers-0.3.3.dist-info/RECORD +0 -8
- {kececinumbers-0.3.3.dist-info → kececinumbers-0.3.4.dist-info}/WHEEL +0 -0
- {kececinumbers-0.3.3.dist-info → kececinumbers-0.3.4.dist-info}/licenses/LICENSE +0 -0
- {kececinumbers-0.3.3.dist-info → kececinumbers-0.3.4.dist-info}/top_level.txt +0 -0
kececinumbers/kececinumbers.py
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
### `kececinumbers.py`
|
2
|
-
|
3
1
|
# -*- coding: utf-8 -*-
|
4
2
|
"""
|
5
3
|
Keçeci Numbers Module (kececinumbers.py)
|
@@ -19,8 +17,8 @@ Key Features:
|
|
19
17
|
- Helper functions for mathematical properties like primality and divisibility.
|
20
18
|
- Advanced plotting capabilities tailored to each number system.
|
21
19
|
- Functions for interactive use or programmatic integration.
|
22
|
-
|
23
|
-
|
20
|
+
---
|
21
|
+
|
24
22
|
Keçeci Conjecture: Keçeci Varsayımı, Keçeci-Vermutung, Conjecture de Keçeci, Гипотеза Кечеджи, 凯杰西猜想, ケジェジ予想, Keçeci Huds, Keçeci Hudsiye, Keçeci Hudsia, كَچَه جِي ,حدس کچه جی, کچہ جی حدسیہ
|
25
23
|
|
26
24
|
Keçeci Varsayımı (Keçeci Conjecture) - Önerilen
|
@@ -28,28 +26,21 @@ Keçeci Varsayımı (Keçeci Conjecture) - Önerilen
|
|
28
26
|
Her Keçeci Sayı türü için, `unified_generator` fonksiyonu tarafından oluşturulan dizilerin, sonlu adımdan sonra periyodik bir yapıya veya tekrar eden bir asal temsiline (Keçeci Asal Sayısı, KPN) yakınsadığı sanılmaktadır. Bu davranış, Collatz Varsayımı'nın çoklu cebirsel sistemlere genişletilmiş bir hali olarak değerlendirilebilir.
|
29
27
|
|
30
28
|
Henüz kanıtlanmamıştır ve bu modül bu varsayımı test etmek için bir çerçeve sunar.
|
31
|
-
|
32
|
-
# Keçeci Conjecture - Proposed
|
33
|
-
|
34
|
-
For every Keçeci Number type, sequences generated by the `unified_generator` function are conjectured to converge to a periodic structure or a recurring prime representation (Keçeci Prime Number, KPN) in finitely many steps. This behavior can be viewed as a generalization of the Collatz Conjecture to multiple algebraic systems.
|
35
|
-
|
36
|
-
It remains unproven, and this module provides a framework for testing the conjecture.
|
37
|
-
|
38
29
|
"""
|
39
30
|
|
40
31
|
# --- Standard Library Imports ---
|
41
32
|
import collections
|
42
|
-
import math
|
43
|
-
import random
|
44
33
|
from dataclasses import dataclass
|
45
34
|
from fractions import Fraction
|
46
|
-
|
47
|
-
|
35
|
+
import math
|
36
|
+
from matplotlib.gridspec import GridSpec
|
48
37
|
import matplotlib.pyplot as plt
|
49
38
|
import numpy as np
|
50
|
-
import quaternion
|
51
|
-
|
39
|
+
import quaternion
|
40
|
+
import random
|
52
41
|
import re
|
42
|
+
from typing import Any, Dict, List, Optional, Tuple
|
43
|
+
|
53
44
|
|
54
45
|
# ==============================================================================
|
55
46
|
# --- MODULE CONSTANTS: KEÇECI NUMBER TYPES ---
|
@@ -72,300 +63,187 @@ TYPE_NEUTROSOPHIC_BICOMPLEX = 11
|
|
72
63
|
|
73
64
|
@dataclass
|
74
65
|
class NeutrosophicNumber:
|
75
|
-
"""
|
76
|
-
Represents a neutrosophic number of the form a + bI, where I is the
|
77
|
-
indeterminate part and I^2 = I.
|
78
|
-
|
79
|
-
Attributes:
|
80
|
-
a (float): The determinate part.
|
81
|
-
b (float): The indeterminate part.
|
82
|
-
"""
|
66
|
+
"""Represents a neutrosophic number of the form a + bI where I^2 = I."""
|
83
67
|
a: float
|
84
68
|
b: float
|
85
69
|
|
86
|
-
def __add__(self, other):
|
70
|
+
def __add__(self, other: Any) -> "NeutrosophicNumber":
|
87
71
|
if isinstance(other, NeutrosophicNumber):
|
88
72
|
return NeutrosophicNumber(self.a + other.a, self.b + other.b)
|
89
|
-
|
73
|
+
if isinstance(other, (int, float)):
|
74
|
+
return NeutrosophicNumber(self.a + other, self.b)
|
75
|
+
return NotImplemented
|
90
76
|
|
91
|
-
def __sub__(self, other):
|
77
|
+
def __sub__(self, other: Any) -> "NeutrosophicNumber":
|
92
78
|
if isinstance(other, NeutrosophicNumber):
|
93
79
|
return NeutrosophicNumber(self.a - other.a, self.b - other.b)
|
94
|
-
|
80
|
+
if isinstance(other, (int, float)):
|
81
|
+
return NeutrosophicNumber(self.a - other, self.b)
|
82
|
+
return NotImplemented
|
95
83
|
|
96
|
-
def __mul__(self, other):
|
84
|
+
def __mul__(self, other: Any) -> "NeutrosophicNumber":
|
97
85
|
if isinstance(other, NeutrosophicNumber):
|
98
|
-
# (a + bI)(c + dI) = ac + (ad + bc + bd)I
|
99
86
|
return NeutrosophicNumber(
|
100
87
|
self.a * other.a,
|
101
|
-
self.a * other.b + self.b * other.a + self.b * other.b
|
88
|
+
self.a * other.b + self.b * other.a + self.b * other.b,
|
102
89
|
)
|
103
|
-
|
90
|
+
if isinstance(other, (int, float)):
|
91
|
+
return NeutrosophicNumber(self.a * other, self.b * other)
|
92
|
+
return NotImplemented
|
104
93
|
|
105
|
-
def __truediv__(self, divisor):
|
94
|
+
def __truediv__(self, divisor: float) -> "NeutrosophicNumber":
|
106
95
|
if isinstance(divisor, (int, float)):
|
96
|
+
if divisor == 0:
|
97
|
+
raise ZeroDivisionError("Cannot divide by zero.")
|
107
98
|
return NeutrosophicNumber(self.a / divisor, self.b / divisor)
|
108
|
-
raise TypeError("Only scalar division is supported
|
99
|
+
raise TypeError("Only scalar division is supported.")
|
109
100
|
|
110
|
-
def __str__(self):
|
101
|
+
def __str__(self) -> str:
|
111
102
|
return f"{self.a} + {self.b}I"
|
112
103
|
|
113
104
|
@dataclass
|
114
105
|
class NeutrosophicComplexNumber:
|
115
|
-
"""
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
This object models systems where a value has both a complex-valued state
|
120
|
-
(like quantum amplitude) and an associated level of uncertainty or
|
121
|
-
unreliability (like quantum decoherence).
|
122
|
-
|
123
|
-
Attributes:
|
124
|
-
real (float): The real part of the deterministic component.
|
125
|
-
imag (float): The imaginary part of the deterministic component.
|
126
|
-
indeterminacy (float): The coefficient of the indeterminate part, I.
|
127
|
-
"""
|
128
|
-
|
129
|
-
def __init__(self, real: float = 0.0, imag: float = 0.0, indeterminacy: float = 0.0):
|
130
|
-
"""
|
131
|
-
Initialises a NeutrosophicComplexNumber.
|
132
|
-
|
133
|
-
Args:
|
134
|
-
real (float): The initial real part. Defaults to 0.0.
|
135
|
-
imag (float): The initial imaginary part. Defaults to 0.0.
|
136
|
-
indeterminacy (float): The initial indeterminacy level. Defaults to 0.0.
|
137
|
-
"""
|
138
|
-
self.real = float(real)
|
139
|
-
self.imag = float(imag)
|
140
|
-
self.indeterminacy = float(indeterminacy)
|
106
|
+
"""Represents a number with a complex part and an indeterminacy level."""
|
107
|
+
real: float = 0.0
|
108
|
+
imag: float = 0.0
|
109
|
+
indeterminacy: float = 0.0
|
141
110
|
|
142
111
|
def __repr__(self) -> str:
|
143
|
-
"""
|
144
|
-
Returns an unambiguous, developer-friendly representation of the object.
|
145
|
-
"""
|
146
112
|
return f"NeutrosophicComplexNumber(real={self.real}, imag={self.imag}, indeterminacy={self.indeterminacy})"
|
147
113
|
|
148
114
|
def __str__(self) -> str:
|
149
|
-
"""
|
150
|
-
Returns a user-friendly string representation of the object.
|
151
|
-
"""
|
152
|
-
# Shows a sign for the imaginary part for clarity (e.g., +1.0j, -2.0j)
|
153
115
|
return f"({self.real}{self.imag:+}j) + {self.indeterminacy}I"
|
154
116
|
|
155
|
-
|
156
|
-
|
157
|
-
def __add__(self, other):
|
158
|
-
"""Adds another number to this one."""
|
117
|
+
def __add__(self, other: Any) -> "NeutrosophicComplexNumber":
|
159
118
|
if isinstance(other, NeutrosophicComplexNumber):
|
160
119
|
return NeutrosophicComplexNumber(
|
161
|
-
self.real + other.real,
|
162
|
-
self.imag + other.imag,
|
163
|
-
self.indeterminacy + other.indeterminacy
|
120
|
+
self.real + other.real, self.imag + other.imag, self.indeterminacy + other.indeterminacy
|
164
121
|
)
|
165
|
-
|
166
|
-
elif isinstance(other, (int, float)):
|
122
|
+
if isinstance(other, (int, float)):
|
167
123
|
return NeutrosophicComplexNumber(self.real + other, self.imag, self.indeterminacy)
|
168
124
|
return NotImplemented
|
169
125
|
|
170
|
-
def __sub__(self, other):
|
171
|
-
"""Subtracts another number from this one."""
|
126
|
+
def __sub__(self, other: Any) -> "NeutrosophicComplexNumber":
|
172
127
|
if isinstance(other, NeutrosophicComplexNumber):
|
173
128
|
return NeutrosophicComplexNumber(
|
174
|
-
self.real - other.real,
|
175
|
-
self.imag - other.imag,
|
176
|
-
self.indeterminacy - other.indeterminacy
|
129
|
+
self.real - other.real, self.imag - other.imag, self.indeterminacy - other.indeterminacy
|
177
130
|
)
|
178
|
-
|
179
|
-
|
131
|
+
if isinstance(other, (int, float)):
|
132
|
+
return NeutrosophicComplexNumber(self.real - other, self.imag, self.indeterminacy)
|
180
133
|
return NotImplemented
|
181
134
|
|
182
|
-
def __mul__(self, other):
|
183
|
-
"""
|
184
|
-
Multiplies this number by another number (scalar, complex, or neutrosophic-complex).
|
185
|
-
This is the most critical operation for complex dynamics.
|
186
|
-
"""
|
135
|
+
def __mul__(self, other: Any) -> "NeutrosophicComplexNumber":
|
187
136
|
if isinstance(other, NeutrosophicComplexNumber):
|
188
|
-
# (a+bj)*(c+dj) = (ac-bd) + (ad+bc)j
|
189
137
|
new_real = self.real * other.real - self.imag * other.imag
|
190
138
|
new_imag = self.real * other.imag + self.imag * other.real
|
191
|
-
|
192
|
-
# The indeterminacy grows based on both original indeterminacies and
|
193
|
-
# the magnitude of the deterministic part, creating rich, non-linear behaviour.
|
194
139
|
new_indeterminacy = self.indeterminacy + other.indeterminacy + (self.magnitude_sq() * other.indeterminacy)
|
195
|
-
|
196
140
|
return NeutrosophicComplexNumber(new_real, new_imag, new_indeterminacy)
|
197
|
-
|
198
|
-
elif isinstance(other, complex):
|
199
|
-
# Multiply by a standard Python complex number
|
141
|
+
if isinstance(other, complex):
|
200
142
|
new_real = self.real * other.real - self.imag * other.imag
|
201
143
|
new_imag = self.real * other.imag + self.imag * other.real
|
202
|
-
# The indeterminacy is unaffected when multiplied by a purely deterministic complex number.
|
203
144
|
return NeutrosophicComplexNumber(new_real, new_imag, self.indeterminacy)
|
204
|
-
|
205
|
-
|
206
|
-
# Multiply by a scalar
|
207
|
-
return NeutrosophicComplexNumber(
|
208
|
-
self.real * other,
|
209
|
-
self.imag * other,
|
210
|
-
self.indeterminacy * other
|
211
|
-
)
|
145
|
+
if isinstance(other, (int, float)):
|
146
|
+
return NeutrosophicComplexNumber(self.real * other, self.imag * other, self.indeterminacy * other)
|
212
147
|
return NotImplemented
|
213
148
|
|
214
|
-
def __truediv__(self, divisor):
|
215
|
-
"""Divides this number by a scalar."""
|
149
|
+
def __truediv__(self, divisor: float) -> "NeutrosophicComplexNumber":
|
216
150
|
if isinstance(divisor, (int, float)):
|
217
151
|
if divisor == 0:
|
218
|
-
raise ZeroDivisionError("Cannot divide
|
152
|
+
raise ZeroDivisionError("Cannot divide by zero.")
|
219
153
|
return NeutrosophicComplexNumber(
|
220
|
-
self.real / divisor,
|
221
|
-
self.imag / divisor,
|
222
|
-
self.indeterminacy / divisor
|
154
|
+
self.real / divisor, self.imag / divisor, self.indeterminacy / divisor
|
223
155
|
)
|
224
|
-
raise TypeError("Only scalar division is supported
|
225
|
-
|
226
|
-
# --- Reversed Mathematical Operations ---
|
156
|
+
raise TypeError("Only scalar division is supported.")
|
227
157
|
|
228
|
-
def __radd__(self, other):
|
229
|
-
"""Handles cases like `5 + my_number`."""
|
158
|
+
def __radd__(self, other: Any) -> "NeutrosophicComplexNumber":
|
230
159
|
return self.__add__(other)
|
231
160
|
|
232
|
-
def __rsub__(self, other):
|
233
|
-
"""Handles cases like `5 - my_number`."""
|
161
|
+
def __rsub__(self, other: Any) -> "NeutrosophicComplexNumber":
|
234
162
|
if isinstance(other, (int, float)):
|
235
163
|
return NeutrosophicComplexNumber(other - self.real, -self.imag, -self.indeterminacy)
|
236
164
|
return NotImplemented
|
237
165
|
|
238
|
-
def __rmul__(self, other):
|
239
|
-
"""Handles cases like `5 * my_number`."""
|
166
|
+
def __rmul__(self, other: Any) -> "NeutrosophicComplexNumber":
|
240
167
|
return self.__mul__(other)
|
241
168
|
|
242
|
-
# --- Unary and Comparison Operations ---
|
243
|
-
|
244
|
-
def __neg__(self):
|
245
|
-
"""Returns the negative of the number."""
|
246
|
-
return NeutrosophicComplexNumber(-self.real, -self.imag, self.indeterminacy)
|
247
|
-
|
248
|
-
def __eq__(self, other) -> bool:
|
249
|
-
"""Checks for equality between two numbers."""
|
250
|
-
if not isinstance(other, NeutrosophicComplexNumber):
|
251
|
-
return False
|
252
|
-
return (self.real == other.real and
|
253
|
-
self.imag == other.imag and
|
254
|
-
self.indeterminacy == other.indeterminacy)
|
255
|
-
|
256
|
-
# --- Helper Methods ---
|
257
|
-
|
258
169
|
def magnitude_sq(self) -> float:
|
259
|
-
"""Returns the squared magnitude of the deterministic (complex) part."""
|
260
170
|
return self.real**2 + self.imag**2
|
261
171
|
|
262
|
-
def magnitude(self) -> float:
|
263
|
-
"""Returns the magnitude (modulus or absolute value) of the deterministic part."""
|
264
|
-
return math.sqrt(self.magnitude_sq())
|
265
|
-
|
266
|
-
def deterministic_part(self) -> complex:
|
267
|
-
"""Returns the deterministic part as a standard Python complex number."""
|
268
|
-
return complex(self.real, self.imag)
|
269
|
-
|
270
|
-
|
271
172
|
@dataclass
|
272
173
|
class HyperrealNumber:
|
273
|
-
"""
|
274
|
-
Represents a hyperreal number as a sequence of real numbers.
|
275
|
-
Operations are performed element-wise on the sequences.
|
276
|
-
|
277
|
-
Attributes:
|
278
|
-
sequence (list[float]): The sequence representing the hyperreal.
|
279
|
-
"""
|
174
|
+
"""Represents a hyperreal number as a sequence of real numbers."""
|
280
175
|
sequence: list
|
281
176
|
|
282
|
-
def __add__(self, other):
|
177
|
+
def __add__(self, other: Any) -> "HyperrealNumber":
|
283
178
|
if isinstance(other, HyperrealNumber):
|
284
179
|
return HyperrealNumber([a + b for a, b in zip(self.sequence, other.sequence)])
|
285
|
-
|
286
|
-
|
287
|
-
def __sub__(self, other):
|
180
|
+
return NotImplemented
|
181
|
+
|
182
|
+
def __sub__(self, other: Any) -> "HyperrealNumber":
|
288
183
|
if isinstance(other, HyperrealNumber):
|
289
184
|
return HyperrealNumber([a - b for a, b in zip(self.sequence, other.sequence)])
|
290
|
-
|
185
|
+
return NotImplemented
|
291
186
|
|
292
|
-
|
293
|
-
# --- NEWLY ADDED FIX ---
|
294
|
-
def __mul__(self, scalar):
|
295
|
-
"""Handles multiplication by a scalar (int or float)."""
|
187
|
+
def __mul__(self, scalar: float) -> "HyperrealNumber":
|
296
188
|
if isinstance(scalar, (int, float)):
|
297
189
|
return HyperrealNumber([x * scalar for x in self.sequence])
|
298
|
-
|
299
|
-
|
300
|
-
def __rmul__(self, scalar):
|
301
|
-
"""Handles the case where the scalar is on the left (e.g., float * HyperrealNumber)."""
|
190
|
+
return NotImplemented
|
191
|
+
|
192
|
+
def __rmul__(self, scalar: float) -> "HyperrealNumber":
|
302
193
|
return self.__mul__(scalar)
|
303
|
-
# --- DÜZELTME SONU ---
|
304
|
-
# --- END OF FIX ---
|
305
194
|
|
306
|
-
def __truediv__(self, divisor):
|
195
|
+
def __truediv__(self, divisor: float) -> "HyperrealNumber":
|
307
196
|
if isinstance(divisor, (int, float)):
|
308
197
|
if divisor == 0:
|
309
198
|
raise ZeroDivisionError("Scalar division by zero.")
|
310
199
|
return HyperrealNumber([x / divisor for x in self.sequence])
|
311
200
|
raise TypeError("Only scalar division is supported.")
|
312
|
-
|
313
|
-
def __mod__(self, divisor):
|
201
|
+
|
202
|
+
def __mod__(self, divisor: float) -> List[float]:
|
314
203
|
if isinstance(divisor, (int, float)):
|
315
204
|
return [x % divisor for x in self.sequence]
|
316
|
-
raise TypeError("Modulo
|
205
|
+
raise TypeError("Modulo only supported with a scalar divisor.")
|
317
206
|
|
318
|
-
def __str__(self):
|
207
|
+
def __str__(self) -> str:
|
319
208
|
return f"Hyperreal({self.sequence[:3]}...)"
|
320
209
|
|
321
210
|
@dataclass
|
322
211
|
class BicomplexNumber:
|
323
|
-
"""
|
324
|
-
Represents a bicomplex number of the form z1 + j*z2, where z1 and z2
|
325
|
-
are standard complex numbers, i^2 = -1, and j^2 = -1.
|
326
|
-
|
327
|
-
Attributes:
|
328
|
-
z1 (complex): The first complex component.
|
329
|
-
z2 (complex): The second complex component (coefficient of j).
|
330
|
-
"""
|
212
|
+
"""Represents a bicomplex number z1 + j*z2, where i^2 = j^2 = -1."""
|
331
213
|
z1: complex
|
332
214
|
z2: complex
|
333
|
-
|
334
|
-
def __add__(self, other):
|
215
|
+
|
216
|
+
def __add__(self, other: Any) -> "BicomplexNumber":
|
335
217
|
if isinstance(other, BicomplexNumber):
|
336
218
|
return BicomplexNumber(self.z1 + other.z1, self.z2 + other.z2)
|
337
|
-
|
219
|
+
return NotImplemented
|
338
220
|
|
339
|
-
def __sub__(self, other):
|
221
|
+
def __sub__(self, other: Any) -> "BicomplexNumber":
|
340
222
|
if isinstance(other, BicomplexNumber):
|
341
223
|
return BicomplexNumber(self.z1 - other.z1, self.z2 - other.z2)
|
342
|
-
|
224
|
+
return NotImplemented
|
343
225
|
|
344
|
-
def __mul__(self, other):
|
226
|
+
def __mul__(self, other: Any) -> "BicomplexNumber":
|
345
227
|
if isinstance(other, BicomplexNumber):
|
346
|
-
# (z1 + z2j)(w1 + w2j) = (z1w1 - z2w2) + (z1w2 + z2w1)j
|
347
228
|
return BicomplexNumber(
|
348
229
|
(self.z1 * other.z1) - (self.z2 * other.z2),
|
349
|
-
(self.z1 * other.z2) + (self.z2 * other.z1)
|
230
|
+
(self.z1 * other.z2) + (self.z2 * other.z1),
|
350
231
|
)
|
351
|
-
|
352
|
-
|
353
|
-
def __truediv__(self, scalar):
|
232
|
+
return NotImplemented
|
233
|
+
|
234
|
+
def __truediv__(self, scalar: float) -> "BicomplexNumber":
|
354
235
|
if isinstance(scalar, (int, float)):
|
236
|
+
if scalar == 0:
|
237
|
+
raise ZeroDivisionError("Cannot divide by zero.")
|
355
238
|
return BicomplexNumber(self.z1 / scalar, self.z2 / scalar)
|
356
239
|
raise TypeError("Only scalar division is supported.")
|
357
240
|
|
358
|
-
def __str__(self):
|
241
|
+
def __str__(self) -> str:
|
359
242
|
return f"Bicomplex({self.z1}, {self.z2})"
|
360
243
|
|
361
244
|
@dataclass
|
362
245
|
class NeutrosophicBicomplexNumber:
|
363
|
-
"""
|
364
|
-
Represents a highly complex number with multiple components.
|
365
|
-
NOTE: The multiplication implemented here is a simplified, element-wise
|
366
|
-
operation for demonstrative purposes and is not mathematically rigorous.
|
367
|
-
The true algebraic multiplication is exceedingly complex.
|
368
|
-
"""
|
246
|
+
"""Represents a simplified neutrosophic-bicomplex number."""
|
369
247
|
real: float
|
370
248
|
imag: float
|
371
249
|
neut_real: float
|
@@ -375,252 +253,187 @@ class NeutrosophicBicomplexNumber:
|
|
375
253
|
j_neut_real: float
|
376
254
|
j_neut_imag: float
|
377
255
|
|
378
|
-
def __add__(self, other):
|
256
|
+
def __add__(self, other: Any) -> "NeutrosophicBicomplexNumber":
|
379
257
|
if isinstance(other, NeutrosophicBicomplexNumber):
|
380
258
|
return NeutrosophicBicomplexNumber(*(a + b for a, b in zip(self.__dict__.values(), other.__dict__.values())))
|
381
|
-
|
382
|
-
|
383
|
-
def __sub__(self, other):
|
259
|
+
return NotImplemented
|
260
|
+
|
261
|
+
def __sub__(self, other: Any) -> "NeutrosophicBicomplexNumber":
|
384
262
|
if isinstance(other, NeutrosophicBicomplexNumber):
|
385
263
|
return NeutrosophicBicomplexNumber(*(a - b for a, b in zip(self.__dict__.values(), other.__dict__.values())))
|
386
|
-
|
387
|
-
|
388
|
-
def __truediv__(self, scalar):
|
264
|
+
return NotImplemented
|
265
|
+
|
266
|
+
def __truediv__(self, scalar: float) -> "NeutrosophicBicomplexNumber":
|
389
267
|
if isinstance(scalar, (int, float)):
|
268
|
+
if scalar == 0:
|
269
|
+
raise ZeroDivisionError("Cannot divide by zero.")
|
390
270
|
return NeutrosophicBicomplexNumber(*(val / scalar for val in self.__dict__.values()))
|
391
271
|
raise TypeError("Only scalar division supported.")
|
392
272
|
|
393
|
-
def __str__(self):
|
273
|
+
def __str__(self) -> str:
|
394
274
|
return f"NeutroBicomplex(r={self.real}, i={self.imag}, Ir={self.neut_real}, ...)"
|
395
275
|
|
396
|
-
|
397
276
|
# ==============================================================================
|
398
277
|
# --- HELPER FUNCTIONS ---
|
399
278
|
# ==============================================================================
|
400
279
|
|
401
|
-
def
|
402
|
-
"""
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
value_to_check = abs(int(n_input.z1.real))
|
424
|
-
elif isinstance(n_input, NeutrosophicBicomplexNumber):
|
425
|
-
value_to_check = abs(int(n_input.real))
|
426
|
-
else:
|
427
|
-
try:
|
428
|
-
value_to_check = abs(int(n_input))
|
429
|
-
except (ValueError, TypeError):
|
430
|
-
return False
|
280
|
+
def _get_integer_representation(n_input: Any) -> Optional[int]:
|
281
|
+
"""Extracts the primary integer component from any supported number type."""
|
282
|
+
try:
|
283
|
+
if isinstance(n_input, (int, float, Fraction)):
|
284
|
+
return abs(int(n_input))
|
285
|
+
if isinstance(n_input, complex):
|
286
|
+
return abs(int(n_input.real))
|
287
|
+
if isinstance(n_input, np.quaternion):
|
288
|
+
return abs(int(n_input.w))
|
289
|
+
if isinstance(n_input, NeutrosophicNumber):
|
290
|
+
return abs(int(n_input.a))
|
291
|
+
if isinstance(n_input, NeutrosophicComplexNumber):
|
292
|
+
return abs(int(n_input.real))
|
293
|
+
if isinstance(n_input, HyperrealNumber):
|
294
|
+
return abs(int(n_input.sequence[0])) if n_input.sequence else 0
|
295
|
+
if isinstance(n_input, BicomplexNumber):
|
296
|
+
return abs(int(n_input.z1.real))
|
297
|
+
if isinstance(n_input, NeutrosophicBicomplexNumber):
|
298
|
+
return abs(int(n_input.real))
|
299
|
+
return abs(int(n_input))
|
300
|
+
except (ValueError, TypeError, IndexError):
|
301
|
+
return None
|
431
302
|
|
432
|
-
|
433
|
-
if
|
303
|
+
def is_prime(n_input: Any) -> bool:
|
304
|
+
"""Checks if a given number (or its principal component) is prime."""
|
305
|
+
value_to_check = _get_integer_representation(n_input)
|
306
|
+
if value_to_check is None or value_to_check < 2:
|
434
307
|
return False
|
435
308
|
if value_to_check == 2:
|
436
309
|
return True
|
437
310
|
if value_to_check % 2 == 0:
|
438
311
|
return False
|
439
|
-
# Check only odd divisors up to the square root
|
440
312
|
for i in range(3, int(math.sqrt(value_to_check)) + 1, 2):
|
441
313
|
if value_to_check % i == 0:
|
442
314
|
return False
|
443
315
|
return True
|
444
316
|
|
445
|
-
def _is_divisible(value, divisor, kececi_type):
|
446
|
-
"""
|
447
|
-
Helper to check divisibility for different number types.
|
448
|
-
Returns True if a number is "perfectly divisible" by an integer divisor.
|
449
|
-
"""
|
317
|
+
def _is_divisible(value: Any, divisor: int, kececi_type: int) -> bool:
|
318
|
+
"""Helper to check divisibility for different number types."""
|
450
319
|
try:
|
451
320
|
if kececi_type in [TYPE_POSITIVE_REAL, TYPE_NEGATIVE_REAL]:
|
452
321
|
return value % divisor == 0
|
453
|
-
|
322
|
+
if kececi_type == TYPE_FLOAT:
|
454
323
|
return math.isclose(value % divisor, 0)
|
455
|
-
|
324
|
+
if kececi_type == TYPE_RATIONAL:
|
456
325
|
return (value / divisor).denominator == 1
|
457
|
-
|
326
|
+
if kececi_type == TYPE_COMPLEX:
|
458
327
|
return math.isclose(value.real % divisor, 0) and math.isclose(value.imag % divisor, 0)
|
459
|
-
|
328
|
+
if kececi_type == TYPE_QUATERNION:
|
460
329
|
return all(math.isclose(c % divisor, 0) for c in [value.w, value.x, value.y, value.z])
|
461
|
-
|
330
|
+
if kececi_type == TYPE_NEUTROSOPHIC:
|
462
331
|
return math.isclose(value.a % divisor, 0) and math.isclose(value.b % divisor, 0)
|
463
|
-
|
332
|
+
if kececi_type == TYPE_NEUTROSOPHIC_COMPLEX:
|
464
333
|
return all(math.isclose(c % divisor, 0) for c in [value.real, value.imag, value.indeterminacy])
|
465
|
-
|
334
|
+
if kececi_type == TYPE_HYPERREAL:
|
466
335
|
return all(math.isclose(x % divisor, 0) for x in value.sequence)
|
467
|
-
|
468
|
-
return
|
469
|
-
|
470
|
-
elif kececi_type == TYPE_NEUTROSOPHIC_BICOMPLEX:
|
336
|
+
if kececi_type == TYPE_BICOMPLEX:
|
337
|
+
return _is_divisible(value.z1, divisor, TYPE_COMPLEX) and _is_divisible(value.z2, divisor, TYPE_COMPLEX)
|
338
|
+
if kececi_type == TYPE_NEUTROSOPHIC_BICOMPLEX:
|
471
339
|
return all(math.isclose(c % divisor, 0) for c in value.__dict__.values())
|
472
340
|
except (TypeError, ValueError):
|
473
341
|
return False
|
474
342
|
return False
|
475
343
|
|
476
344
|
def _parse_complex(s: str) -> complex:
|
477
|
-
"""
|
478
|
-
Bir string'i kompleks sayıya çevirir.
|
479
|
-
Eğer 'j' içermiyorsa, "3" girdisini 3+3j olarak yorumlar.
|
480
|
-
"""
|
345
|
+
"""Parses a string into a complex number. '3' becomes 3+3j."""
|
481
346
|
s_clean = s.strip().lower()
|
482
347
|
try:
|
483
|
-
# Doğrudan kompleks çevirmeyi dene (ör: "3+4j")
|
484
348
|
c = complex(s_clean)
|
485
|
-
# Eğer girdi "3" gibi sadece reel bir sayıysa ve 'j' içermiyorsa,
|
486
|
-
# onu s_complex.real + s_complex.real*j yap.
|
487
349
|
if c.imag == 0 and 'j' not in s_clean:
|
488
350
|
return complex(c.real, c.real)
|
489
351
|
return c
|
490
352
|
except ValueError as e:
|
491
|
-
raise ValueError(f"
|
353
|
+
raise ValueError(f"Invalid complex number format: '{s}'") from e
|
492
354
|
|
493
|
-
def _parse_neutrosophic(s: str) ->
|
494
|
-
"""
|
495
|
-
Parses a neutrosophic number string of the form 'a+bI' into a tuple (a, b).
|
496
|
-
Handles cases like '5+2I', '3-I', '7', '4I', '-I'.
|
497
|
-
"""
|
355
|
+
def _parse_neutrosophic(s: str) -> Tuple[float, float]:
|
356
|
+
"""Parses a neutrosophic string 'a+bI' into a tuple (a, b)."""
|
498
357
|
s = s.strip().replace(" ", "").upper()
|
499
358
|
if not s:
|
500
359
|
return 0.0, 0.0
|
501
360
|
|
502
|
-
# Eğer 'I' yoksa, bu standart bir sayıdır (b=0)
|
503
361
|
if 'I' not in s:
|
504
|
-
|
505
|
-
return float(s), 0.0
|
506
|
-
except ValueError:
|
507
|
-
raise ValueError(f"Invalid number format for non-neutrosophic part: {s}")
|
362
|
+
return float(s), 0.0
|
508
363
|
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
364
|
+
pattern = re.compile(r"^(?P<a>[+-]?\d+\.?\d*)?(?P<b>[+-]?)I$")
|
365
|
+
match = re.match(r"^(?P<val>[+-]?\d+\.?\d*)$", s)
|
366
|
+
if match: # Just a number
|
367
|
+
return float(match.group('val')), 0.0
|
368
|
+
|
369
|
+
pattern = re.compile(r"^(?P<a>[+-]?\d+\.?\d*)?(?P<b>[+-]?\d*\.?\d*)I$")
|
370
|
+
full_match = pattern.match(s)
|
371
|
+
if not full_match:
|
372
|
+
raise ValueError(f"Invalid neutrosophic format: {s}")
|
373
|
+
|
374
|
+
parts = full_match.groupdict()
|
375
|
+
a_part = parts.get('a') or "0"
|
376
|
+
b_part = parts.get('b')
|
377
|
+
|
378
|
+
if b_part in (None, "", "+"):
|
379
|
+
b_val = 1.0
|
380
|
+
elif b_part == "-":
|
381
|
+
b_val = -1.0
|
519
382
|
else:
|
520
|
-
|
521
|
-
last_plus = a_part_str.rfind('+')
|
522
|
-
last_minus = a_part_str.rfind('-')
|
383
|
+
b_val = float(b_part)
|
523
384
|
|
524
|
-
|
525
|
-
if last_minus == 0 and last_plus == -1:
|
526
|
-
split_pos = -1
|
527
|
-
else:
|
528
|
-
split_pos = max(last_plus, last_minus)
|
529
|
-
|
530
|
-
if split_pos == -1: # Örneğin '3I' durumu
|
531
|
-
a = 0.0
|
532
|
-
b = float(a_part_str)
|
533
|
-
else: # Örneğin '5+3I' veya '-2-4I' durumu
|
534
|
-
a = float(a_part_str[:split_pos])
|
535
|
-
b_str = a_part_str[split_pos:]
|
536
|
-
if b_str == '+':
|
537
|
-
b = 1.0
|
538
|
-
elif b_str == '-':
|
539
|
-
b = -1.0
|
540
|
-
else:
|
541
|
-
b = float(b_str)
|
542
|
-
|
543
|
-
return a, b
|
385
|
+
return float(a_part), b_val
|
544
386
|
|
545
|
-
|
546
|
-
|
547
|
-
'a+be'
|
548
|
-
'5+3e', '-2-e', '10', '4e', '-e' gibi formatları işler.
|
549
|
-
"""
|
387
|
+
|
388
|
+
def _parse_hyperreal(s: str) -> Tuple[float, float]:
|
389
|
+
"""Parses 'a+be' string into a tuple (a, b)."""
|
550
390
|
s = s.strip().replace(" ", "").lower()
|
551
391
|
if not s:
|
552
392
|
return 0.0, 0.0
|
553
|
-
|
554
|
-
# Eğer 'e' yoksa, bu standart bir sayıdır (b=0)
|
555
393
|
if 'e' not in s:
|
556
394
|
return float(s), 0.0
|
557
395
|
|
558
|
-
|
559
|
-
|
560
|
-
match = re.match(r"^(?P<a>[+-]?\d+\.?\d*)?(?P<b>[+-]?\d*\.?\d*)e$", s)
|
396
|
+
pattern = re.compile(r"^(?P<a>[+-]?\d+\.?\d*)?(?P<b>[+-]?\d*\.?\d*)e$")
|
397
|
+
match = pattern.match(s)
|
561
398
|
if not match:
|
562
|
-
|
563
|
-
match = re.match(r"^(?P<a>[+-]?\d+\.?\d*)?(?P<b>[+-])e$", s)
|
564
|
-
|
565
|
-
if not match:
|
566
|
-
raise ValueError(f"Geçersiz hiperreel format: {s}")
|
399
|
+
raise ValueError(f"Invalid hyperreal format: {s}")
|
567
400
|
|
568
401
|
parts = match.groupdict()
|
569
|
-
a_part = parts.get('a')
|
402
|
+
a_part = parts.get('a') or "0"
|
570
403
|
b_part = parts.get('b')
|
571
|
-
|
572
|
-
a = float(a_part) if a_part else 0.0
|
573
404
|
|
574
|
-
if b_part
|
575
|
-
|
576
|
-
elif b_part ==
|
577
|
-
|
405
|
+
if b_part in (None, "", "+"):
|
406
|
+
b_val = 1.0
|
407
|
+
elif b_part == "-":
|
408
|
+
b_val = -1.0
|
578
409
|
else:
|
579
|
-
|
410
|
+
b_val = float(b_part)
|
580
411
|
|
581
|
-
return
|
412
|
+
return float(a_part), b_val
|
582
413
|
|
583
414
|
def _parse_quaternion(s: str) -> np.quaternion:
|
584
|
-
"""
|
585
|
-
Kullanıcıdan gelen metin girdisini ('a+bi+cj+dk' veya sadece skaler)
|
586
|
-
bir kuaterniyon nesnesine çevirir.
|
587
|
-
|
588
|
-
Örnekler:
|
589
|
-
- '2.5' -> quaternion(2.5, 2.5, 2.5, 2.5)
|
590
|
-
- '2.5+2.5i+2.5j+2.5k' -> quaternion(2.5, 2.5, 2.5, 2.5)
|
591
|
-
- '1-2i+3.5j-k' -> quaternion(1, -2, 3.5, -1)
|
592
|
-
"""
|
415
|
+
"""Parses user string ('a+bi+cj+dk' or scalar) into a quaternion."""
|
593
416
|
s_clean = s.replace(" ", "").lower()
|
594
417
|
if not s_clean:
|
595
|
-
raise ValueError("
|
418
|
+
raise ValueError("Input cannot be empty.")
|
596
419
|
|
597
|
-
# Girdinin sadece bir sayı olup olmadığını kontrol et
|
598
420
|
try:
|
599
421
|
val = float(s_clean)
|
600
|
-
# Programın orijinal mantığına göre skalerden kuaterniyon oluştur
|
601
422
|
return np.quaternion(val, val, val, val)
|
602
423
|
except ValueError:
|
603
|
-
# Girdi tam bir kuaterniyon ifadesi, ayrıştırmaya devam et
|
604
424
|
pass
|
605
425
|
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
matches = pattern.findall(s_clean.replace('i', 'i ').replace('j', 'j ').replace('k', 'k ')) # Ayrıştırmayı kolaylaştır
|
610
|
-
|
611
|
-
parts = {'w': 0.0, 'x': 0.0, 'y': 0.0, 'z': 0.0}
|
612
|
-
|
613
|
-
# 'i', 'j', 'k' olmayan katsayıları ('-1k' gibi) düzeltmek için
|
614
|
-
s_temp = s_clean
|
615
|
-
for val_str, comp in re.findall(r'([+-])([ijk])', s_clean):
|
616
|
-
s_temp = s_temp.replace(val_str+comp, f'{val_str}1{comp}')
|
426
|
+
s_temp = re.sub(r'([+-])([ijk])', r'\g<1>1\g<2>', s_clean)
|
427
|
+
if s_temp.startswith(('i', 'j', 'k')):
|
428
|
+
s_temp = '1' + s_temp
|
617
429
|
|
430
|
+
pattern = re.compile(r'([+-]?\d*\.?\d*)([ijk])?')
|
618
431
|
matches = pattern.findall(s_temp)
|
619
|
-
|
620
|
-
|
621
|
-
raise ValueError(f"Geçersiz kuaterniyon formatı: '{s}'")
|
622
|
-
|
432
|
+
|
433
|
+
parts = {'w': 0.0, 'x': 0.0, 'y': 0.0, 'z': 0.0}
|
623
434
|
for value_str, component in matches:
|
435
|
+
if not value_str:
|
436
|
+
continue
|
624
437
|
value = float(value_str)
|
625
438
|
if component == 'i':
|
626
439
|
parts['x'] += value
|
@@ -628,141 +441,98 @@ def _parse_quaternion(s: str) -> np.quaternion:
|
|
628
441
|
parts['y'] += value
|
629
442
|
elif component == 'k':
|
630
443
|
parts['z'] += value
|
631
|
-
else:
|
444
|
+
else:
|
632
445
|
parts['w'] += value
|
633
446
|
|
634
447
|
return np.quaternion(parts['w'], parts['x'], parts['y'], parts['z'])
|
635
448
|
|
636
|
-
def get_random_type(num_iterations, fixed_start_raw="0", fixed_add_base_scalar=9.0):
|
637
|
-
"""
|
638
|
-
Generates Keçeci Numbers for a randomly selected type using fixed parameters.
|
639
|
-
(Updated with the full list of 11 types and compatible with the new get_with_params signature)
|
640
|
-
"""
|
641
|
-
# Rastgele sayı üretme aralığı 11 tipe göre güncellendi.
|
449
|
+
def get_random_type(num_iterations: int, fixed_start_raw: str = "0", fixed_add_base_scalar: float = 9.0) -> List[Any]:
|
450
|
+
"""Generates Keçeci Numbers for a randomly selected type."""
|
642
451
|
random_type_choice = random.randint(1, 11)
|
643
|
-
|
644
|
-
# Kullanıcının sağladığı tam liste eklendi.
|
645
452
|
type_names_list = [
|
646
453
|
"Positive Real", "Negative Real", "Complex", "Float", "Rational",
|
647
454
|
"Quaternion", "Neutrosophic", "Neutro-Complex", "Hyperreal",
|
648
455
|
"Bicomplex", "Neutro-Bicomplex"
|
649
456
|
]
|
650
|
-
|
651
|
-
# Listenin indeksi 0'dan başladığı için random_type_choice-1 kullanılır.
|
652
457
|
print(f"\nRandomly selected Keçeci Number Type: {random_type_choice} ({type_names_list[random_type_choice-1]})")
|
653
458
|
|
654
|
-
|
655
|
-
# Beklenmeyen 'random_range_factor' veya 'fixed_params' argümanları yok.
|
656
|
-
generated_sequence = get_with_params(
|
459
|
+
return get_with_params(
|
657
460
|
kececi_type_choice=random_type_choice,
|
658
461
|
iterations=num_iterations,
|
659
462
|
start_value_raw=fixed_start_raw,
|
660
463
|
add_value_base_scalar=fixed_add_base_scalar
|
661
464
|
)
|
662
|
-
|
663
|
-
return generated_sequence
|
664
465
|
|
665
466
|
# ==============================================================================
|
666
467
|
# --- CORE GENERATOR ---
|
667
468
|
# ==============================================================================
|
668
469
|
|
669
|
-
def unified_generator(kececi_type, start_input_raw, add_input_base_scalar, iterations):
|
670
|
-
"""
|
671
|
-
Herhangi bir desteklenen türde Keçeci Sayı dizileri üreten çekirdek motor.
|
672
|
-
Bu sürüm, tüm tipler için sağlam tür dönüştürme ve özel format ayrıştırma içerir.
|
673
|
-
"""
|
470
|
+
def unified_generator(kececi_type: int, start_input_raw: str, add_input_base_scalar: float, iterations: int) -> List[Any]:
|
471
|
+
"""Core engine to generate Keçeci Number sequences."""
|
674
472
|
current_value = None
|
675
473
|
add_value_typed = None
|
676
474
|
ask_unit = None
|
677
475
|
use_integer_division = False
|
678
476
|
|
679
477
|
try:
|
680
|
-
# --- Adım 1: Keçeci Türüne Göre Başlatma ---
|
681
478
|
a_float = float(add_input_base_scalar)
|
682
479
|
|
683
480
|
if kececi_type in [TYPE_POSITIVE_REAL, TYPE_NEGATIVE_REAL]:
|
684
|
-
|
685
|
-
current_value = s_int
|
481
|
+
current_value = int(float(start_input_raw))
|
686
482
|
add_value_typed = int(a_float)
|
687
483
|
ask_unit = 1
|
688
484
|
use_integer_division = True
|
689
|
-
|
690
485
|
elif kececi_type == TYPE_FLOAT:
|
691
486
|
current_value = float(start_input_raw)
|
692
487
|
add_value_typed = a_float
|
693
488
|
ask_unit = 1.0
|
694
|
-
|
695
489
|
elif kececi_type == TYPE_RATIONAL:
|
696
490
|
current_value = Fraction(start_input_raw)
|
697
491
|
add_value_typed = Fraction(add_input_base_scalar)
|
698
492
|
ask_unit = Fraction(1)
|
699
|
-
|
700
493
|
elif kececi_type == TYPE_COMPLEX:
|
701
494
|
current_value = _parse_complex(start_input_raw)
|
702
495
|
add_value_typed = complex(a_float, a_float)
|
703
496
|
ask_unit = 1 + 1j
|
704
|
-
|
705
497
|
elif kececi_type == TYPE_NEUTROSOPHIC:
|
706
498
|
a, b = _parse_neutrosophic(start_input_raw)
|
707
499
|
current_value = NeutrosophicNumber(a, b)
|
708
500
|
add_value_typed = NeutrosophicNumber(a_float, 0)
|
709
501
|
ask_unit = NeutrosophicNumber(1, 1)
|
710
|
-
|
711
|
-
# --- YENİ EKLENEN/DÜZELTİLEN BLOKLAR ---
|
712
|
-
|
713
|
-
elif kececi_type == TYPE_NEUTROSOPHIC_COMPLEX: # HATA DÜZELTİLDİ
|
502
|
+
elif kececi_type == TYPE_NEUTROSOPHIC_COMPLEX:
|
714
503
|
s_complex = _parse_complex(start_input_raw)
|
715
|
-
# Başlangıç indeterminacy değerini 0 olarak varsayalım
|
716
504
|
current_value = NeutrosophicComplexNumber(s_complex.real, s_complex.imag, 0.0)
|
717
|
-
# Artış, deterministik reel kısma etki eder
|
718
505
|
add_value_typed = NeutrosophicComplexNumber(a_float, 0.0, 0.0)
|
719
506
|
ask_unit = NeutrosophicComplexNumber(1, 1, 1)
|
720
|
-
|
721
|
-
elif kececi_type == TYPE_HYPERREAL: # HATA DÜZELTİLDİ
|
507
|
+
elif kececi_type == TYPE_HYPERREAL:
|
722
508
|
a, b = _parse_hyperreal(start_input_raw)
|
723
|
-
# 'a' reel kısmı, 'b' ise sonsuz küçükleri ölçekler
|
724
509
|
sequence_list = [a + b / n for n in range(1, 11)]
|
725
510
|
current_value = HyperrealNumber(sequence_list)
|
726
|
-
# Artış, sadece standart (ilk) reel kısma etki eder
|
727
511
|
add_sequence = [a_float] + [0.0] * 9
|
728
512
|
add_value_typed = HyperrealNumber(add_sequence)
|
729
513
|
ask_unit = HyperrealNumber([1.0] * 10)
|
730
|
-
|
731
|
-
elif kececi_type == TYPE_BICOMPLEX: # Mantık aynı, sadece ayrıştırıcıyı kullanıyor
|
514
|
+
elif kececi_type == TYPE_BICOMPLEX:
|
732
515
|
s_complex = _parse_complex(start_input_raw)
|
733
516
|
a_complex = complex(a_float)
|
734
517
|
current_value = BicomplexNumber(s_complex, s_complex / 2)
|
735
518
|
add_value_typed = BicomplexNumber(a_complex, a_complex / 2)
|
736
519
|
ask_unit = BicomplexNumber(complex(1, 1), complex(0.5, 0.5))
|
737
|
-
|
738
|
-
elif kececi_type == TYPE_NEUTROSOPHIC_BICOMPLEX: # HATA DÜZELTİLDİ
|
520
|
+
elif kececi_type == TYPE_NEUTROSOPHIC_BICOMPLEX:
|
739
521
|
s_complex = _parse_complex(start_input_raw)
|
740
|
-
# Başlangıç değeri olarak kompleks sayıyı kullanıp diğer 6 bileşeni 0 yapalım
|
741
522
|
current_value = NeutrosophicBicomplexNumber(s_complex.real, s_complex.imag, 0, 0, 0, 0, 0, 0)
|
742
|
-
# Artış, sadece ana reel kısma etki eder
|
743
523
|
add_value_typed = NeutrosophicBicomplexNumber(a_float, 0, 0, 0, 0, 0, 0, 0)
|
744
524
|
ask_unit = NeutrosophicBicomplexNumber(*([1.0] * 8))
|
745
|
-
|
746
|
-
# --- DİĞER TİPLER ---
|
747
|
-
|
748
525
|
elif kececi_type == TYPE_QUATERNION:
|
749
|
-
# Artık girdiyi doğrudan float'a çevirmek yerine,
|
750
|
-
# hem skaler hem de tam ifadeyi ayrıştırabilen fonksiyonu kullanıyoruz.
|
751
526
|
current_value = _parse_quaternion(start_input_raw)
|
752
|
-
|
753
|
-
# Artırım değeri (add_value) genellikle basit bir skalerdir,
|
754
|
-
# bu yüzden bu kısım aynı kalabilir.
|
755
527
|
add_value_typed = np.quaternion(a_float, a_float, a_float, a_float)
|
756
528
|
ask_unit = np.quaternion(1, 1, 1, 1)
|
757
|
-
|
758
529
|
else:
|
759
|
-
raise ValueError(f"
|
530
|
+
raise ValueError(f"Invalid Keçeci Number Type: {kececi_type}")
|
760
531
|
|
761
532
|
except (ValueError, TypeError) as e:
|
762
|
-
print(f"
|
533
|
+
print(f"ERROR: Failed to initialize type {kececi_type} with input '{start_input_raw}': {e}")
|
763
534
|
return []
|
764
535
|
|
765
|
-
# --- Adım 2: İterasyon Döngüsü ---
|
766
536
|
sequence = [current_value]
|
767
537
|
last_divisor_used = None
|
768
538
|
ask_counter = 0
|
@@ -802,44 +572,29 @@ def unified_generator(kececi_type, start_input_raw, add_input_base_scalar, itera
|
|
802
572
|
|
803
573
|
return sequence
|
804
574
|
|
805
|
-
def print_detailed_report(sequence, params):
|
806
|
-
"""
|
807
|
-
Generates and prints a detailed report of the Keçeci sequence results.
|
808
|
-
|
809
|
-
Args:
|
810
|
-
sequence (list): The generated Keçeci sequence.
|
811
|
-
params (dict): A dictionary containing the generation parameters.
|
812
|
-
"""
|
575
|
+
def print_detailed_report(sequence: List[Any], params: Dict[str, Any]):
|
576
|
+
"""Generates and prints a detailed report of the sequence results."""
|
813
577
|
if not sequence:
|
814
|
-
print("\n--- REPORT
|
815
|
-
print("Sequence could not be generated. No report to show.")
|
578
|
+
print("\n--- REPORT ---\nSequence could not be generated.")
|
816
579
|
return
|
817
580
|
|
818
581
|
print("\n\n" + "="*50)
|
819
582
|
print("--- DETAILED SEQUENCE REPORT ---")
|
820
583
|
print("="*50)
|
821
584
|
|
822
|
-
# Parametreleri yazdır
|
823
585
|
print("\n[Parameters Used]")
|
824
|
-
print(f" - Keçeci Type: {params
|
586
|
+
print(f" - Keçeci Type: {params.get('type_name', 'N/A')} ({params['type_choice']})")
|
825
587
|
print(f" - Start Value: '{params['start_val']}'")
|
826
588
|
print(f" - Increment: {params['add_val']}")
|
827
589
|
print(f" - Keçeci Steps: {params['steps']}")
|
828
590
|
|
829
|
-
# Dizi Özeti
|
830
591
|
print("\n[Sequence Summary]")
|
831
592
|
print(f" - Total Numbers Generated: {len(sequence)}")
|
832
593
|
|
833
|
-
# Keçeci Asal Sayısı (KPN) sonucunu bul ve yazdır
|
834
594
|
kpn = find_kececi_prime_number(sequence)
|
835
|
-
if kpn is not None
|
836
|
-
print(f" - Keçeci Prime Number (KPN): {kpn}")
|
837
|
-
else:
|
838
|
-
print(" - Keçeci Prime Number (KPN): Not found in this sequence.")
|
595
|
+
print(f" - Keçeci Prime Number (KPN): {kpn if kpn is not None else 'Not found'}")
|
839
596
|
|
840
|
-
# Dizi Önizlemesi
|
841
597
|
print("\n[Sequence Preview]")
|
842
|
-
# Dizinin tamamını yazdırmadan önce bir önizleme sunalım
|
843
598
|
preview_count = min(len(sequence), 5)
|
844
599
|
print(f" --- First {preview_count} Numbers ---")
|
845
600
|
for i in range(preview_count):
|
@@ -852,7 +607,6 @@ def print_detailed_report(sequence, params):
|
|
852
607
|
|
853
608
|
print("\n" + "="*50)
|
854
609
|
|
855
|
-
# Kullanıcıya tüm diziyi görmek isteyip istemediğini sor
|
856
610
|
while True:
|
857
611
|
show_all = input("Do you want to print the full sequence? (y/n): ").lower().strip()
|
858
612
|
if show_all in ['y', 'n']:
|
@@ -868,18 +622,13 @@ def print_detailed_report(sequence, params):
|
|
868
622
|
# --- HIGH-LEVEL CONTROL FUNCTIONS ---
|
869
623
|
# ==============================================================================
|
870
624
|
|
871
|
-
def get_with_params(kececi_type_choice, iterations, start_value_raw="0", add_value_base_scalar=9.0):
|
872
|
-
"""
|
873
|
-
Generates Keçeci Numbers with specified parameters.
|
874
|
-
"""
|
625
|
+
def get_with_params(kececi_type_choice: int, iterations: int, start_value_raw: str = "0", add_value_base_scalar: float = 9.0) -> List[Any]:
|
626
|
+
"""Generates Keçeci Numbers with specified parameters."""
|
875
627
|
print(f"\n--- Generating Sequence: Type {kececi_type_choice}, Steps {iterations} ---")
|
876
628
|
print(f"Start: '{start_value_raw}', Increment: {add_value_base_scalar}")
|
877
629
|
|
878
630
|
generated_sequence = unified_generator(
|
879
|
-
kececi_type_choice,
|
880
|
-
start_value_raw,
|
881
|
-
add_value_base_scalar,
|
882
|
-
iterations
|
631
|
+
kececi_type_choice, start_value_raw, add_value_base_scalar, iterations
|
883
632
|
)
|
884
633
|
|
885
634
|
if generated_sequence:
|
@@ -894,11 +643,8 @@ def get_with_params(kececi_type_choice, iterations, start_value_raw="0", add_val
|
|
894
643
|
|
895
644
|
return generated_sequence
|
896
645
|
|
897
|
-
def get_interactive():
|
898
|
-
"""
|
899
|
-
Interactively gets parameters from the user and generates Keçeci Numbers.
|
900
|
-
This version only gets data and returns the sequence without plotting.
|
901
|
-
"""
|
646
|
+
def get_interactive() -> Tuple[List[Any], Dict[str, Any]]:
|
647
|
+
"""Interactively gets parameters from the user to generate a sequence."""
|
902
648
|
print("\n--- Keçeci Number Interactive Generator ---")
|
903
649
|
print(" 1: Positive Real 2: Negative Real 3: Complex")
|
904
650
|
print(" 4: Float 5: Rational 6: Quaternion")
|
@@ -907,242 +653,156 @@ def get_interactive():
|
|
907
653
|
|
908
654
|
while True:
|
909
655
|
try:
|
910
|
-
type_choice = int(input(
|
911
|
-
if 1 <= type_choice <= 11:
|
912
|
-
|
913
|
-
|
656
|
+
type_choice = int(input("Select Keçeci Number Type (1-11): "))
|
657
|
+
if 1 <= type_choice <= 11:
|
658
|
+
break
|
659
|
+
print("Invalid type. Please enter a number between 1 and 11.")
|
660
|
+
except ValueError:
|
661
|
+
print("Invalid input. Please enter a number.")
|
914
662
|
|
915
|
-
# Her tip için özel başlangıç değeri istemleri (prompts)
|
916
663
|
prompts = {
|
917
|
-
1:
|
918
|
-
2:
|
919
|
-
3:
|
920
|
-
4:
|
921
|
-
5:
|
922
|
-
6:
|
923
|
-
7:
|
924
|
-
8:
|
925
|
-
9:
|
664
|
+
1: "Enter positive integer start (e.g., '10'): ",
|
665
|
+
2: "Enter negative integer start (e.g., '-5'): ",
|
666
|
+
3: "Enter complex start (e.g., '3+4j' or '3' for 3+3j): ",
|
667
|
+
4: "Enter float start (e.g., '3.14'): ",
|
668
|
+
5: "Enter rational start (e.g., '7/2' or '5'): ",
|
669
|
+
6: "Enter quaternion (e.g., '1+2i-3j+k' or '2.5'): ",
|
670
|
+
7: "Enter neutrosophic start (e.g., '5+2I' or '7'): ",
|
671
|
+
8: "Enter complex base for neutro-complex (e.g., '1-2j'): ",
|
672
|
+
9: "Enter hyperreal start (e.g., '5+3e' or '10'): ",
|
926
673
|
10: "Enter complex base for bicomplex (e.g., '2+1j'): ",
|
927
674
|
11: "Enter complex base for neutro-bicomplex (e.g., '1+2j'): "
|
928
675
|
}
|
929
676
|
|
930
|
-
# Seçilen tipe göre doğru istemi al, yoksa genel bir istem kullan
|
931
677
|
start_prompt = prompts.get(type_choice, "Enter starting value: ")
|
932
|
-
|
933
678
|
start_input_val_raw = input(start_prompt)
|
934
|
-
add_base_scalar_val = float(input("Enter base scalar increment (e.g., 9.0
|
679
|
+
add_base_scalar_val = float(input("Enter base scalar increment (e.g., 9.0): "))
|
935
680
|
num_kececi_steps = int(input("Enter number of Keçeci steps (e.g., 15): "))
|
936
681
|
|
937
|
-
# Diziyi oluştur ve çizdir
|
938
682
|
sequence = get_with_params(type_choice, num_kececi_steps, start_input_val_raw, add_base_scalar_val)
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
return sequence,
|
683
|
+
|
684
|
+
params = {
|
685
|
+
"type_choice": type_choice,
|
686
|
+
"start_val": start_input_val_raw,
|
687
|
+
"add_val": add_base_scalar_val,
|
688
|
+
"steps": num_kececi_steps
|
689
|
+
}
|
690
|
+
return sequence, params
|
947
691
|
|
948
692
|
# ==============================================================================
|
949
693
|
# --- ANALYSIS AND PLOTTING ---
|
950
694
|
# ==============================================================================
|
951
695
|
|
952
|
-
def find_kececi_prime_number(kececi_numbers_list):
|
953
|
-
"""
|
954
|
-
Finds the Keçeci Prime Number from a generated sequence.
|
955
|
-
|
956
|
-
The Keçeci Prime is the integer representation of the most frequent number
|
957
|
-
in the sequence whose principal component is itself prime. Ties in frequency
|
958
|
-
are broken by choosing the larger prime number.
|
959
|
-
"""
|
696
|
+
def find_kececi_prime_number(kececi_numbers_list: List[Any]) -> Optional[int]:
|
697
|
+
"""Finds the Keçeci Prime Number from a generated sequence."""
|
960
698
|
if not kececi_numbers_list:
|
961
699
|
return None
|
962
700
|
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
# This logic is duplicated from is_prime to get the value itself
|
968
|
-
value = 0
|
969
|
-
if isinstance(num, (int, float, Fraction)): value = abs(int(num))
|
970
|
-
elif isinstance(num, complex): value = abs(int(num.real))
|
971
|
-
elif isinstance(num, np.quaternion): value = abs(int(num.w))
|
972
|
-
elif isinstance(num, NeutrosophicNumber): value = abs(int(num.a))
|
973
|
-
elif isinstance(num, NeutrosophicComplexNumber): value = abs(int(num.real))
|
974
|
-
elif isinstance(num, HyperrealNumber): value = abs(int(num.sequence[0])) if num.sequence else 0
|
975
|
-
elif isinstance(num, BicomplexNumber): value = abs(int(num.z1.real))
|
976
|
-
elif isinstance(num, NeutrosophicBicomplexNumber): value = abs(int(num.real))
|
977
|
-
integer_prime_reps.append(value)
|
701
|
+
integer_prime_reps = [
|
702
|
+
rep for num in kececi_numbers_list
|
703
|
+
if is_prime(num) and (rep := _get_integer_representation(num)) is not None
|
704
|
+
]
|
978
705
|
|
979
706
|
if not integer_prime_reps:
|
980
707
|
return None
|
981
708
|
|
982
|
-
# Count frequencies of these prime integers
|
983
709
|
counts = collections.Counter(integer_prime_reps)
|
984
|
-
|
985
|
-
# Find primes that repeat
|
986
710
|
repeating_primes = [(freq, prime) for prime, freq in counts.items() if freq > 1]
|
987
|
-
|
988
711
|
if not repeating_primes:
|
989
712
|
return None
|
990
713
|
|
991
|
-
# Find the one with the highest frequency, using the prime value as a tie-breaker
|
992
714
|
_, best_prime = max(repeating_primes)
|
993
715
|
return best_prime
|
994
716
|
|
995
|
-
def plot_numbers(sequence, title="Keçeci Number Sequence Analysis"):
|
996
|
-
"""
|
997
|
-
Plots the generated Keçeci Number sequence with appropriate, detailed
|
998
|
-
visualizations for each number type.
|
999
|
-
"""
|
717
|
+
def plot_numbers(sequence: List[Any], title: str = "Keçeci Number Sequence Analysis"):
|
718
|
+
"""Plots the generated sequence with detailed visualizations for each type."""
|
1000
719
|
plt.style.use('seaborn-v0_8-whitegrid')
|
1001
720
|
|
1002
721
|
if not sequence:
|
1003
722
|
print("Sequence is empty, nothing to plot.")
|
1004
723
|
return
|
1005
724
|
|
1006
|
-
fig = plt.figure(figsize=(16, 9))
|
725
|
+
fig = plt.figure(figsize=(16, 9))
|
1007
726
|
plt.suptitle(title, fontsize=16, y=0.98)
|
1008
727
|
first_elem = sequence[0]
|
1009
728
|
|
1010
|
-
# --- Her Türe Özel Çizim Mantığı ---
|
1011
|
-
|
1012
729
|
if isinstance(first_elem, (int, float, Fraction)):
|
1013
730
|
ax = fig.add_subplot(1, 1, 1)
|
1014
731
|
ax.plot([float(x) for x in sequence], 'o-', label="Value")
|
1015
732
|
ax.set_title("Value over Iterations")
|
1016
|
-
ax.set_xlabel("Index")
|
1017
|
-
ax.set_ylabel("Value")
|
1018
|
-
ax.legend()
|
733
|
+
ax.set_xlabel("Index"), ax.set_ylabel("Value"), ax.legend()
|
1019
734
|
|
1020
735
|
elif isinstance(first_elem, complex):
|
1021
736
|
gs = GridSpec(2, 2, figure=fig)
|
1022
|
-
ax1 = fig.add_subplot(gs[0, 0])
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
real_parts = [c.real for c in sequence]
|
1027
|
-
imag_parts = [c.imag for c in sequence]
|
1028
|
-
|
1029
|
-
ax1.plot(real_parts, 'o-', label='Real Part')
|
1030
|
-
ax1.set_title("Real Part"); ax1.legend()
|
1031
|
-
|
1032
|
-
ax2.plot(imag_parts, 'o-', color='red', label='Imaginary Part')
|
1033
|
-
ax2.set_title("Imaginary Part"); ax2.legend()
|
1034
|
-
|
737
|
+
ax1, ax2, ax3 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[0, 1]), fig.add_subplot(gs[1, :])
|
738
|
+
real_parts, imag_parts = [c.real for c in sequence], [c.imag for c in sequence]
|
739
|
+
ax1.plot(real_parts, 'o-', label='Real Part'), ax1.set_title("Real Part"), ax1.legend()
|
740
|
+
ax2.plot(imag_parts, 'o-', color='red', label='Imaginary Part'), ax2.set_title("Imaginary Part"), ax2.legend()
|
1035
741
|
ax3.plot(real_parts, imag_parts, '.-', label='Trajectory')
|
1036
742
|
ax3.scatter(real_parts[0], imag_parts[0], c='g', s=100, label='Start', zorder=5)
|
1037
743
|
ax3.scatter(real_parts[-1], imag_parts[-1], c='r', s=100, label='End', zorder=5)
|
1038
|
-
ax3.set_title("Trajectory in Complex Plane")
|
744
|
+
ax3.set_title("Trajectory in Complex Plane"), ax3.set_xlabel("Real"), ax3.set_ylabel("Imaginary"), ax3.legend(), ax3.axis('equal')
|
1039
745
|
|
1040
746
|
elif isinstance(first_elem, np.quaternion):
|
1041
747
|
gs = GridSpec(2, 1, figure=fig)
|
1042
|
-
ax1 = fig.add_subplot(gs[0, 0])
|
1043
|
-
|
1044
|
-
|
1045
|
-
ax1.
|
1046
|
-
|
1047
|
-
|
1048
|
-
ax1.plot([q.z for q in sequence], 'd--', label='z')
|
1049
|
-
ax1.set_title("Quaternion Components over Iterations"); ax1.legend()
|
1050
|
-
|
1051
|
-
magnitudes = [np.sqrt(q.w**2 + q.x**2 + q.y**2 + q.z**2) for q in sequence]
|
1052
|
-
ax2.plot(magnitudes, 'o-', color='purple', label='Magnitude')
|
1053
|
-
ax2.set_title("Quaternion Magnitude over Iterations"); ax2.legend()
|
1054
|
-
ax2.set_xlabel("Index")
|
748
|
+
ax1, ax2 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[1, 0], sharex=ax1)
|
749
|
+
ax1.plot([q.w for q in sequence], 'o-', label='w (scalar)'), ax1.plot([q.x for q in sequence], 's--', label='x')
|
750
|
+
ax1.plot([q.y for q in sequence], '^--', label='y'), ax1.plot([q.z for q in sequence], 'd--', label='z')
|
751
|
+
ax1.set_title("Quaternion Components"), ax1.legend()
|
752
|
+
magnitudes = [abs(q) for q in sequence]
|
753
|
+
ax2.plot(magnitudes, 'o-', color='purple', label='Magnitude'), ax2.set_title("Magnitude"), ax2.legend(), ax2.set_xlabel("Index")
|
1055
754
|
|
1056
755
|
elif isinstance(first_elem, BicomplexNumber):
|
1057
756
|
gs = GridSpec(2, 2, figure=fig)
|
1058
|
-
ax1 = fig.add_subplot(gs[0, 0])
|
1059
|
-
|
1060
|
-
|
1061
|
-
z1r =
|
1062
|
-
z2r =
|
1063
|
-
|
1064
|
-
|
1065
|
-
ax1.set_title("Component z1"); ax1.legend()
|
1066
|
-
|
1067
|
-
ax2.plot(z2r, label='z2.real'); ax2.plot(z2i, label='z2.imag')
|
1068
|
-
ax2.set_title("Component z2"); ax2.legend()
|
1069
|
-
|
1070
|
-
ax3.plot(z1r, z1i, '.-'); ax3.set_title("z1 Trajectory"); ax3.set_xlabel("Real"); ax3.set_ylabel("Imaginary")
|
1071
|
-
ax4.plot(z2r, z2i, '.-'); ax4.set_title("z2 Trajectory"); ax4.set_xlabel("Real"); ax4.set_ylabel("Imaginary")
|
757
|
+
ax1, ax2, ax3, ax4 = fig.add_subplot(gs[0,0]), fig.add_subplot(gs[0,1]), fig.add_subplot(gs[1,0]), fig.add_subplot(gs[1,1])
|
758
|
+
z1r, z1i = [x.z1.real for x in sequence], [x.z1.imag for x in sequence]
|
759
|
+
z2r, z2i = [x.z2.real for x in sequence], [x.z2.imag for x in sequence]
|
760
|
+
ax1.plot(z1r, label='z1.real'), ax1.plot(z1i, label='z1.imag'), ax1.set_title("Component z1"), ax1.legend()
|
761
|
+
ax2.plot(z2r, label='z2.real'), ax2.plot(z2i, label='z2.imag'), ax2.set_title("Component z2"), ax2.legend()
|
762
|
+
ax3.plot(z1r, z1i, '.-'), ax3.set_title("z1 Trajectory"), ax3.set_xlabel("Real"), ax3.set_ylabel("Imaginary")
|
763
|
+
ax4.plot(z2r, z2i, '.-'), ax4.set_title("z2 Trajectory"), ax4.set_xlabel("Real"), ax4.set_ylabel("Imaginary")
|
1072
764
|
|
1073
765
|
elif isinstance(first_elem, NeutrosophicNumber):
|
1074
766
|
gs = GridSpec(1, 2, figure=fig)
|
1075
|
-
ax1 = fig.add_subplot(gs[0, 0])
|
1076
|
-
|
1077
|
-
a =
|
1078
|
-
ax1.plot(a, label='Determinate (a)'); ax1.plot(b, label='Indeterminate (b)')
|
1079
|
-
ax1.set_title("Components over Iterations"); ax1.legend()
|
1080
|
-
|
767
|
+
ax1, ax2 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[0, 1])
|
768
|
+
a, b = [x.a for x in sequence], [x.b for x in sequence]
|
769
|
+
ax1.plot(a, label='Determinate (a)'), ax1.plot(b, label='Indeterminate (b)'), ax1.set_title("Components"), ax1.legend()
|
1081
770
|
sc = ax2.scatter(a, b, c=range(len(a)), cmap='viridis')
|
1082
|
-
ax2.set_title("Trajectory
|
771
|
+
ax2.set_title("Trajectory"), ax2.set_xlabel("Determinate"), ax2.set_ylabel("Indeterminate"), fig.colorbar(sc, ax=ax2, label="Iteration")
|
1083
772
|
|
1084
773
|
elif isinstance(first_elem, NeutrosophicComplexNumber):
|
1085
774
|
gs = GridSpec(2, 1, figure=fig)
|
1086
|
-
ax1 = fig.add_subplot(gs[0, 0])
|
1087
|
-
|
1088
|
-
r =
|
1089
|
-
ax1.
|
1090
|
-
ax1.set_title("Components over Iterations"); ax1.legend()
|
1091
|
-
|
775
|
+
ax1, ax2 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[1, 0])
|
776
|
+
r, i, ind = [x.real for x in sequence], [x.imag for x in sequence], [x.indeterminacy for x in sequence]
|
777
|
+
ax1.plot(r, label='Real'), ax1.plot(i, label='Imag'), ax1.plot(ind, label='Indeterminacy', linestyle=':')
|
778
|
+
ax1.set_title("Components"), ax1.legend()
|
1092
779
|
sc = ax2.scatter(r, i, c=ind, cmap='magma', s=20)
|
1093
|
-
ax2.set_title("Trajectory
|
1094
|
-
|
1095
|
-
fig.colorbar(sc, ax=ax2, label='Indeterminacy')
|
1096
|
-
ax2.axis('equal')
|
780
|
+
ax2.set_title("Trajectory (colored by Indeterminacy)"), ax2.set_xlabel("Real"), ax2.set_ylabel("Imaginary")
|
781
|
+
fig.colorbar(sc, ax=ax2, label='Indeterminacy'), ax2.axis('equal')
|
1097
782
|
|
1098
|
-
# --- YENİ EKLENEN BLOKLAR ---
|
1099
|
-
|
1100
783
|
elif isinstance(first_elem, HyperrealNumber):
|
1101
784
|
gs = GridSpec(2, 1, figure=fig)
|
1102
|
-
ax1 = fig.add_subplot(gs[0, 0])
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
for
|
1108
|
-
comp_data = [h.sequence[i] for h in sequence]
|
1109
|
-
ax1.plot(comp_data, label=f'Component {i}')
|
1110
|
-
ax1.set_title("Hyperreal Components over Iterations"); ax1.legend()
|
1111
|
-
|
1112
|
-
# En önemli iki bileşenin yörüngesini çiz
|
1113
|
-
comp0 = [h.sequence[0] for h in sequence]
|
1114
|
-
comp1 = [h.sequence[1] for h in sequence]
|
785
|
+
ax1, ax2 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[1, 0])
|
786
|
+
num_components = min(len(first_elem.sequence), 4)
|
787
|
+
for i in range(num_components):
|
788
|
+
ax1.plot([h.sequence[i] for h in sequence], label=f'Comp {i}')
|
789
|
+
ax1.set_title("Hyperreal Components"), ax1.legend()
|
790
|
+
comp0, comp1 = [h.sequence[0] for h in sequence], [h.sequence[1] for h in sequence]
|
1115
791
|
sc = ax2.scatter(comp0, comp1, c=range(len(comp0)), cmap='plasma')
|
1116
|
-
ax2.set_title("Trajectory
|
1117
|
-
ax2.set_xlabel("Standard Part (C0)"); ax2.set_ylabel("Primary Infinitesimal (C1)")
|
1118
|
-
fig.colorbar(sc, ax=ax2, label="Iteration")
|
792
|
+
ax2.set_title("Trajectory (C0 vs C1)"), ax2.set_xlabel("C0"), ax2.set_ylabel("C1"), fig.colorbar(sc, ax=ax2, label="Iteration")
|
1119
793
|
|
1120
794
|
elif isinstance(first_elem, NeutrosophicBicomplexNumber):
|
1121
795
|
gs = GridSpec(2, 2, figure=fig)
|
1122
|
-
ax1 = fig.add_subplot(gs[0, 0])
|
1123
|
-
ax3 = fig.add_subplot(gs[1, 0])
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
ax1.set_title("Primary Deterministic Plane"); ax1.legend()
|
1129
|
-
|
1130
|
-
nr = [n.neut_real for n in sequence]; ni = [n.neut_imag for n in sequence]
|
1131
|
-
ax2.plot(nr, ni, '.-', label='(I, I*i1)')
|
1132
|
-
ax2.set_title("Primary Neutrosophic Plane"); ax2.legend()
|
1133
|
-
|
1134
|
-
jr = [n.j_real for n in sequence]; ji = [n.j_imag for n in sequence]
|
1135
|
-
ax3.plot(jr, ji, '.-', label='(i2, i1*i2)')
|
1136
|
-
ax3.set_title("Secondary Deterministic Plane"); ax3.legend()
|
796
|
+
ax1, ax2 = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[0, 1])
|
797
|
+
ax3, ax4 = fig.add_subplot(gs[1, 0]), fig.add_subplot(gs[1, 1])
|
798
|
+
ax1.plot([n.real for n in sequence], [n.imag for n in sequence], '.-'), ax1.set_title("Primary Deterministic")
|
799
|
+
ax2.plot([n.neut_real for n in sequence], [n.neut_imag for n in sequence], '.-'), ax2.set_title("Primary Neutrosophic")
|
800
|
+
ax3.plot([n.j_real for n in sequence], [n.j_imag for n in sequence], '.-'), ax3.set_title("Secondary Deterministic")
|
801
|
+
ax4.plot([n.j_neut_real for n in sequence], [n.j_neut_imag for n in sequence], '.-'), ax4.set_title("Secondary Neutrosophic")
|
1137
802
|
|
1138
|
-
|
1139
|
-
ax4.plot(njr, nji, '.-', label='(I*i2, I*i1*i2)')
|
1140
|
-
ax4.set_title("Secondary Neutrosophic Plane"); ax4.legend()
|
1141
|
-
|
1142
|
-
else: # Gelecekte eklenebilecek diğer tipler için yedek blok
|
803
|
+
else:
|
1143
804
|
ax = fig.add_subplot(1, 1, 1)
|
1144
|
-
ax.text(0.5, 0.5, f"Plotting for
|
1145
|
-
ha='center', va='center', fontsize=12, bbox=dict(facecolor='lightyellow'))
|
805
|
+
ax.text(0.5, 0.5, f"Plotting for '{type(first_elem).__name__}' not implemented.", ha='center')
|
1146
806
|
|
1147
807
|
plt.tight_layout(rect=[0, 0, 1, 0.96])
|
1148
808
|
|
@@ -1153,45 +813,35 @@ if __name__ == "__main__":
|
|
1153
813
|
print("="*60)
|
1154
814
|
print(" Keçeci Numbers Module - Demonstration")
|
1155
815
|
print("="*60)
|
1156
|
-
print(
|
816
|
+
print("This script demonstrates the generation of various Keçeci Number types.")
|
1157
817
|
|
1158
818
|
# --- Example 1: Interactive Mode ---
|
1159
|
-
#
|
1160
|
-
# get_interactive()
|
819
|
+
# Uncomment the following lines to run in interactive mode:
|
820
|
+
# seq, params = get_interactive()
|
821
|
+
# if seq:
|
822
|
+
# plot_numbers(seq, title=f"Keçeci Type {params['type_choice']} Sequence")
|
823
|
+
# plt.show()
|
1161
824
|
|
1162
825
|
# --- Example 2: Programmatic Generation and Plotting ---
|
1163
|
-
# We will generate a sequence for each type to test the system.
|
1164
826
|
print("\nRunning programmatic tests for all 11 number types...")
|
1165
827
|
|
1166
|
-
|
1167
|
-
STEPS = 15
|
828
|
+
STEPS = 30
|
1168
829
|
START_VAL = "2.5"
|
1169
830
|
ADD_VAL = 3.0
|
1170
831
|
|
1171
832
|
all_types = {
|
1172
|
-
"Positive Real": TYPE_POSITIVE_REAL,
|
1173
|
-
"
|
1174
|
-
"
|
1175
|
-
"
|
1176
|
-
"
|
1177
|
-
"Quaternion": TYPE_QUATERNION,
|
1178
|
-
"Neutrosophic": TYPE_NEUTROSOPHIC,
|
1179
|
-
"Neutrosophic Complex": TYPE_NEUTROSOPHIC_COMPLEX,
|
1180
|
-
"Hyperreal": TYPE_HYPERREAL,
|
1181
|
-
"Bicomplex": TYPE_BICOMPLEX,
|
1182
|
-
"Neutrosophic Bicomplex": TYPE_NEUTROSOPHIC_BICOMPLEX
|
833
|
+
"Positive Real": TYPE_POSITIVE_REAL, "Negative Real": TYPE_NEGATIVE_REAL,
|
834
|
+
"Complex": TYPE_COMPLEX, "Float": TYPE_FLOAT, "Rational": TYPE_RATIONAL,
|
835
|
+
"Quaternion": TYPE_QUATERNION, "Neutrosophic": TYPE_NEUTROSOPHIC,
|
836
|
+
"Neutrosophic Complex": TYPE_NEUTROSOPHIC_COMPLEX, "Hyperreal": TYPE_HYPERREAL,
|
837
|
+
"Bicomplex": TYPE_BICOMPLEX, "Neutrosophic Bicomplex": TYPE_NEUTROSOPHIC_BICOMPLEX
|
1183
838
|
}
|
1184
839
|
|
1185
|
-
# Generate and plot for a few selected types
|
1186
840
|
types_to_plot = [
|
1187
|
-
"Complex",
|
1188
|
-
"Quaternion",
|
1189
|
-
"Bicomplex",
|
1190
|
-
"Neutrosophic Complex"
|
841
|
+
"Complex", "Quaternion", "Bicomplex", "Neutrosophic Complex", "Hyperreal"
|
1191
842
|
]
|
1192
843
|
|
1193
844
|
for name, type_id in all_types.items():
|
1194
|
-
# Adjust start/add values for specific types if needed
|
1195
845
|
start = "-5" if type_id == TYPE_NEGATIVE_REAL else "2+3j" if type_id in [TYPE_COMPLEX, TYPE_BICOMPLEX] else START_VAL
|
1196
846
|
|
1197
847
|
seq = get_with_params(type_id, STEPS, start, ADD_VAL)
|