PyPyNum 1.16.0__py3-none-any.whl → 1.16.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyPyNum
3
- Version: 1.16.0
3
+ Version: 1.16.1
4
4
  Summary: PyPyNum is a Python library for math & science computations, covering algebra, calculus, stats, with data structures like matrices, vectors, tensors. It offers numerical tools, programs, and supports computational ops, functions, processing, simulation, & visualization in data science & ML, crucial for research, engineering, & data processing.
5
5
  Home-page: https://github.com/PythonSJL/PyPyNum
6
6
  Author: Shen Jiayi
@@ -234,7 +234,7 @@ processing.</font><font color = red>[Python>=3.4]</font>
234
234
  [![Downloads](https://static.pepy.tech/badge/pypynum/month)](https://pepy.tech/project/pypynum)
235
235
  [![Downloads](https://static.pepy.tech/badge/pypynum/week)](https://pepy.tech/project/pypynum)
236
236
 
237
- ## Version -> 1.16.0 | PyPI -> https://pypi.org/project/PyPyNum/ | Gitee -> https://www.gitee.com/PythonSJL/PyPyNum | GitHub -> https://github.com/PythonSJL/PyPyNum
237
+ ## PyPyNum | Version -> 1.16.1 | PyPI -> https://pypi.org/project/PyPyNum/ | Gitee -> https://www.gitee.com/PythonSJL/PyPyNum | GitHub -> https://github.com/PythonSJL/PyPyNum
238
238
 
239
239
  ![LOGO](PyPyNum.png)
240
240
 
@@ -327,72 +327,70 @@ Python interpreter and run it!
327
327
  ```
328
328
  !=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
329
329
 
330
- The submodule 'consts' has added
331
- a large number of mathematical
332
- and scientific constants,
333
- currently totaling 128.
330
+ Fixed and improved the basic
331
+ operation function of 'Array'.
334
332
 
335
- This module defines a collection
336
- of constants representing
337
- various physical, mathematical,
338
- and unit conversion factors.
339
-
340
- These constants are commonly
341
- used in scientific and
342
- engineering calculations.
333
+ !=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
343
334
 
344
- If you want to know information
345
- about each constant, you can
346
- execute 'help(consts)' to
347
- obtain it.
335
+ We will remove 'Tensor' in
336
+ future versions. Because its
337
+ computational functions have
338
+ already been implemented in
339
+ 'Array'. The current version
340
+ will throw 'FutureWarning' as a
341
+ warning.
348
342
 
349
343
  !=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
350
344
 
345
+ Fixed the calculation error of
346
+ 'mp_euler_gamma', which was
347
+ caused when modifying the
348
+ iteration stop condition
349
+ previously.
351
350
 
352
- <<< Here are the newly added functions >>>
351
+ !=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
353
352
 
353
+ <<< Here are the newly added functions >>>
354
354
 
355
- PyPyNum
356
- ├── special
357
- │ └── FUNCTION
358
- │ ├── qbinomial(n: typing.Union[int, float, complex], m: typing.Union[int, float, complex], q: typing.Union[int, float, complex]) -> typing.Union[int, float, complex]
359
- │ │ # Calculate the q-binomial coefficient of n and m with parameter q.
360
- │ ├── qfactorial(n: typing.Union[int, float, complex], q: typing.Union[int, float, complex]) -> typing.Union[int, float, complex]
361
- │ │ # Compute the q-factorial of n with parameter q.
362
- │ ├── qgamma(n: typing.Union[int, float, complex], q: typing.Union[int, float, complex]) -> typing.Union[int, float, complex]
363
- │ │ # Calculate the q-gamma function of n with parameter q.
364
- │ └── qpochhammer(a: typing.Union[int, float, complex], q: typing.Union[int, float, complex], n: typing.Union[int, float, complex]) -> typing.Union[int, float, complex]
365
- │ # Compute the q-Pochhammer symbol for given a, q, and n.
366
- ├── multiprec
367
- │ └── FUNCTION
368
- │ ├── mp_catalan(sigfigs: int) -> decimal.Decimal
369
- │ # Calculate the Catalan's constant with a specified number of significant figures using multiprecision arithmetic.
370
- ├── seqs
371
- │ └── FUNCTION
372
- │ ├── padovan(n: int, single: bool) -> typing.Union[int, list]
373
- │ │ # Generate the Padovan sequence up to the nth term.
374
- │ ├── pelllucas(n: int, single: bool) -> typing.Union[int, list]
375
- │ │ # Generate the Pell-Lucas sequence up to the nth term.
376
- │ ├── perrin(n: int, single: bool) -> typing.Union[int, list]
377
- │ │ # Generate the Perrin sequence up to the nth term.
378
- │ └── sylvester(n: int, single: bool) -> typing.Union[int, list]
379
- │ # Generate the Sylvester sequence up to the nth term.
380
- ├── tools
381
- │ └── FUNCTION
382
- │ ├── lcsubseq(x: typing.Union[list, tuple, str], y: typing.Union[list, tuple, str]) -> list
383
- │ │ # Find the longest common subsequence between two sequences x and y.
384
- │ └── lcsubstr(x: typing.Union[list, tuple, str], y: typing.Union[list, tuple, str]) -> list
385
- │ # Find the longest common substring between two sequences x and y.
386
- ├── matrices
387
- │ ├── CLASS
388
- │ │ └── Matrix(pypynum.arrays.Array)/__init__(self: Any, data: Any, check: Any) -> Any
389
- │ │ # Initialize a Matrix object from a given data array.
390
- │ └── FUNCTION
391
- │ ├── perm_mat(num_rows: int, num_cols: int, row_swaps: typing.Union[list, tuple], col_swaps: typing.Union[list, tuple], rtype: typing.Callable) -> typing.Any
392
- │ │ # Create a permutation matrix based on specified row and column swaps.
393
- │ └── perm_mat_indices(num_rows: int, num_cols: int, row_swaps: typing.Union[list, tuple], col_swaps: typing.Union[list, tuple]) -> tuple
394
- │ # Compute the indices for a permutation matrix based on specified row and column swaps.
395
355
 
356
+ cos_sim(seq1: Union[list, tuple, str], seq2: Union[list, tuple, str], is_vector: bool = False) -> float
357
+ Introduction
358
+ ==========
359
+ Calculate the cosine similarity between two sequences.
360
+
361
+ The cosine similarity is a measure of similarity between two non-zero vectors. It is defined as the cosine of the
362
+ angle between them, which is computed as the dot product of the vectors divided by the product of their magnitudes.
363
+ This function supports both numerical vectors and frequency distributions of sequences.
364
+
365
+ Example
366
+ ==========
367
+ >>> cos_sim("hello world", "world hello")
368
+ 0.9999999999999998
369
+ >>>
370
+ :param seq1: First sequence to compare.
371
+ :param seq2: Second sequence to compare.
372
+ :param is_vector: A boolean indicating whether the input sequences are numerical vectors. Default is False.
373
+ :return: The cosine similarity between the two sequences, ranging from -1 to 1.
374
+
375
+
376
+ replace(seq: Union[list, tuple], old: Union[list, tuple], new: Union[list, tuple], count: int = -1) -> Union[list, tuple]
377
+ Introduction
378
+ ==========
379
+ Replace occurrences of the subsequence 'old' in 'seq' with 'new'.
380
+
381
+ This function is designed to handle sequences such as lists or tuples and replace specified subsequences
382
+ with new ones. It also allows limiting the number of replacements.
383
+
384
+ Example
385
+ ==========
386
+ >>> replace([1, 2, 3, 4, 2, 3], [2, 3], [5, 6])
387
+ [1, 5, 6, 4, 5, 6]
388
+ >>>
389
+ :param seq: The sequence in which to replace the subsequence.
390
+ :param old: The subsequence to be replaced.
391
+ :param new: The subsequence to replace with.
392
+ :param count: The maximum number of replacements to perform. Default is -1 (unlimited).
393
+ :return: The modified sequence with replacements.
396
394
 
397
395
  !=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
398
396
 
@@ -439,15 +437,16 @@ PyPyNum
439
437
  │ ├── asarray(data: Any) -> Any
440
438
  │ ├── aslist(data: Any) -> Any
441
439
  │ ├── boolarray(data: Any) -> Any
442
- │ ├── fill(shape: Any, sequence: Any, repeat: Any, pad: Any, rtype: Any) -> Any
443
- │ ├── full(shape: Any, fill_value: Any, rtype: Any) -> Any
444
- │ ├── full_like(a: Any, fill_value: Any, rtype: Any) -> Any
440
+ │ ├── fill(shape: typing.Union[list, tuple], sequence: typing.Union[list, tuple], repeat: bool, pad: typing.Any, rtype: typing.Callable) -> typing.Any
441
+ │ ├── full(shape: typing.Union[list, tuple], fill_value: typing.Any, rtype: typing.Callable) -> typing.Any
442
+ │ ├── full_like(a: typing.Any, fill_value: typing.Any, rtype: typing.Callable) -> typing.Any
445
443
  │ ├── get_shape(data: Any) -> Any
446
444
  │ ├── is_valid_array(_array: Any, _shape: Any) -> Any
447
- │ ├── ones(shape: Any, rtype: Any) -> Any
448
- │ ├── ones_like(a: Any, rtype: Any) -> Any
449
- │ ├── zeros(shape: Any, rtype: Any) -> Any
450
- └── zeros_like(a: Any, rtype: Any) -> Any
445
+ │ ├── ones(shape: typing.Union[list, tuple], rtype: typing.Callable) -> typing.Any
446
+ │ ├── ones_like(a: typing.Any, rtype: typing.Callable) -> typing.Any
447
+ │ ├── tensorproduct(tensors: pypynum.arrays.Array) -> pypynum.arrays.Array
448
+ ├── zeros(shape: typing.Union[list, tuple], rtype: typing.Callable) -> typing.Any
449
+ │ └── zeros_like(a: typing.Any, rtype: typing.Callable) -> typing.Any
451
450
  ├── chars
452
451
  │ ├── CLASS
453
452
  │ └── FUNCTION
@@ -870,8 +869,7 @@ PyPyNum
870
869
  │ │ └── Tensor(pypynum.arrays.Array)/__init__(self: Any, data: Any, check: Any) -> Any
871
870
  │ └── FUNCTION
872
871
  │ ├── ten(data: list) -> pypynum.tensors.Tensor
873
- ├── tensor_and_number(tensor: Any, operator: Any, number: Any) -> Any
874
- │ └── tensorproduct(tensors: pypynum.tensors.Tensor) -> pypynum.tensors.Tensor
872
+ └── tensor_and_number(tensor: Any, operator: Any, number: Any) -> Any
875
873
  ├── test
876
874
  │ ├── CLASS
877
875
  │ └── FUNCTION
@@ -882,6 +880,7 @@ PyPyNum
882
880
  │ ├── CLASS
883
881
  │ └── FUNCTION
884
882
  │ ├── classify(array: typing.Union[list, tuple]) -> dict
883
+ │ ├── cos_sim(seq1: typing.Union[list, tuple, str], seq2: typing.Union[list, tuple, str], is_vector: bool) -> float
885
884
  │ ├── dedup(iterable: typing.Union[list, tuple, str]) -> typing.Union[list, tuple, str]
886
885
  │ ├── fast_pow(a: typing.Any, n: int, init: typing.Any, mul: typing.Callable) -> typing.Any
887
886
  │ ├── frange(start: typing.Union[int, float], stop: typing.Union[int, float], step: float) -> list
@@ -894,6 +893,7 @@ PyPyNum
894
893
  │ ├── primality(n: int, iter_num: int) -> bool
895
894
  │ ├── prime_factors(integer: int, dictionary: bool, pollard_rho: bool) -> typing.Union[list, dict]
896
895
  │ ├── primes(limit: int) -> list
896
+ │ ├── replace(seq: typing.Union[list, tuple], old: typing.Union[list, tuple], new: typing.Union[list, tuple], count: int) -> typing.Union[list, tuple]
897
897
  │ ├── semiprimes(limit: int) -> list
898
898
  │ ├── split(iterable: typing.Union[list, tuple, str], key: typing.Union[list, tuple], retain: bool) -> list
899
899
  │ └── twinprimes(limit: int) -> list
@@ -1,7 +1,7 @@
1
1
  pypynum/PyPyNum.png,sha256=t96tJPWfHxT8kcXm_qZI2z5W36TgOqjCU9qdgbmlFws,11623
2
- pypynum/README.md,sha256=1SOzsAn-Z-7WMCdc3TNB_SFHqhNscOpf7DCQ7mh6Cr4,84595
3
- pypynum/__init__.py,sha256=2Huv1gP1tUG1seEJmofWw_UMFlf3A_xIKT87hLfEMn8,2640
4
- pypynum/arrays.py,sha256=NiNs_wTeVgQpJuSe5OrIdFFG0Nln_ed4Im3hua0ZBnE,13293
2
+ pypynum/README.md,sha256=y4JBXggitGZ9Gy0b9fmCo4sZbLJ064DqYZ29J0lbVi8,83919
3
+ pypynum/__init__.py,sha256=3ozuifHA8CK2c6h9uFuZo3xkTsYgixL4VZesQMeObkw,2640
4
+ pypynum/arrays.py,sha256=GpU_smZ-9Bw897tWDGTTPMThQ_VfCvjfrIq6OGpuiDI,15492
5
5
  pypynum/chars.py,sha256=6XNmH0zYsv0pfadW3KoevrR8xQPIkles9oGikjS6R1I,2181
6
6
  pypynum/ciphers.py,sha256=kC7wZk3FF-MCCvn2-1YxiaRa4ImDKxyyihJYc6Dyf5E,10008
7
7
  pypynum/consts.py,sha256=enetPwJevWgYXuGEasAb-tXMHpvL2xWKUe-B1gTwInk,8416
@@ -20,7 +20,7 @@ pypynum/kernels.py,sha256=GMwWnjLWEprFXSEAIN8d6GZrC2KDx6qhJdbcLBoYOTg,15869
20
20
  pypynum/logics.py,sha256=EwvWFNND14__oWx7o-_oYIUubmVhp3DrvBcnRCWW8vc,10999
21
21
  pypynum/maths.py,sha256=McuOXRktbjcjZpTfWEoHnmFkeeQVacMoHyThqTIC27E,32808
22
22
  pypynum/matrices.py,sha256=useh4_Hlk3YBRTSTJK6SsErTRnDVblsqB0a7iw1mB_k,22439
23
- pypynum/multiprec.py,sha256=r8_OoWH56pRbBxCjd5-qkfxJMBU1r7LjV4Wvr7zR46Y,20111
23
+ pypynum/multiprec.py,sha256=LCaj0pkZIXmPKodm2Jt5RdyTg20Q6Js-n7PGBzqMXhk,20111
24
24
  pypynum/networks.py,sha256=iSOvC9JW1h4AFGokGGOTkKie5hAYN_YT9H4f3apI9b8,3275
25
25
  pypynum/numbers.py,sha256=EPzw8zq5U7GQj8URu2VxeVIXS-_XQm2ADmSAIHa816k,11133
26
26
  pypynum/plotting.py,sha256=mbIYK5TpY1qvuMJrqz4d8bxJEiZww3AI684vSKV-DgU,7781
@@ -33,17 +33,17 @@ pypynum/seqs.py,sha256=Hch8ebCrVFHUfKig54CVGzf3xXkVJlVbLsE0e7flOX4,11666
33
33
  pypynum/special.py,sha256=58pRacza__MwnovWFRemVglszF1wdUwgA4uyS25M47w,11643
34
34
  pypynum/stattest.py,sha256=nCAqFjaHVa9EOaWcmgWrhPuBoyLdoypkz6_YeM_AOd8,5511
35
35
  pypynum/symbols.py,sha256=u-Dig3OLs6qoLzxMpTAYJGq5uSWDMvgU13TAHKLyjMY,2768
36
- pypynum/tensors.py,sha256=gKpklk-7R9FHRD9iUOXOG6d-h-mL3I_E7TAL-xOWKu8,3685
36
+ pypynum/tensors.py,sha256=F87npY9VbaCAr0OvTwsW1GAhEQPQAQTVlJzeVuf4zSg,3418
37
37
  pypynum/test.py,sha256=HY6TiQr9-wIadRoXElu8TJkVWKMxcahisyWBtew8B9c,8730
38
38
  pypynum/this.py,sha256=wT7DwodxqOQ7LoDaUtvskMkAb8CODL_56mtXPy12P54,3411
39
- pypynum/tools.py,sha256=QOuftgsu9603odrzMUXG9HQIJumFtGhXq0x9PFlUIS4,18850
39
+ pypynum/tools.py,sha256=PWE4eHVHcFrbKTz-ohiRPc1xo2_FvQj3LpfDvWe8mh0,23035
40
40
  pypynum/trees.py,sha256=b02t69vBjc3ibKaUAkWfBvMDdsugF4DpGC2-q4RsgEU,39779
41
41
  pypynum/types.py,sha256=v1lGIL_p0xgxL6mGX7uBQBHBa7UScKCsgPkW8Q6nzlk,3348
42
42
  pypynum/ufuncs.py,sha256=Lmr_ZVsswQqbGo2MB8gjd_lijRBOZIy2q2wQBOHvYxM,3549
43
43
  pypynum/utils.py,sha256=BhH_iSU44bS6tC3MMrDfIfGhIsQg9nMVlp6fl0-KcRA,21001
44
44
  pypynum/vectors.py,sha256=GGVk0YSLVm-hzJjm068W7tNRYu8NqPgOKtWHIOTn9yY,3212
45
45
  pypynum/zh_cn.py,sha256=YBmTCO0h-xMDEo9pfpaR1qvh0qaL811psoZDdBniuzE,13818
46
- PyPyNum-1.16.0.dist-info/METADATA,sha256=insI60KoVZ3gxJwZN7pb4WQC3iQ9Kgia_VYIItcyUxQ,98974
47
- PyPyNum-1.16.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
48
- PyPyNum-1.16.0.dist-info/top_level.txt,sha256=4wW_Xb4bRglmiMsdPAe9f75MkXhNpuN88H17g_Cr5u8,8
49
- PyPyNum-1.16.0.dist-info/RECORD,,
46
+ PyPyNum-1.16.1.dist-info/METADATA,sha256=CjPWR4mVYBqmVNqYNTXXnA0dhosQvbClUg614eNIzZM,98298
47
+ PyPyNum-1.16.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
48
+ PyPyNum-1.16.1.dist-info/top_level.txt,sha256=4wW_Xb4bRglmiMsdPAe9f75MkXhNpuN88H17g_Cr5u8,8
49
+ PyPyNum-1.16.1.dist-info/RECORD,,
pypynum/README.md CHANGED
@@ -20,7 +20,7 @@ processing.</font><font color = red>[Python>=3.4]</font>
20
20
  [![Downloads](https://static.pepy.tech/badge/pypynum/month)](https://pepy.tech/project/pypynum)
21
21
  [![Downloads](https://static.pepy.tech/badge/pypynum/week)](https://pepy.tech/project/pypynum)
22
22
 
23
- ## Version -> 1.16.0 | PyPI -> https://pypi.org/project/PyPyNum/ | Gitee -> https://www.gitee.com/PythonSJL/PyPyNum | GitHub -> https://github.com/PythonSJL/PyPyNum
23
+ ## PyPyNum | Version -> 1.16.1 | PyPI -> https://pypi.org/project/PyPyNum/ | Gitee -> https://www.gitee.com/PythonSJL/PyPyNum | GitHub -> https://github.com/PythonSJL/PyPyNum
24
24
 
25
25
  ![LOGO](PyPyNum.png)
26
26
 
@@ -113,72 +113,70 @@ Python interpreter and run it!
113
113
  ```
114
114
  !=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
115
115
 
116
- The submodule 'consts' has added
117
- a large number of mathematical
118
- and scientific constants,
119
- currently totaling 128.
116
+ Fixed and improved the basic
117
+ operation function of 'Array'.
120
118
 
121
- This module defines a collection
122
- of constants representing
123
- various physical, mathematical,
124
- and unit conversion factors.
125
-
126
- These constants are commonly
127
- used in scientific and
128
- engineering calculations.
119
+ !=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
129
120
 
130
- If you want to know information
131
- about each constant, you can
132
- execute 'help(consts)' to
133
- obtain it.
121
+ We will remove 'Tensor' in
122
+ future versions. Because its
123
+ computational functions have
124
+ already been implemented in
125
+ 'Array'. The current version
126
+ will throw 'FutureWarning' as a
127
+ warning.
134
128
 
135
129
  !=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
136
130
 
131
+ Fixed the calculation error of
132
+ 'mp_euler_gamma', which was
133
+ caused when modifying the
134
+ iteration stop condition
135
+ previously.
137
136
 
138
- <<< Here are the newly added functions >>>
137
+ !=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
139
138
 
139
+ <<< Here are the newly added functions >>>
140
140
 
141
- PyPyNum
142
- ├── special
143
- │ └── FUNCTION
144
- │ ├── qbinomial(n: typing.Union[int, float, complex], m: typing.Union[int, float, complex], q: typing.Union[int, float, complex]) -> typing.Union[int, float, complex]
145
- │ │ # Calculate the q-binomial coefficient of n and m with parameter q.
146
- │ ├── qfactorial(n: typing.Union[int, float, complex], q: typing.Union[int, float, complex]) -> typing.Union[int, float, complex]
147
- │ │ # Compute the q-factorial of n with parameter q.
148
- │ ├── qgamma(n: typing.Union[int, float, complex], q: typing.Union[int, float, complex]) -> typing.Union[int, float, complex]
149
- │ │ # Calculate the q-gamma function of n with parameter q.
150
- │ └── qpochhammer(a: typing.Union[int, float, complex], q: typing.Union[int, float, complex], n: typing.Union[int, float, complex]) -> typing.Union[int, float, complex]
151
- │ # Compute the q-Pochhammer symbol for given a, q, and n.
152
- ├── multiprec
153
- │ └── FUNCTION
154
- │ ├── mp_catalan(sigfigs: int) -> decimal.Decimal
155
- │ # Calculate the Catalan's constant with a specified number of significant figures using multiprecision arithmetic.
156
- ├── seqs
157
- │ └── FUNCTION
158
- │ ├── padovan(n: int, single: bool) -> typing.Union[int, list]
159
- │ │ # Generate the Padovan sequence up to the nth term.
160
- │ ├── pelllucas(n: int, single: bool) -> typing.Union[int, list]
161
- │ │ # Generate the Pell-Lucas sequence up to the nth term.
162
- │ ├── perrin(n: int, single: bool) -> typing.Union[int, list]
163
- │ │ # Generate the Perrin sequence up to the nth term.
164
- │ └── sylvester(n: int, single: bool) -> typing.Union[int, list]
165
- │ # Generate the Sylvester sequence up to the nth term.
166
- ├── tools
167
- │ └── FUNCTION
168
- │ ├── lcsubseq(x: typing.Union[list, tuple, str], y: typing.Union[list, tuple, str]) -> list
169
- │ │ # Find the longest common subsequence between two sequences x and y.
170
- │ └── lcsubstr(x: typing.Union[list, tuple, str], y: typing.Union[list, tuple, str]) -> list
171
- │ # Find the longest common substring between two sequences x and y.
172
- ├── matrices
173
- │ ├── CLASS
174
- │ │ └── Matrix(pypynum.arrays.Array)/__init__(self: Any, data: Any, check: Any) -> Any
175
- │ │ # Initialize a Matrix object from a given data array.
176
- │ └── FUNCTION
177
- │ ├── perm_mat(num_rows: int, num_cols: int, row_swaps: typing.Union[list, tuple], col_swaps: typing.Union[list, tuple], rtype: typing.Callable) -> typing.Any
178
- │ │ # Create a permutation matrix based on specified row and column swaps.
179
- │ └── perm_mat_indices(num_rows: int, num_cols: int, row_swaps: typing.Union[list, tuple], col_swaps: typing.Union[list, tuple]) -> tuple
180
- │ # Compute the indices for a permutation matrix based on specified row and column swaps.
181
141
 
142
+ cos_sim(seq1: Union[list, tuple, str], seq2: Union[list, tuple, str], is_vector: bool = False) -> float
143
+ Introduction
144
+ ==========
145
+ Calculate the cosine similarity between two sequences.
146
+
147
+ The cosine similarity is a measure of similarity between two non-zero vectors. It is defined as the cosine of the
148
+ angle between them, which is computed as the dot product of the vectors divided by the product of their magnitudes.
149
+ This function supports both numerical vectors and frequency distributions of sequences.
150
+
151
+ Example
152
+ ==========
153
+ >>> cos_sim("hello world", "world hello")
154
+ 0.9999999999999998
155
+ >>>
156
+ :param seq1: First sequence to compare.
157
+ :param seq2: Second sequence to compare.
158
+ :param is_vector: A boolean indicating whether the input sequences are numerical vectors. Default is False.
159
+ :return: The cosine similarity between the two sequences, ranging from -1 to 1.
160
+
161
+
162
+ replace(seq: Union[list, tuple], old: Union[list, tuple], new: Union[list, tuple], count: int = -1) -> Union[list, tuple]
163
+ Introduction
164
+ ==========
165
+ Replace occurrences of the subsequence 'old' in 'seq' with 'new'.
166
+
167
+ This function is designed to handle sequences such as lists or tuples and replace specified subsequences
168
+ with new ones. It also allows limiting the number of replacements.
169
+
170
+ Example
171
+ ==========
172
+ >>> replace([1, 2, 3, 4, 2, 3], [2, 3], [5, 6])
173
+ [1, 5, 6, 4, 5, 6]
174
+ >>>
175
+ :param seq: The sequence in which to replace the subsequence.
176
+ :param old: The subsequence to be replaced.
177
+ :param new: The subsequence to replace with.
178
+ :param count: The maximum number of replacements to perform. Default is -1 (unlimited).
179
+ :return: The modified sequence with replacements.
182
180
 
183
181
  !=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
184
182
 
@@ -225,15 +223,16 @@ PyPyNum
225
223
  │ ├── asarray(data: Any) -> Any
226
224
  │ ├── aslist(data: Any) -> Any
227
225
  │ ├── boolarray(data: Any) -> Any
228
- │ ├── fill(shape: Any, sequence: Any, repeat: Any, pad: Any, rtype: Any) -> Any
229
- │ ├── full(shape: Any, fill_value: Any, rtype: Any) -> Any
230
- │ ├── full_like(a: Any, fill_value: Any, rtype: Any) -> Any
226
+ │ ├── fill(shape: typing.Union[list, tuple], sequence: typing.Union[list, tuple], repeat: bool, pad: typing.Any, rtype: typing.Callable) -> typing.Any
227
+ │ ├── full(shape: typing.Union[list, tuple], fill_value: typing.Any, rtype: typing.Callable) -> typing.Any
228
+ │ ├── full_like(a: typing.Any, fill_value: typing.Any, rtype: typing.Callable) -> typing.Any
231
229
  │ ├── get_shape(data: Any) -> Any
232
230
  │ ├── is_valid_array(_array: Any, _shape: Any) -> Any
233
- │ ├── ones(shape: Any, rtype: Any) -> Any
234
- │ ├── ones_like(a: Any, rtype: Any) -> Any
235
- │ ├── zeros(shape: Any, rtype: Any) -> Any
236
- └── zeros_like(a: Any, rtype: Any) -> Any
231
+ │ ├── ones(shape: typing.Union[list, tuple], rtype: typing.Callable) -> typing.Any
232
+ │ ├── ones_like(a: typing.Any, rtype: typing.Callable) -> typing.Any
233
+ │ ├── tensorproduct(tensors: pypynum.arrays.Array) -> pypynum.arrays.Array
234
+ ├── zeros(shape: typing.Union[list, tuple], rtype: typing.Callable) -> typing.Any
235
+ │ └── zeros_like(a: typing.Any, rtype: typing.Callable) -> typing.Any
237
236
  ├── chars
238
237
  │ ├── CLASS
239
238
  │ └── FUNCTION
@@ -656,8 +655,7 @@ PyPyNum
656
655
  │ │ └── Tensor(pypynum.arrays.Array)/__init__(self: Any, data: Any, check: Any) -> Any
657
656
  │ └── FUNCTION
658
657
  │ ├── ten(data: list) -> pypynum.tensors.Tensor
659
- ├── tensor_and_number(tensor: Any, operator: Any, number: Any) -> Any
660
- │ └── tensorproduct(tensors: pypynum.tensors.Tensor) -> pypynum.tensors.Tensor
658
+ └── tensor_and_number(tensor: Any, operator: Any, number: Any) -> Any
661
659
  ├── test
662
660
  │ ├── CLASS
663
661
  │ └── FUNCTION
@@ -668,6 +666,7 @@ PyPyNum
668
666
  │ ├── CLASS
669
667
  │ └── FUNCTION
670
668
  │ ├── classify(array: typing.Union[list, tuple]) -> dict
669
+ │ ├── cos_sim(seq1: typing.Union[list, tuple, str], seq2: typing.Union[list, tuple, str], is_vector: bool) -> float
671
670
  │ ├── dedup(iterable: typing.Union[list, tuple, str]) -> typing.Union[list, tuple, str]
672
671
  │ ├── fast_pow(a: typing.Any, n: int, init: typing.Any, mul: typing.Callable) -> typing.Any
673
672
  │ ├── frange(start: typing.Union[int, float], stop: typing.Union[int, float], step: float) -> list
@@ -680,6 +679,7 @@ PyPyNum
680
679
  │ ├── primality(n: int, iter_num: int) -> bool
681
680
  │ ├── prime_factors(integer: int, dictionary: bool, pollard_rho: bool) -> typing.Union[list, dict]
682
681
  │ ├── primes(limit: int) -> list
682
+ │ ├── replace(seq: typing.Union[list, tuple], old: typing.Union[list, tuple], new: typing.Union[list, tuple], count: int) -> typing.Union[list, tuple]
683
683
  │ ├── semiprimes(limit: int) -> list
684
684
  │ ├── split(iterable: typing.Union[list, tuple, str], key: typing.Union[list, tuple], retain: bool) -> list
685
685
  │ └── twinprimes(limit: int) -> list
pypynum/__init__.py CHANGED
@@ -68,7 +68,7 @@ from .ufuncs import *
68
68
  from .utils import *
69
69
  from .vectors import *
70
70
 
71
- __version__ = "1.16.0"
71
+ __version__ = "1.16.1"
72
72
  print("PyPyNum", "Version -> " + __version__, "PyPI -> https://pypi.org/project/PyPyNum/",
73
73
  "Gitee -> https://www.gitee.com/PythonSJL/PyPyNum", "GitHub -> https://github.com/PythonSJL/PyPyNum", sep=" | ")
74
74
  for _ in list(globals().keys()):
pypynum/arrays.py CHANGED
@@ -1,4 +1,4 @@
1
- from .types import ShapeError
1
+ from .types import Any, Callable, ShapeError, arr
2
2
 
3
3
  ArrayError = ShapeError("The shape of the array is invalid")
4
4
  MatchError = ShapeError("The shapes of the two arrays do not match")
@@ -6,7 +6,7 @@ MatchError = ShapeError("The shapes of the two arrays do not match")
6
6
 
7
7
  class Array:
8
8
  """
9
- It is the base class of vectors, matrices, and tensors, supporting operations and many statistical functions.
9
+ It is the base class of vectors and matrices, supporting operations and many statistical functions.
10
10
  :param data: An array in the form of a list
11
11
  :param check: Check the rationality of the input array
12
12
  """
@@ -41,12 +41,6 @@ class Array:
41
41
  _max = max([_.count("[") for _ in _then])
42
42
  return "\n".join([(_max - _.count("[")) * " " + _ + "\n" * (_.count("]") - 1) for _ in _then]).strip()
43
43
 
44
- def __add__(self, other):
45
- return Array(self.copy().data + other.copy().data)
46
-
47
- def __radd__(self, other):
48
- return self + other
49
-
50
44
  def __getitem__(self, item):
51
45
  def get_item_recursive(result, indices):
52
46
  if indices == ():
@@ -104,11 +98,44 @@ class Array:
104
98
  def __hash__(self):
105
99
  return hash(repr(self.data))
106
100
 
101
+ def __add__(self, other):
102
+ if isinstance(other, Array):
103
+ if self.shape != other.shape:
104
+ raise MatchError
105
+ return fill(self.shape, [t1 + t2 for t1, t2 in zip(self.flatten(), other.flatten())], rtype=type(self))
106
+ elif isinstance(other, (int, float, complex)):
107
+ from .ufuncs import add
108
+ return add(self, other)
109
+ else:
110
+ raise ValueError("Another must be an array or number")
111
+
112
+ def __sub__(self, other):
113
+ if isinstance(other, Array):
114
+ if self.shape != other.shape:
115
+ raise MatchError
116
+ return fill(self.shape, [t1 - t2 for t1, t2 in zip(self.flatten(), other.flatten())], rtype=type(self))
117
+ elif isinstance(other, (int, float, complex)):
118
+ from .ufuncs import subtract
119
+ return subtract(self, other)
120
+ else:
121
+ raise ValueError("Another must be an array or number")
122
+
123
+ def __mul__(self, other):
124
+ if isinstance(other, Array):
125
+ if self.shape != other.shape:
126
+ raise MatchError
127
+ return fill(self.shape, [t1 * t2 for t1, t2 in zip(self.flatten(), other.flatten())], rtype=type(self))
128
+ elif isinstance(other, (int, float, complex)):
129
+ from .ufuncs import multiply
130
+ return multiply(self, other)
131
+ else:
132
+ raise ValueError("Another must be an array or number")
133
+
107
134
  def __truediv__(self, other):
108
135
  if isinstance(other, Array):
109
136
  if self.shape != other.shape:
110
137
  raise MatchError
111
- return type(self)(fill(self.shape, [t1 / t2 for t1, t2 in zip(self.flatten(), other.flatten())]))
138
+ return fill(self.shape, [t1 / t2 for t1, t2 in zip(self.flatten(), other.flatten())], rtype=type(self))
112
139
  elif isinstance(other, (int, float, complex)):
113
140
  from .ufuncs import divide
114
141
  return divide(self, other)
@@ -119,7 +146,7 @@ class Array:
119
146
  if isinstance(other, Array):
120
147
  if self.shape != other.shape:
121
148
  raise MatchError
122
- return type(self)(fill(self.shape, [t1 // t2 for t1, t2 in zip(self.flatten(), other.flatten())]))
149
+ return fill(self.shape, [t1 // t2 for t1, t2 in zip(self.flatten(), other.flatten())], rtype=type(self))
123
150
  elif isinstance(other, (int, float, complex)):
124
151
  from .ufuncs import floor_divide
125
152
  return floor_divide(self, other)
@@ -130,7 +157,7 @@ class Array:
130
157
  if isinstance(other, Array):
131
158
  if self.shape != other.shape:
132
159
  raise MatchError
133
- return type(self)(fill(self.shape, [t1 % t2 for t1, t2 in zip(self.flatten(), other.flatten())]))
160
+ return fill(self.shape, [t1 % t2 for t1, t2 in zip(self.flatten(), other.flatten())], rtype=type(self))
134
161
  elif isinstance(other, (int, float, complex)):
135
162
  from .ufuncs import modulo
136
163
  return modulo(self, other)
@@ -145,6 +172,14 @@ class Array:
145
172
  else:
146
173
  raise ValueError("Exponential and modulus must both be arrays or numbers")
147
174
 
175
+ __radd__ = __add__
176
+ __rsub__ = __sub__
177
+ __rmul__ = __mul__
178
+ __rtruediv__ = __truediv__
179
+ __rfloordiv__ = __floordiv__
180
+ __rmod__ = __mod__
181
+ __rpow__ = __pow__
182
+
148
183
  def __gt__(self, other):
149
184
  return self.comparison(other, lambda x, y: x > y)
150
185
 
@@ -185,7 +220,7 @@ class Array:
185
220
  return data
186
221
 
187
222
  def reshape(self, shape, repeat=True, pad=0):
188
- return type(self)(fill(shape, self.flatten(), repeat, pad))
223
+ return fill(shape, self.flatten(), repeat, pad, type(self))
189
224
 
190
225
  def copy(self):
191
226
  from copy import deepcopy
@@ -291,7 +326,7 @@ def asarray(data):
291
326
  return Array(aslist(data))
292
327
 
293
328
 
294
- def full(shape, fill_value, rtype=Array):
329
+ def full(shape: arr, fill_value: Any, rtype: Callable = Array) -> Any:
295
330
  def inner(data):
296
331
  return fill_value if len(data) == 0 else [(inner(data[1:])) for _ in range(data[0])]
297
332
 
@@ -301,7 +336,7 @@ def full(shape, fill_value, rtype=Array):
301
336
  return result if rtype is list else rtype(result)
302
337
 
303
338
 
304
- def full_like(a, fill_value, rtype=Array):
339
+ def full_like(a: Any, fill_value: Any, rtype: Callable = Array) -> Any:
305
340
  def inner(data):
306
341
  return [inner(item) for item in data] if isinstance(data, list) else fill_value
307
342
 
@@ -313,23 +348,23 @@ def full_like(a, fill_value, rtype=Array):
313
348
  return result if rtype is list else rtype(result)
314
349
 
315
350
 
316
- def zeros(shape, rtype=Array):
351
+ def zeros(shape: arr, rtype: Callable = Array) -> Any:
317
352
  return full(shape, 0, rtype)
318
353
 
319
354
 
320
- def zeros_like(a, rtype=Array):
355
+ def zeros_like(a: Any, rtype: Callable = Array) -> Any:
321
356
  return full_like(a, 0, rtype)
322
357
 
323
358
 
324
- def ones(shape, rtype=Array):
359
+ def ones(shape: arr, rtype: Callable = Array) -> Any:
325
360
  return full(shape, 1, rtype)
326
361
 
327
362
 
328
- def ones_like(a, rtype=Array):
363
+ def ones_like(a: Any, rtype: Callable = Array) -> Any:
329
364
  return full_like(a, 1, rtype)
330
365
 
331
366
 
332
- def fill(shape, sequence=None, repeat=True, pad=0, rtype=Array):
367
+ def fill(shape: arr, sequence: arr = None, repeat: bool = True, pad: Any = 0, rtype: Callable = Array) -> Any:
333
368
  pointer = -1
334
369
  length = 1
335
370
  for item in shape:
@@ -353,6 +388,21 @@ def fill(shape, sequence=None, repeat=True, pad=0, rtype=Array):
353
388
  return result if rtype is list else rtype(result)
354
389
 
355
390
 
391
+ def tensorproduct(*tensors: Array) -> Array:
392
+ if not all([isinstance(tensor, Array) for tensor in tensors]):
393
+ raise TypeError("All inputs must be tensors")
394
+ if len(tensors) == 1:
395
+ return tensors[0].copy()
396
+
397
+ def mul(a, b):
398
+ return Array(fill(a.shape + b.shape, [i * j for i in a.flatten() for j in b.flatten()], rtype=list), False)
399
+
400
+ first = tensors[0]
401
+ for second in tensors[1:]:
402
+ first = mul(first, second)
403
+ return first
404
+
405
+
356
406
  class BoolArray(Array):
357
407
  def __init__(self, data=None, check=True):
358
408
  from .ufuncs import apply
pypynum/multiprec.py CHANGED
@@ -415,8 +415,8 @@ def mp_euler_gamma(sigfigs: int = 28) -> Decimal:
415
415
  fact_k = Decimal(1)
416
416
  harmonic_sum = Decimal(0)
417
417
  temp = None
418
- while i_n != temp:
419
- temp = i_n
418
+ while j_n != temp:
419
+ temp = j_n
420
420
  term = (n_power_k / fact_k) ** 2
421
421
  i_n += term * harmonic_sum
422
422
  j_n += term
pypynum/tensors.py CHANGED
@@ -12,6 +12,9 @@ class Tensor(Array):
12
12
  """
13
13
 
14
14
  def __init__(self, data, check=True):
15
+ from warnings import warn
16
+ warn("The 'Tensor' class is deprecated and will be removed in a future version. "
17
+ "Please use the 'Array' class instead for similar functionality.", FutureWarning)
15
18
  super().__init__(data, check)
16
19
 
17
20
  def __add__(self, other):
@@ -80,19 +83,4 @@ def ten(data: list) -> Tensor:
80
83
  return Tensor(data)
81
84
 
82
85
 
83
- def tensorproduct(*tensors: Tensor) -> Tensor:
84
- if not all([isinstance(tensor, Tensor) for tensor in tensors]):
85
- raise TypeError("All inputs must be tensors")
86
- if len(tensors) == 1:
87
- return tensors[0].copy()
88
-
89
- def mul(a, b):
90
- return Tensor(fill(a.shape + b.shape, [i * j for i in a.flatten() for j in b.flatten()], rtype=list), False)
91
-
92
- first = tensors[0]
93
- for second in tensors[1:]:
94
- first = mul(first, second)
95
- return first
96
-
97
-
98
86
  del Array
pypynum/tools.py CHANGED
@@ -545,6 +545,116 @@ def lcsubstr(x: ite, y: ite) -> list:
545
545
  return list(x[end_idx - max_len:end_idx])
546
546
 
547
547
 
548
+ def cos_sim(seq1: ite, seq2: ite, is_vector: bool = False) -> float:
549
+ """
550
+ Introduction
551
+ ==========
552
+ Calculate the cosine similarity between two sequences.
553
+
554
+ The cosine similarity is a measure of similarity between two non-zero vectors. It is defined as the cosine of the
555
+ angle between them, which is computed as the dot product of the vectors divided by the product of their magnitudes.
556
+ This function supports both numerical vectors and frequency distributions of sequences.
557
+
558
+ Example
559
+ ==========
560
+ >>> cos_sim("hello world", "world hello")
561
+ 0.9999999999999998
562
+ >>>
563
+ :param seq1: First sequence to compare.
564
+ :param seq2: Second sequence to compare.
565
+ :param is_vector: A boolean indicating whether the input sequences are numerical vectors. Default is False.
566
+ :return: The cosine similarity between the two sequences, ranging from -1 to 1.
567
+ """
568
+ from .maths import freq
569
+ if is_vector:
570
+ dot_product = sum([a * b for a, b in zip(seq1, seq2)])
571
+ magnitude_seq1 = sum([a ** 2 for a in seq1]) ** 0.5
572
+ magnitude_seq2 = sum([b ** 2 for b in seq2]) ** 0.5
573
+ else:
574
+ freq1 = freq(seq1)
575
+ freq2 = freq(seq2)
576
+ dot_product = sum([freq1.get(k, 0) * freq2.get(k, 0) for k in set(freq1) | set(freq2)])
577
+ magnitude_seq1 = sum([v ** 2 for v in freq1.values()]) ** 0.5
578
+ magnitude_seq2 = sum([v ** 2 for v in freq2.values()]) ** 0.5
579
+ if magnitude_seq1 * magnitude_seq2 == 0:
580
+ return 0.0
581
+ return dot_product / (magnitude_seq1 * magnitude_seq2)
582
+
583
+
584
+ def replace(seq: arr, old: arr, new: arr, count: int = -1) -> arr:
585
+ """
586
+ Introduction
587
+ ==========
588
+ Replace occurrences of the subsequence 'old' in 'seq' with 'new'.
589
+
590
+ This function is designed to handle sequences such as lists or tuples and replace specified subsequences
591
+ with new ones. It also allows limiting the number of replacements.
592
+
593
+ Example
594
+ ==========
595
+ >>> replace([1, 2, 3, 4, 2, 3], [2, 3], [5, 6])
596
+ [1, 5, 6, 4, 5, 6]
597
+ >>>
598
+ :param seq: The sequence in which to replace the subsequence.
599
+ :param old: The subsequence to be replaced.
600
+ :param new: The subsequence to replace with.
601
+ :param count: The maximum number of replacements to perform. Default is -1 (unlimited).
602
+ :return: The modified sequence with replacements.
603
+ """
604
+ if not isinstance(seq, (list, tuple)):
605
+ raise TypeError("Parameter 'seq' must be a list or a tuple, got {}".format(type(seq)))
606
+ if not isinstance(old, (list, tuple)):
607
+ raise TypeError("Parameter 'old' must be a list or a tuple, got {}".format(type(old)))
608
+ if not isinstance(new, (list, tuple)):
609
+ raise TypeError("Parameter 'new' must be a list or a tuple, got {}".format(type(new)))
610
+ if not old:
611
+ raise ValueError("Parameter 'old' must not be empty")
612
+ if not isinstance(count, int) or count < 0 and count != -1:
613
+ raise ValueError("Parameter 'count' must be a non-negative integer or -1, got {}".format(count))
614
+ if count == 0:
615
+ return seq[:]
616
+ old_len = len(old)
617
+ table = [0] * old_len
618
+ pos, cnd = 1, 0
619
+ while pos < old_len:
620
+ if old[pos] == old[cnd]:
621
+ cnd += 1
622
+ table[pos] = cnd
623
+ pos += 1
624
+ elif cnd > 0:
625
+ cnd = table[cnd - 1]
626
+ else:
627
+ table[pos] = 0
628
+ pos += 1
629
+ result = []
630
+ i, j = 0, 0
631
+ replaced = 0
632
+ seq_len = len(seq)
633
+ while i < seq_len:
634
+ if j == old_len:
635
+ result.extend(new)
636
+ replaced += 1
637
+ j = 0
638
+ if count != -1 and replaced == count:
639
+ result.extend(seq[i:])
640
+ break
641
+ elif seq[i] == old[j]:
642
+ i += 1
643
+ j += 1
644
+ else:
645
+ if j != 0:
646
+ result.extend(old[:j])
647
+ j = table[j - 1]
648
+ else:
649
+ result.append(seq[i])
650
+ i += 1
651
+ if j == old_len:
652
+ result.extend(new)
653
+ elif j > 0:
654
+ result.extend(old[:j])
655
+ return tuple(result) if isinstance(seq, tuple) else result
656
+
657
+
548
658
  def fast_pow(a: Any, n: int, init: Any = 1, mul: Callable = None) -> Any:
549
659
  """
550
660
  Introduction
@@ -553,7 +663,6 @@ def fast_pow(a: Any, n: int, init: Any = 1, mul: Callable = None) -> Any:
553
663
 
554
664
  It is a versatile tool that can be used with any data type supporting multiplication, including the ability to
555
665
  perform matrix exponentiation by setting an initial matrix and a matrix multiplication function.
556
-
557
666
  For instance, to compute the matrix power of a 2x2 matrix, you can define the matrix as the base 'a',
558
667
  set an identity matrix as the 'init', and provide a function for matrix multiplication as 'mul'.
559
668