PyPyNum 1.11.1__py3-none-any.whl → 1.11.2__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.
- {PyPyNum-1.11.1.dist-info → PyPyNum-1.11.2.dist-info}/METADATA +114 -87
- {PyPyNum-1.11.1.dist-info → PyPyNum-1.11.2.dist-info}/RECORD +12 -11
- pypynum/Matrix.py +22 -0
- pypynum/README.md +113 -86
- pypynum/__init__.py +4 -3
- pypynum/chars.py +24 -1
- pypynum/confs.py +81 -0
- pypynum/polynomial.py +14 -5
- pypynum/random.py +30 -103
- pypynum/utils.py +176 -2
- {PyPyNum-1.11.1.dist-info → PyPyNum-1.11.2.dist-info}/WHEEL +0 -0
- {PyPyNum-1.11.1.dist-info → PyPyNum-1.11.2.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyPyNum
|
|
3
|
-
Version: 1.11.
|
|
3
|
+
Version: 1.11.2
|
|
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
|
[](https://pepy.tech/project/pypynum)
|
|
235
235
|
[](https://pepy.tech/project/pypynum)
|
|
236
236
|
|
|
237
|
-
## Version -> 1.11.
|
|
237
|
+
## Version -> 1.11.2 | PyPI -> https://pypi.org/project/PyPyNum/ | Gitee -> https://www.gitee.com/PythonSJL/PyPyNum | GitHub -> https://github.com/PythonSJL/PyPyNum
|
|
238
238
|
|
|
239
239
|

|
|
240
240
|
|
|
@@ -263,6 +263,7 @@ The logo cannot be displayed on PyPI, it can be viewed in Gitee or GitHub.
|
|
|
263
263
|
| `pypynum.Array` | 多维数组 Multidimensional array |
|
|
264
264
|
| `pypynum.chars` | 特殊数学符号 Special mathematical symbols |
|
|
265
265
|
| `pypynum.cipher` | 加密解密算法 Encryption and decryption algorithm |
|
|
266
|
+
| `pypynum.confs` | 通用配置 Universal configuration |
|
|
266
267
|
| `pypynum.constants` | 数学常数集合 Set of mathematical constants |
|
|
267
268
|
| `pypynum.dists` | 概率分布 Probability distribution |
|
|
268
269
|
| `pypynum.equations` | 方程求解 Solving equations |
|
|
@@ -336,93 +337,110 @@ Python interpreter and run it!
|
|
|
336
337
|
```
|
|
337
338
|
!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
|
|
338
339
|
|
|
339
|
-
|
|
340
|
+
新增了Config类
|
|
340
341
|
|
|
341
|
-
|
|
342
|
+
Added Config class
|
|
342
343
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
344
|
+
Introduction
|
|
345
|
+
The Config class is designed to manage and configure application settings. It provides a mechanism to ensure consistency in configurations and prevents accidental changes by limiting attribute modification.
|
|
346
|
+
Roadmap
|
|
347
|
+
The Config class is currently stable. Future updates may include new configuration options to support additional features.
|
|
348
|
+
Usage
|
|
349
|
+
Modifying Configuration:
|
|
350
|
+
You can modify the configuration by setting attributes directly, but only with predefined boolean values.
|
|
351
|
+
config. use_latex = True # Enable LaTeX formatting
|
|
352
|
+
Reading Configuration:
|
|
353
|
+
You can read the current configuration by accessing the attributes.
|
|
354
|
+
print(config. use_unicode) # Output: False
|
|
355
|
+
Ensuring Exclusive Configuration:
|
|
356
|
+
The Config class is designed to be mutually exclusive, meaning only one configuration item can be True at a time.
|
|
357
|
+
config. use_std = True # This will automatically set other configuration items to False
|
|
358
|
+
Getting Configuration Information:
|
|
359
|
+
Use the __repr__ method to get a string representation of the current configuration.
|
|
360
|
+
print(config) # Output: Config(use_latex=True, use_std=False, use_unicode=False)
|
|
361
|
+
|
|
362
|
+
修改配置时,您可以像这样导入“from pypynum import config”
|
|
363
|
+
|
|
364
|
+
When modifying the configuration, you can import 'from pypynum import config' like this
|
|
365
|
+
|
|
366
|
+
!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
|
|
367
|
+
|
|
368
|
+
一些类现在支持以Unicode或LaTeX显示数据
|
|
369
|
+
|
|
370
|
+
Some classes now support displaying data in Unicode or LaTeX
|
|
351
371
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
8 | 96 19 96 -94 -95 75 40 -74
|
|
425
|
-
=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
|
|
372
|
+
|
|
373
|
+
Polynomial :
|
|
374
|
+
Standard 27x - 85x^4 + 25x^12 + 54x^42 + x^47 - 29x^61 - 73x^66 - 53x^72 - 90x^94 - 99x^97
|
|
375
|
+
Unicode 27x - 85x⁴ + 25x¹² + 54x⁴² + x⁴⁷ - 29x⁶¹ - 73x⁶⁶ - 53x⁷² - 90x⁹⁴ - 99x⁹⁷
|
|
376
|
+
LaTeX 27x - 85x^{4} + 25x^{12} + 54x^{42} + x^{47} - 29x^{61} - 73x^{66} - 53x^{72} - 90x^{94} - 99x^{97}
|
|
377
|
+
|
|
378
|
+
IntervalSet :
|
|
379
|
+
Standard [-94, -61) U [-41, -20] U (-1, 76] U (78, 85)
|
|
380
|
+
Unicode [-94, -61) ∪ [-41, -20] ∪ (-1, 76] ∪ (78, 85)
|
|
381
|
+
LaTeX \left[-94, -61\right) \cup \left[-41, -20\right] \cup \left(-1, 76\right] \cup \left(78, 85\right)
|
|
382
|
+
|
|
383
|
+
Matrix :
|
|
384
|
+
Standard
|
|
385
|
+
[[-65 26 81 -47]
|
|
386
|
+
[ 60 85 4 -23]
|
|
387
|
+
[ 27 56 86 -7]
|
|
388
|
+
[ 38 79 47 76]]
|
|
389
|
+
LaTeX
|
|
390
|
+
\begin{bmatrix}-65 & 26 & 81 & -47\\60 & 85 & 4 & -23\\27 & 56 & 86 & -7\\38 & 79 & 47 & 76\end{bmatrix}
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
Matrix自带的latex()方法可以设置LaTeX矩阵类型与元素间距
|
|
394
|
+
The LaTeX() method that comes with Matrix allows you to set the LaTeX matrix type and element spacing
|
|
395
|
+
|
|
396
|
+
EXAMPLE :
|
|
397
|
+
>>> print(A.latex(matrix_type="vmatrix", row_spacing=5, col_spacing=5, spacing_unit="mm"))
|
|
398
|
+
\begin{vmatrix}-65 & \hspace{5mm} & 26 & \hspace{5mm} & 81 & \hspace{5mm} & -47\\[5mm]60 & \hspace{5mm} & 85 & \hspace{5mm} & 4 & \hspace{5mm} & -23\\[5mm]27 & \hspace{5mm} & 56 & \hspace{5mm} & 86 & \hspace{5mm} & -7\\[5mm]38 & \hspace{5mm} & 79 & \hspace{5mm} & 47 & \hspace{5mm} & 76\end{vmatrix}
|
|
399
|
+
|
|
400
|
+
!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
|
|
401
|
+
|
|
402
|
+
新增了IntervalSet类
|
|
403
|
+
|
|
404
|
+
Added IntervalSet class
|
|
405
|
+
|
|
406
|
+
支持区间的各种集合运算
|
|
407
|
+
|
|
408
|
+
Support various set operations for intervals
|
|
409
|
+
|
|
410
|
+
class IntervalSet(builtins.object)
|
|
411
|
+
| __and__ = intersection(self, other)
|
|
412
|
+
| __eq__ = is_equal(self, other)
|
|
413
|
+
| __ge__ = is_superset(self, other)
|
|
414
|
+
| __gt__ = is_proper_superset(self, other)
|
|
415
|
+
| __init__(self, intervals=None)
|
|
416
|
+
| It is a set of intervals and supports multiple operations.
|
|
417
|
+
| :param intervals: A sequence containing multiple intervals
|
|
418
|
+
| __le__ = is_subset(self, other)
|
|
419
|
+
| __lt__ = is_proper_subset(self, other)
|
|
420
|
+
| __matmul__ = complement(self, other)
|
|
421
|
+
| __ne__ = is_not_equal(self, other)
|
|
422
|
+
| __or__ = union(self, other)
|
|
423
|
+
| __repr__(self, use_latex=False)
|
|
424
|
+
| Return repr(self).
|
|
425
|
+
| __sub__ = difference(self, other)
|
|
426
|
+
| __xor__ = symmetric_difference(self, other)
|
|
427
|
+
| add_interval(self, start, end, start_open=False, end_open=False)
|
|
428
|
+
| add_intervals(self, intervals)
|
|
429
|
+
| complement(self, other)
|
|
430
|
+
| difference(self, other)
|
|
431
|
+
| intersection(self, other)
|
|
432
|
+
| is_equal(self, other)
|
|
433
|
+
| is_not_equal(self, other)
|
|
434
|
+
| is_proper_subset(self, other)
|
|
435
|
+
| is_proper_superset(self, other)
|
|
436
|
+
| is_subset(self, other)
|
|
437
|
+
| is_superset(self, other)
|
|
438
|
+
| latex(self)
|
|
439
|
+
| remove_interval(self, start, end, start_open=False, end_open=False)
|
|
440
|
+
| symmetric_difference(self, other)
|
|
441
|
+
| union(self, other)
|
|
442
|
+
|
|
443
|
+
!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
|
|
426
444
|
```
|
|
427
445
|
|
|
428
446
|
### 运行用时测试
|
|
@@ -579,6 +597,10 @@ PyPyNum
|
|
|
579
597
|
├── chars
|
|
580
598
|
│ ├── CLASS
|
|
581
599
|
│ └── FUNCTION
|
|
600
|
+
│ ├── int2subscript(standard_str: str) -> str
|
|
601
|
+
│ ├── int2superscript(standard_str: str) -> str
|
|
602
|
+
│ ├── subscript2int(subscript_str: str) -> str
|
|
603
|
+
│ └── superscript2int(superscript_str: str) -> str
|
|
582
604
|
├── cipher
|
|
583
605
|
│ ├── CLASS
|
|
584
606
|
│ └── FUNCTION
|
|
@@ -594,6 +616,9 @@ PyPyNum
|
|
|
594
616
|
│ ├── rot13(text: str) -> str
|
|
595
617
|
│ ├── substitution(text: str, sub_map: dict, decrypt: bool) -> str
|
|
596
618
|
│ └── vigenere(text: str, key: str, decrypt: bool) -> str
|
|
619
|
+
├── confs
|
|
620
|
+
│ ├── CLASS
|
|
621
|
+
│ └── FUNCTION
|
|
597
622
|
├── constants
|
|
598
623
|
│ ├── CLASS
|
|
599
624
|
│ └── FUNCTION
|
|
@@ -779,9 +804,10 @@ PyPyNum
|
|
|
779
804
|
├── random
|
|
780
805
|
│ ├── CLASS
|
|
781
806
|
│ └── FUNCTION
|
|
807
|
+
│ ├── __create_nested_list(dimensions: Any, func: Any) -> Any
|
|
808
|
+
│ ├── __validate_shape(shape: Any) -> Any
|
|
782
809
|
│ ├── choice(seq: typing.Union[list, tuple, str], shape: typing.Union[list, tuple]) -> Any
|
|
783
810
|
│ ├── gauss(mu: typing.Union[int, float], sigma: typing.Union[int, float], shape: typing.Union[list, tuple]) -> typing.Union[float, list]
|
|
784
|
-
│ ├── gauss_error(original: typing.Union[list, tuple], mu: typing.Union[int, float], sigma: typing.Union[int, float]) -> list
|
|
785
811
|
│ ├── rand(shape: typing.Union[list, tuple]) -> typing.Union[float, list]
|
|
786
812
|
│ ├── randint(a: int, b: int, shape: typing.Union[list, tuple]) -> typing.Union[int, list]
|
|
787
813
|
│ └── uniform(a: typing.Union[int, float], b: typing.Union[int, float], shape: typing.Union[list, tuple]) -> typing.Union[float, list]
|
|
@@ -849,6 +875,7 @@ PyPyNum
|
|
|
849
875
|
└── utils
|
|
850
876
|
├── CLASS
|
|
851
877
|
│ ├── InfIterator(object)/__init__(self: Any, start: typing.Union[int, float, complex], mode: str, common: typing.Union[int, float, complex]) -> Any
|
|
878
|
+
│ ├── IntervalSet(object)/__init__(self: Any, intervals: Any) -> Any
|
|
852
879
|
│ ├── LinkedList(object)/__init__(self: Any) -> Any
|
|
853
880
|
│ ├── LinkedListNode(object)/__init__(self: Any, value: Any, next_node: Any) -> Any
|
|
854
881
|
│ └── OrderedSet(object)/__init__(self: Any, sequence: Any) -> Any
|
|
@@ -4,18 +4,19 @@ pypynum/Geometry.py,sha256=bJCuif-wHO-t7oHFEE7ntzIdQwzUEbT3mcKgmBV6Wps,13982
|
|
|
4
4
|
pypynum/Graph.py,sha256=m9iTCNYRCZmAexDzwJ8Y6J7v1aweT-6TZkqh4fOtZDE,10131
|
|
5
5
|
pypynum/Group.py,sha256=QZdUUxa8zD9jxn69cJsbQlWZNvnSlw-31LZsmzXUxU0,2810
|
|
6
6
|
pypynum/Logic.py,sha256=IJAv59ECHU0HmG9lYCAQ_puqeL6Zor3-IDIVH48KBWE,11000
|
|
7
|
-
pypynum/Matrix.py,sha256=
|
|
7
|
+
pypynum/Matrix.py,sha256=AeA8I8uQ-Q2b63qDW4aasI6h6Vt3at-CK2IQ9WXfexQ,20436
|
|
8
8
|
pypynum/NeuralN.py,sha256=iSOvC9JW1h4AFGokGGOTkKie5hAYN_YT9H4f3apI9b8,3275
|
|
9
9
|
pypynum/PyPyNum.png,sha256=t96tJPWfHxT8kcXm_qZI2z5W36TgOqjCU9qdgbmlFws,11623
|
|
10
10
|
pypynum/Quaternion.py,sha256=-BW_crP_i-veHN0_pD3Z1dipFNUX198oZDrUYTsoZw0,8017
|
|
11
|
-
pypynum/README.md,sha256
|
|
11
|
+
pypynum/README.md,sha256=LOUbJ3bpdTzH1Rk1Pq4eOwBJGirI59rFgS9F5XdN-i0,63014
|
|
12
12
|
pypynum/Symbolics.py,sha256=u-Dig3OLs6qoLzxMpTAYJGq5uSWDMvgU13TAHKLyjMY,2768
|
|
13
13
|
pypynum/Tensor.py,sha256=gi7OjrGgP5BSJS9Oma1B2EdX9qSpMNIP2BnKLojdT78,3930
|
|
14
14
|
pypynum/Tree.py,sha256=BYnlb2kKNJ8kkuq8BAHIcLvPZw5KHxbvM7YuVGhQVMk,4330
|
|
15
15
|
pypynum/Vector.py,sha256=ee-gkBtyG0l5dLFwAKRTTlnDG05pWpM19RGN7VoPvqE,3212
|
|
16
|
-
pypynum/__init__.py,sha256=
|
|
17
|
-
pypynum/chars.py,sha256=
|
|
16
|
+
pypynum/__init__.py,sha256=QpdHhzjxjtfIhfRJOvaqim00BVq-IAOwKfsckEGOMe4,2845
|
|
17
|
+
pypynum/chars.py,sha256=ZOXZn2VzxmpHuvZ87ojhEib3CfTNgysRsFMFITHOA2E,2179
|
|
18
18
|
pypynum/cipher.py,sha256=DaitY3DCoTuzyrXtD8Ap3IYDLhlMc7-o4AJfLlicvB4,10011
|
|
19
|
+
pypynum/confs.py,sha256=nnHV-5_1u7hsbzjkOuFxz9p3nhVYqwrfXek5kXoJkrM,2853
|
|
19
20
|
pypynum/constants.py,sha256=xELv4DIKEqBdwF9tUqCmTQVbgVrlrj385ht5eawvshU,1406
|
|
20
21
|
pypynum/dists.py,sha256=WHDeM0oC4Do77p9TVVMu3pgWzI04gYdK_s1TNGhets0,29697
|
|
21
22
|
pypynum/equations.py,sha256=pwbSLpmFl9eChyxkTeRrs3KC3gy19kpAcpxNvWAKQVA,749
|
|
@@ -26,9 +27,9 @@ pypynum/image.py,sha256=nhTZmaBVIKhuar-CcwZWb-hRYmkj4b_g7vIlYvEJEEE,12155
|
|
|
26
27
|
pypynum/maths.py,sha256=kwOUVEdaL8A0kYRnllg-7ytIYbnT4YUGcA41kokHda8,30672
|
|
27
28
|
pypynum/numbers.py,sha256=PqQ07TWfcNlfjCjUg1UJda-BI1uOffmQVK1qIGbll_s,8619
|
|
28
29
|
pypynum/plotting.py,sha256=mbIYK5TpY1qvuMJrqz4d8bxJEiZww3AI684vSKV-DgU,7781
|
|
29
|
-
pypynum/polynomial.py,sha256=
|
|
30
|
+
pypynum/polynomial.py,sha256=gF2KRLqBHItJ8tdTjFT4FOJqVkWiHTBdGREp3roppB0,9778
|
|
30
31
|
pypynum/pprinters.py,sha256=Qt9-V5SUyoOqC3lsUU5D5zSSM-MmcnFCUyUtLxhS4pE,2514
|
|
31
|
-
pypynum/random.py,sha256=
|
|
32
|
+
pypynum/random.py,sha256=PkpZp-XRbhdsSLtTiQkK83WcOWYLbLGXROu3fsOKDcU,2272
|
|
32
33
|
pypynum/regression.py,sha256=PfTM8glJSi3Jgvc_C_3hQBeVjkbrzSuDqRbEf3s403w,2040
|
|
33
34
|
pypynum/sequence.py,sha256=7NSZm_p_B00KFj5XZrtSm2FXhsowxs0qg_Q_P4pAA8o,7194
|
|
34
35
|
pypynum/stattest.py,sha256=W1041KeVsvdcLKFJOK4hQm_DjO5ZjUE8WEmGUe-4_Zk,5507
|
|
@@ -37,8 +38,8 @@ pypynum/this.py,sha256=oRX1OpMa4NJmQSdEjJxfszEo5FRYlxRiF8OTDRIcdMA,2154
|
|
|
37
38
|
pypynum/tools.py,sha256=xN2hYpEnPGmn1CsdQ60OUv5HIwJRbQAWTI8NclwwHno,12609
|
|
38
39
|
pypynum/types.py,sha256=CVWPZo_ACr_QGH5gAOhoG3jK35peiqipu3PH8ScEYHE,181
|
|
39
40
|
pypynum/ufuncs.py,sha256=g2tewdsGa4VrIq2khR-0SWJoXBitVRN87DulOnTxxDA,2572
|
|
40
|
-
pypynum/utils.py,sha256=
|
|
41
|
-
PyPyNum-1.11.
|
|
42
|
-
PyPyNum-1.11.
|
|
43
|
-
PyPyNum-1.11.
|
|
44
|
-
PyPyNum-1.11.
|
|
41
|
+
pypynum/utils.py,sha256=OqUFVraYDTSubF9QhZm8WC6A0ppnkhVU0YtAeYN9EyU,21048
|
|
42
|
+
PyPyNum-1.11.2.dist-info/METADATA,sha256=46S9DbnAyoufHs7dwgnfUSf5OAnmRjzVvN1qfyMS2dA,77393
|
|
43
|
+
PyPyNum-1.11.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
44
|
+
PyPyNum-1.11.2.dist-info/top_level.txt,sha256=4wW_Xb4bRglmiMsdPAe9f75MkXhNpuN88H17g_Cr5u8,8
|
|
45
|
+
PyPyNum-1.11.2.dist-info/RECORD,,
|
pypynum/Matrix.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from .Array import Array
|
|
2
|
+
from .confs import config
|
|
2
3
|
from .errors import ShapeError
|
|
3
4
|
|
|
4
5
|
MatchError = ShapeError("The shapes of two matrices do not match")
|
|
@@ -195,6 +196,27 @@ class Matrix(Array):
|
|
|
195
196
|
transpose = t
|
|
196
197
|
trace = tr
|
|
197
198
|
|
|
199
|
+
def latex(self, matrix_type="bmatrix", row_spacing=0, col_spacing=0, spacing_unit="mm"):
|
|
200
|
+
valid_matrix_types = ["Bmatrix", "Vmatrix", "array", "bmatrix", "matrix", "pmatrix", "smallmatrix", "vmatrix"]
|
|
201
|
+
valid_units = ["bp", "cc", "cm", "dd", "em", "ex", "in", "mm", "mu", "pc", "pt", "sp"]
|
|
202
|
+
if matrix_type not in valid_matrix_types:
|
|
203
|
+
raise ValueError("Invalid matrix type. Choose from {}".format(valid_matrix_types))
|
|
204
|
+
if spacing_unit not in valid_units:
|
|
205
|
+
raise ValueError("Invalid spacing unit. Choose from {}".format(valid_units))
|
|
206
|
+
alignment = "c" * len(self[0]) if matrix_type == "array" else None
|
|
207
|
+
col_separator = " & " if col_spacing == 0 else " & \\hspace{{{}{}}} & ".format(col_spacing, spacing_unit)
|
|
208
|
+
row_separator = "\\\\" if row_spacing == 0 else "\\\\[{}{}]".format(row_spacing, spacing_unit)
|
|
209
|
+
latex_str = ["\\begin{{{}}}".format(matrix_type), "{{{}}}".format(alignment) if alignment else "",
|
|
210
|
+
row_separator.join([col_separator.join(map(str, row)) for row in self]),
|
|
211
|
+
"\\end{{{}}}".format(matrix_type)]
|
|
212
|
+
return "".join(latex_str)
|
|
213
|
+
|
|
214
|
+
def __repr__(self, use_latex=False):
|
|
215
|
+
use_latex = config.use_latex or use_latex
|
|
216
|
+
return self.latex() if use_latex else super().__repr__()
|
|
217
|
+
|
|
218
|
+
__str__ = __repr__
|
|
219
|
+
|
|
198
220
|
def __setitem__(self, key, value):
|
|
199
221
|
if isinstance(key, (int, slice)):
|
|
200
222
|
self.data[key] = value
|
pypynum/README.md
CHANGED
|
@@ -20,7 +20,7 @@ processing.</font><font color = red>[Python>=3.4]</font>
|
|
|
20
20
|
[](https://pepy.tech/project/pypynum)
|
|
21
21
|
[](https://pepy.tech/project/pypynum)
|
|
22
22
|
|
|
23
|
-
## Version -> 1.11.
|
|
23
|
+
## Version -> 1.11.2 | PyPI -> https://pypi.org/project/PyPyNum/ | Gitee -> https://www.gitee.com/PythonSJL/PyPyNum | GitHub -> https://github.com/PythonSJL/PyPyNum
|
|
24
24
|
|
|
25
25
|

|
|
26
26
|
|
|
@@ -49,6 +49,7 @@ The logo cannot be displayed on PyPI, it can be viewed in Gitee or GitHub.
|
|
|
49
49
|
| `pypynum.Array` | 多维数组 Multidimensional array |
|
|
50
50
|
| `pypynum.chars` | 特殊数学符号 Special mathematical symbols |
|
|
51
51
|
| `pypynum.cipher` | 加密解密算法 Encryption and decryption algorithm |
|
|
52
|
+
| `pypynum.confs` | 通用配置 Universal configuration |
|
|
52
53
|
| `pypynum.constants` | 数学常数集合 Set of mathematical constants |
|
|
53
54
|
| `pypynum.dists` | 概率分布 Probability distribution |
|
|
54
55
|
| `pypynum.equations` | 方程求解 Solving equations |
|
|
@@ -122,93 +123,110 @@ Python interpreter and run it!
|
|
|
122
123
|
```
|
|
123
124
|
!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
|
|
124
125
|
|
|
125
|
-
|
|
126
|
+
新增了Config类
|
|
126
127
|
|
|
127
|
-
|
|
128
|
+
Added Config class
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
130
|
+
Introduction
|
|
131
|
+
The Config class is designed to manage and configure application settings. It provides a mechanism to ensure consistency in configurations and prevents accidental changes by limiting attribute modification.
|
|
132
|
+
Roadmap
|
|
133
|
+
The Config class is currently stable. Future updates may include new configuration options to support additional features.
|
|
134
|
+
Usage
|
|
135
|
+
Modifying Configuration:
|
|
136
|
+
You can modify the configuration by setting attributes directly, but only with predefined boolean values.
|
|
137
|
+
config. use_latex = True # Enable LaTeX formatting
|
|
138
|
+
Reading Configuration:
|
|
139
|
+
You can read the current configuration by accessing the attributes.
|
|
140
|
+
print(config. use_unicode) # Output: False
|
|
141
|
+
Ensuring Exclusive Configuration:
|
|
142
|
+
The Config class is designed to be mutually exclusive, meaning only one configuration item can be True at a time.
|
|
143
|
+
config. use_std = True # This will automatically set other configuration items to False
|
|
144
|
+
Getting Configuration Information:
|
|
145
|
+
Use the __repr__ method to get a string representation of the current configuration.
|
|
146
|
+
print(config) # Output: Config(use_latex=True, use_std=False, use_unicode=False)
|
|
147
|
+
|
|
148
|
+
修改配置时,您可以像这样导入“from pypynum import config”
|
|
149
|
+
|
|
150
|
+
When modifying the configuration, you can import 'from pypynum import config' like this
|
|
151
|
+
|
|
152
|
+
!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
|
|
153
|
+
|
|
154
|
+
一些类现在支持以Unicode或LaTeX显示数据
|
|
155
|
+
|
|
156
|
+
Some classes now support displaying data in Unicode or LaTeX
|
|
137
157
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
8 | 96 19 96 -94 -95 75 40 -74
|
|
211
|
-
=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
|
|
158
|
+
|
|
159
|
+
Polynomial :
|
|
160
|
+
Standard 27x - 85x^4 + 25x^12 + 54x^42 + x^47 - 29x^61 - 73x^66 - 53x^72 - 90x^94 - 99x^97
|
|
161
|
+
Unicode 27x - 85x⁴ + 25x¹² + 54x⁴² + x⁴⁷ - 29x⁶¹ - 73x⁶⁶ - 53x⁷² - 90x⁹⁴ - 99x⁹⁷
|
|
162
|
+
LaTeX 27x - 85x^{4} + 25x^{12} + 54x^{42} + x^{47} - 29x^{61} - 73x^{66} - 53x^{72} - 90x^{94} - 99x^{97}
|
|
163
|
+
|
|
164
|
+
IntervalSet :
|
|
165
|
+
Standard [-94, -61) U [-41, -20] U (-1, 76] U (78, 85)
|
|
166
|
+
Unicode [-94, -61) ∪ [-41, -20] ∪ (-1, 76] ∪ (78, 85)
|
|
167
|
+
LaTeX \left[-94, -61\right) \cup \left[-41, -20\right] \cup \left(-1, 76\right] \cup \left(78, 85\right)
|
|
168
|
+
|
|
169
|
+
Matrix :
|
|
170
|
+
Standard
|
|
171
|
+
[[-65 26 81 -47]
|
|
172
|
+
[ 60 85 4 -23]
|
|
173
|
+
[ 27 56 86 -7]
|
|
174
|
+
[ 38 79 47 76]]
|
|
175
|
+
LaTeX
|
|
176
|
+
\begin{bmatrix}-65 & 26 & 81 & -47\\60 & 85 & 4 & -23\\27 & 56 & 86 & -7\\38 & 79 & 47 & 76\end{bmatrix}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
Matrix自带的latex()方法可以设置LaTeX矩阵类型与元素间距
|
|
180
|
+
The LaTeX() method that comes with Matrix allows you to set the LaTeX matrix type and element spacing
|
|
181
|
+
|
|
182
|
+
EXAMPLE :
|
|
183
|
+
>>> print(A.latex(matrix_type="vmatrix", row_spacing=5, col_spacing=5, spacing_unit="mm"))
|
|
184
|
+
\begin{vmatrix}-65 & \hspace{5mm} & 26 & \hspace{5mm} & 81 & \hspace{5mm} & -47\\[5mm]60 & \hspace{5mm} & 85 & \hspace{5mm} & 4 & \hspace{5mm} & -23\\[5mm]27 & \hspace{5mm} & 56 & \hspace{5mm} & 86 & \hspace{5mm} & -7\\[5mm]38 & \hspace{5mm} & 79 & \hspace{5mm} & 47 & \hspace{5mm} & 76\end{vmatrix}
|
|
185
|
+
|
|
186
|
+
!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
|
|
187
|
+
|
|
188
|
+
新增了IntervalSet类
|
|
189
|
+
|
|
190
|
+
Added IntervalSet class
|
|
191
|
+
|
|
192
|
+
支持区间的各种集合运算
|
|
193
|
+
|
|
194
|
+
Support various set operations for intervals
|
|
195
|
+
|
|
196
|
+
class IntervalSet(builtins.object)
|
|
197
|
+
| __and__ = intersection(self, other)
|
|
198
|
+
| __eq__ = is_equal(self, other)
|
|
199
|
+
| __ge__ = is_superset(self, other)
|
|
200
|
+
| __gt__ = is_proper_superset(self, other)
|
|
201
|
+
| __init__(self, intervals=None)
|
|
202
|
+
| It is a set of intervals and supports multiple operations.
|
|
203
|
+
| :param intervals: A sequence containing multiple intervals
|
|
204
|
+
| __le__ = is_subset(self, other)
|
|
205
|
+
| __lt__ = is_proper_subset(self, other)
|
|
206
|
+
| __matmul__ = complement(self, other)
|
|
207
|
+
| __ne__ = is_not_equal(self, other)
|
|
208
|
+
| __or__ = union(self, other)
|
|
209
|
+
| __repr__(self, use_latex=False)
|
|
210
|
+
| Return repr(self).
|
|
211
|
+
| __sub__ = difference(self, other)
|
|
212
|
+
| __xor__ = symmetric_difference(self, other)
|
|
213
|
+
| add_interval(self, start, end, start_open=False, end_open=False)
|
|
214
|
+
| add_intervals(self, intervals)
|
|
215
|
+
| complement(self, other)
|
|
216
|
+
| difference(self, other)
|
|
217
|
+
| intersection(self, other)
|
|
218
|
+
| is_equal(self, other)
|
|
219
|
+
| is_not_equal(self, other)
|
|
220
|
+
| is_proper_subset(self, other)
|
|
221
|
+
| is_proper_superset(self, other)
|
|
222
|
+
| is_subset(self, other)
|
|
223
|
+
| is_superset(self, other)
|
|
224
|
+
| latex(self)
|
|
225
|
+
| remove_interval(self, start, end, start_open=False, end_open=False)
|
|
226
|
+
| symmetric_difference(self, other)
|
|
227
|
+
| union(self, other)
|
|
228
|
+
|
|
229
|
+
!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
|
|
212
230
|
```
|
|
213
231
|
|
|
214
232
|
### 运行用时测试
|
|
@@ -365,6 +383,10 @@ PyPyNum
|
|
|
365
383
|
├── chars
|
|
366
384
|
│ ├── CLASS
|
|
367
385
|
│ └── FUNCTION
|
|
386
|
+
│ ├── int2subscript(standard_str: str) -> str
|
|
387
|
+
│ ├── int2superscript(standard_str: str) -> str
|
|
388
|
+
│ ├── subscript2int(subscript_str: str) -> str
|
|
389
|
+
│ └── superscript2int(superscript_str: str) -> str
|
|
368
390
|
├── cipher
|
|
369
391
|
│ ├── CLASS
|
|
370
392
|
│ └── FUNCTION
|
|
@@ -380,6 +402,9 @@ PyPyNum
|
|
|
380
402
|
│ ├── rot13(text: str) -> str
|
|
381
403
|
│ ├── substitution(text: str, sub_map: dict, decrypt: bool) -> str
|
|
382
404
|
│ └── vigenere(text: str, key: str, decrypt: bool) -> str
|
|
405
|
+
├── confs
|
|
406
|
+
│ ├── CLASS
|
|
407
|
+
│ └── FUNCTION
|
|
383
408
|
├── constants
|
|
384
409
|
│ ├── CLASS
|
|
385
410
|
│ └── FUNCTION
|
|
@@ -565,9 +590,10 @@ PyPyNum
|
|
|
565
590
|
├── random
|
|
566
591
|
│ ├── CLASS
|
|
567
592
|
│ └── FUNCTION
|
|
593
|
+
│ ├── __create_nested_list(dimensions: Any, func: Any) -> Any
|
|
594
|
+
│ ├── __validate_shape(shape: Any) -> Any
|
|
568
595
|
│ ├── choice(seq: typing.Union[list, tuple, str], shape: typing.Union[list, tuple]) -> Any
|
|
569
596
|
│ ├── gauss(mu: typing.Union[int, float], sigma: typing.Union[int, float], shape: typing.Union[list, tuple]) -> typing.Union[float, list]
|
|
570
|
-
│ ├── gauss_error(original: typing.Union[list, tuple], mu: typing.Union[int, float], sigma: typing.Union[int, float]) -> list
|
|
571
597
|
│ ├── rand(shape: typing.Union[list, tuple]) -> typing.Union[float, list]
|
|
572
598
|
│ ├── randint(a: int, b: int, shape: typing.Union[list, tuple]) -> typing.Union[int, list]
|
|
573
599
|
│ └── uniform(a: typing.Union[int, float], b: typing.Union[int, float], shape: typing.Union[list, tuple]) -> typing.Union[float, list]
|
|
@@ -635,6 +661,7 @@ PyPyNum
|
|
|
635
661
|
└── utils
|
|
636
662
|
├── CLASS
|
|
637
663
|
│ ├── InfIterator(object)/__init__(self: Any, start: typing.Union[int, float, complex], mode: str, common: typing.Union[int, float, complex]) -> Any
|
|
664
|
+
│ ├── IntervalSet(object)/__init__(self: Any, intervals: Any) -> Any
|
|
638
665
|
│ ├── LinkedList(object)/__init__(self: Any) -> Any
|
|
639
666
|
│ ├── LinkedListNode(object)/__init__(self: Any, value: Any, next_node: Any) -> Any
|
|
640
667
|
│ └── OrderedSet(object)/__init__(self: Any, sequence: Any) -> Any
|
pypynum/__init__.py
CHANGED
|
@@ -28,8 +28,9 @@ __email__ = "2261748025@qq.com"
|
|
|
28
28
|
__copyright__ = "2023 to perpetuity. All rights reserved."
|
|
29
29
|
|
|
30
30
|
from .Array import array, fill, full, full_like, zeros, zeros_like, ones, ones_like, aslist, asarray
|
|
31
|
-
from . import
|
|
31
|
+
from .chars import int2superscript, superscript2int, int2subscript, subscript2int
|
|
32
32
|
from .cipher import *
|
|
33
|
+
from .confs import config
|
|
33
34
|
from . import constants
|
|
34
35
|
from .dists import *
|
|
35
36
|
from .equations import *
|
|
@@ -60,10 +61,10 @@ from .tools import *
|
|
|
60
61
|
from .Tree import *
|
|
61
62
|
from . import types
|
|
62
63
|
from .ufuncs import *
|
|
63
|
-
from .utils import OrderedSet, InfIterator, LinkedList
|
|
64
|
+
from .utils import OrderedSet, InfIterator, LinkedList, IntervalSet
|
|
64
65
|
from .Vector import vec
|
|
65
66
|
|
|
66
|
-
__version__ = "1.11.
|
|
67
|
+
__version__ = "1.11.2"
|
|
67
68
|
print("PyPyNum", "Version -> " + __version__, "PyPI -> https://pypi.org/project/PyPyNum/",
|
|
68
69
|
"Gitee -> https://www.gitee.com/PythonSJL/PyPyNum", "GitHub -> https://github.com/PythonSJL/PyPyNum", sep=" | ")
|
|
69
70
|
del math, arr, ite, num, real, geom, ContentError, RandomError, LogicError, InputError, FullError, Union
|
pypynum/chars.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Special mathematical characters
|
|
3
3
|
"""
|
|
4
|
-
|
|
5
4
|
div = "÷"
|
|
6
5
|
mul = "×"
|
|
7
6
|
overline = "̄"
|
|
@@ -26,3 +25,27 @@ tab = [
|
|
|
26
25
|
]
|
|
27
26
|
pi = "Ππ𝜫𝝅𝝥𝝿𝞟𝞹Пп∏ϖ∐ℼㄇ兀"
|
|
28
27
|
others = "¬°‰‱′″∀∂∃∅∆∇∈∉∏∐∑∝∞∟∠∣∥∧∨∩∪∫∬∭∮∯∰∴∵∷∽≈≌≒≠≡≢≤≥≪≫≮≯≰≱≲≳⊕⊙⊥⊿⌒㏑㏒"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def int2superscript(standard_str: str) -> str:
|
|
31
|
+
superscript_map = {"0": "⁰", "1": "¹", "2": "²", "3": "³", "4": "⁴",
|
|
32
|
+
"5": "⁵", "6": "⁶", "7": "⁷", "8": "⁸", "9": "⁹"}
|
|
33
|
+
return "".join([superscript_map.get(digit, digit) for digit in standard_str])
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def superscript2int(superscript_str: str) -> str:
|
|
37
|
+
standard_map = {"⁰": "0", "¹": "1", "²": "2", "³": "3", "⁴": "4",
|
|
38
|
+
"⁵": "5", "⁶": "6", "⁷": "7", "⁸": "8", "⁹": "9"}
|
|
39
|
+
return "".join([standard_map.get(char, char) for char in superscript_str])
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def int2subscript(standard_str: str) -> str:
|
|
43
|
+
subscript_map = {"0": "₀", "1": "₁", "2": "₂", "3": "₃", "4": "₄",
|
|
44
|
+
"5": "₅", "6": "₆", "7": "₇", "8": "₈", "9": "₉"}
|
|
45
|
+
return "".join([subscript_map.get(digit, digit) for digit in standard_str])
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def subscript2int(subscript_str: str) -> str:
|
|
49
|
+
standard_map = {"₀": "0", "₁": "1", "₂": "2", "₃": "3", "₄": "4",
|
|
50
|
+
"₅": "5", "₆": "6", "₇": "7", "₈": "8", "₉": "9"}
|
|
51
|
+
return "".join([standard_map.get(char, char) for char in subscript_str])
|
pypynum/confs.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
class Config:
|
|
2
|
+
"""
|
|
3
|
+
Introduction
|
|
4
|
+
==========
|
|
5
|
+
The Config class is designed to manage and configure application settings. It provides a mechanism to ensure
|
|
6
|
+
consistency in configurations and prevents accidental changes by limiting attribute modification.
|
|
7
|
+
|
|
8
|
+
Roadmap
|
|
9
|
+
==========
|
|
10
|
+
The Config class is currently stable. Future updates may include new configuration options
|
|
11
|
+
to support additional features.
|
|
12
|
+
|
|
13
|
+
Usage
|
|
14
|
+
==========
|
|
15
|
+
|
|
16
|
+
Modifying Configuration:
|
|
17
|
+
----------
|
|
18
|
+
You can modify the configuration by setting attributes directly, but only with predefined boolean values.
|
|
19
|
+
|
|
20
|
+
- config.use_latex = True # Enable LaTeX formatting
|
|
21
|
+
|
|
22
|
+
Reading Configuration:
|
|
23
|
+
----------
|
|
24
|
+
You can read the current configuration by accessing the attributes.
|
|
25
|
+
|
|
26
|
+
- print(config.use_unicode) # Output: False
|
|
27
|
+
|
|
28
|
+
Ensuring Exclusive Configuration:
|
|
29
|
+
----------
|
|
30
|
+
The Config class is designed to be mutually exclusive, meaning only one configuration item can be True at a time.
|
|
31
|
+
|
|
32
|
+
- config.use_std = True # This will automatically set other configuration items to False
|
|
33
|
+
|
|
34
|
+
Getting Configuration Information:
|
|
35
|
+
----------
|
|
36
|
+
Use the `__repr__` method to get a string representation of the current configuration.
|
|
37
|
+
|
|
38
|
+
- print(config) # Output: Config(use_latex=True, use_std=False, use_unicode=False)
|
|
39
|
+
"""
|
|
40
|
+
use_latex = False
|
|
41
|
+
use_unicode = False
|
|
42
|
+
use_std = True
|
|
43
|
+
attributes = ("attributes",)
|
|
44
|
+
|
|
45
|
+
def __init__(self):
|
|
46
|
+
Config.attributes = tuple(attr for attr in dir(Config) if attr[0] != "_" and attr != "attributes")
|
|
47
|
+
|
|
48
|
+
def __setattr__(self, name, value):
|
|
49
|
+
if name in self.attributes:
|
|
50
|
+
value = bool(value)
|
|
51
|
+
if value is True:
|
|
52
|
+
for attr in self.attributes:
|
|
53
|
+
if attr != name and getattr(self, attr, False) is True:
|
|
54
|
+
super().__setattr__(attr, False)
|
|
55
|
+
super().__setattr__(name, value)
|
|
56
|
+
else:
|
|
57
|
+
raise AttributeError(f"Attribute '{name}' is read-only and cannot be added")
|
|
58
|
+
|
|
59
|
+
def __delattr__(self, name):
|
|
60
|
+
raise AttributeError(f"Attribute '{name}' cannot be deleted")
|
|
61
|
+
|
|
62
|
+
def __init_subclass__(cls, **kwargs):
|
|
63
|
+
raise NotImplementedError("Config cannot be subclassed")
|
|
64
|
+
|
|
65
|
+
def __copy__(self):
|
|
66
|
+
raise TypeError("Config cannot be copied")
|
|
67
|
+
|
|
68
|
+
def __deepcopy__(self, memo):
|
|
69
|
+
raise TypeError("Config cannot be copied")
|
|
70
|
+
|
|
71
|
+
def __getattribute__(self, name):
|
|
72
|
+
if name == "__class__":
|
|
73
|
+
raise AttributeError("Access to '__class__' is forbidden")
|
|
74
|
+
return super().__getattribute__(name)
|
|
75
|
+
|
|
76
|
+
def __repr__(self):
|
|
77
|
+
return "Config({})".format(", ".join("{}={}".format(attr, getattr(self, attr)) for attr in self.attributes))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
config = Config()
|
|
81
|
+
del Config
|
pypynum/polynomial.py
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from .confs import config
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
class Polynomial:
|
|
2
5
|
def __init__(self, terms=None):
|
|
3
6
|
if terms is None:
|
|
@@ -111,14 +114,20 @@ class Polynomial:
|
|
|
111
114
|
return self.__repr__(True)
|
|
112
115
|
|
|
113
116
|
def __repr__(self, use_latex=False):
|
|
117
|
+
from .chars import int2superscript
|
|
118
|
+
use_latex = config.use_latex or use_latex
|
|
119
|
+
use_unicode = config.use_unicode
|
|
114
120
|
if not self.terms:
|
|
115
121
|
return "0"
|
|
116
122
|
result = ""
|
|
117
123
|
for i, (degree, coefficient) in enumerate(self.terms):
|
|
118
|
-
if
|
|
124
|
+
if i != 0:
|
|
125
|
+
if coefficient < 0:
|
|
126
|
+
result += " - "
|
|
127
|
+
else:
|
|
128
|
+
result += " + "
|
|
129
|
+
elif coefficient < 0:
|
|
119
130
|
result += "-"
|
|
120
|
-
else:
|
|
121
|
-
result += "+"
|
|
122
131
|
if degree == 0:
|
|
123
132
|
result += str(abs(coefficient))
|
|
124
133
|
elif abs(coefficient) != 1:
|
|
@@ -127,12 +136,12 @@ class Polynomial:
|
|
|
127
136
|
if degree > 1:
|
|
128
137
|
if use_latex:
|
|
129
138
|
result += "x^{" + str(degree) + "}"
|
|
139
|
+
elif use_unicode:
|
|
140
|
+
result += "x" + int2superscript(str(degree))
|
|
130
141
|
else:
|
|
131
142
|
result += "x^" + str(degree)
|
|
132
143
|
else:
|
|
133
144
|
result += "x"
|
|
134
|
-
if result and result[0] == "+":
|
|
135
|
-
result = result[1:]
|
|
136
145
|
return result
|
|
137
146
|
|
|
138
147
|
def __pos__(self):
|
pypynum/random.py
CHANGED
|
@@ -1,129 +1,56 @@
|
|
|
1
|
-
from random import choice as
|
|
2
|
-
from .Array import array
|
|
1
|
+
from random import choice as __choice, gauss as __gauss, randint as __randint, random as __random, uniform as __uniform
|
|
3
2
|
from .errors import RandomError
|
|
4
3
|
from .types import Union, arr, ite, real
|
|
5
4
|
|
|
6
5
|
|
|
7
|
-
def
|
|
8
|
-
if not isinstance(
|
|
9
|
-
raise TypeError("The parameter seq must be iterable")
|
|
10
|
-
if shape is None:
|
|
11
|
-
return _choice(seq)
|
|
12
|
-
if not (isinstance(shape, (list, tuple)) and all([isinstance(item, int) and item and abs(
|
|
13
|
-
item) == item for item in shape])):
|
|
6
|
+
def __validate_shape(shape):
|
|
7
|
+
if not (isinstance(shape, (list, tuple)) and all(isinstance(item, int) and item > 0 for item in shape)):
|
|
14
8
|
raise RandomError("The shape must be all positive integers")
|
|
15
9
|
|
|
16
|
-
def inner(_dimensions):
|
|
17
|
-
if len(_dimensions) == 0:
|
|
18
|
-
return _choice(seq)
|
|
19
|
-
else:
|
|
20
|
-
_array = []
|
|
21
|
-
for i in range(_dimensions[0]):
|
|
22
|
-
_row = inner(_dimensions[1:])
|
|
23
|
-
_array.append(_row)
|
|
24
|
-
return _array
|
|
25
10
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def gauss(mu: real = 0, sigma: real = 1, shape: arr = None) -> Union[float, list]:
|
|
30
|
-
if not (isinstance(mu, (int, float)) and isinstance(sigma, (int, float))):
|
|
31
|
-
raise RandomError("The parameters mu and sigma must both be real numbers")
|
|
32
|
-
if shape is None:
|
|
33
|
-
return _gauss(mu, sigma)
|
|
34
|
-
if not (isinstance(shape, (list, tuple)) and all([isinstance(item, int) and item and abs(
|
|
35
|
-
item) == item for item in shape])):
|
|
36
|
-
raise RandomError("The shape must be all positive integers")
|
|
11
|
+
def __create_nested_list(dimensions, func):
|
|
12
|
+
return func() if len(dimensions) == 0 else [__create_nested_list(dimensions[1:], func)
|
|
13
|
+
for _ in range(dimensions[0])]
|
|
37
14
|
|
|
38
|
-
def inner(_dimensions):
|
|
39
|
-
if len(_dimensions) == 0:
|
|
40
|
-
return _gauss(mu, sigma)
|
|
41
|
-
else:
|
|
42
|
-
_array = []
|
|
43
|
-
for i in range(_dimensions[0]):
|
|
44
|
-
_row = inner(_dimensions[1:])
|
|
45
|
-
_array.append(_row)
|
|
46
|
-
return _array
|
|
47
15
|
|
|
48
|
-
|
|
16
|
+
def choice(seq: ite, shape: arr = None):
|
|
17
|
+
if not isinstance(seq, (list, tuple, str)):
|
|
18
|
+
raise TypeError("The parameter seq must be iterable")
|
|
19
|
+
if shape is not None:
|
|
20
|
+
__validate_shape(shape)
|
|
21
|
+
return __create_nested_list(shape, lambda: __choice(seq))
|
|
22
|
+
return __choice(seq)
|
|
49
23
|
|
|
50
24
|
|
|
51
|
-
def
|
|
25
|
+
def gauss(mu: real = 0, sigma: real = 1, shape: arr = None) -> Union[float, list]:
|
|
52
26
|
if not (isinstance(mu, (int, float)) and isinstance(sigma, (int, float))):
|
|
53
27
|
raise RandomError("The parameters mu and sigma must both be real numbers")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
_copy = []
|
|
59
|
-
for item in _nested_list:
|
|
60
|
-
_copy.append(inner(item))
|
|
61
|
-
return _copy
|
|
62
|
-
else:
|
|
63
|
-
return _nested_list + _gauss(mu, sigma)
|
|
64
|
-
|
|
65
|
-
return inner(original)
|
|
28
|
+
if shape is not None:
|
|
29
|
+
__validate_shape(shape)
|
|
30
|
+
return __create_nested_list(shape, lambda: __gauss(mu, sigma))
|
|
31
|
+
return __gauss(mu, sigma)
|
|
66
32
|
|
|
67
33
|
|
|
68
34
|
def randint(a: int, b: int, shape: arr = None) -> Union[int, list]:
|
|
69
35
|
if not (isinstance(a, int) and isinstance(b, int)):
|
|
70
36
|
raise RandomError("The range must be all integers")
|
|
71
|
-
if shape is None:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
raise RandomError("The shape must be all positive integers")
|
|
76
|
-
|
|
77
|
-
def inner(_dimensions):
|
|
78
|
-
if len(_dimensions) == 0:
|
|
79
|
-
return _randint(a, b)
|
|
80
|
-
else:
|
|
81
|
-
_array = []
|
|
82
|
-
for i in range(_dimensions[0]):
|
|
83
|
-
_row = inner(_dimensions[1:])
|
|
84
|
-
_array.append(_row)
|
|
85
|
-
return _array
|
|
86
|
-
|
|
87
|
-
return inner(shape)
|
|
37
|
+
if shape is not None:
|
|
38
|
+
__validate_shape(shape)
|
|
39
|
+
return __create_nested_list(shape, lambda: __randint(a, b))
|
|
40
|
+
return __randint(a, b)
|
|
88
41
|
|
|
89
42
|
|
|
90
43
|
def rand(shape: arr = None) -> Union[float, list]:
|
|
91
|
-
if shape is None:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
raise RandomError("The shape must be all positive integers")
|
|
96
|
-
|
|
97
|
-
def inner(_dimensions):
|
|
98
|
-
if len(_dimensions) == 0:
|
|
99
|
-
return _random()
|
|
100
|
-
else:
|
|
101
|
-
_array = []
|
|
102
|
-
for i in range(_dimensions[0]):
|
|
103
|
-
_row = inner(_dimensions[1:])
|
|
104
|
-
_array.append(_row)
|
|
105
|
-
return _array
|
|
106
|
-
|
|
107
|
-
return inner(shape)
|
|
44
|
+
if shape is not None:
|
|
45
|
+
__validate_shape(shape)
|
|
46
|
+
return __create_nested_list(shape, __random)
|
|
47
|
+
return __random()
|
|
108
48
|
|
|
109
49
|
|
|
110
50
|
def uniform(a: real, b: real, shape: arr = None) -> Union[float, list]:
|
|
111
51
|
if not (isinstance(a, (int, float)) and isinstance(b, (int, float))):
|
|
112
52
|
raise RandomError("The range must be all real numbers")
|
|
113
|
-
if shape is None:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
raise RandomError("The shape must be all positive integers")
|
|
118
|
-
|
|
119
|
-
def inner(_dimensions):
|
|
120
|
-
if len(_dimensions) == 0:
|
|
121
|
-
return _uniform(a, b)
|
|
122
|
-
else:
|
|
123
|
-
_array = []
|
|
124
|
-
for i in range(_dimensions[0]):
|
|
125
|
-
_row = inner(_dimensions[1:])
|
|
126
|
-
_array.append(_row)
|
|
127
|
-
return _array
|
|
128
|
-
|
|
129
|
-
return inner(shape)
|
|
53
|
+
if shape is not None:
|
|
54
|
+
__validate_shape(shape)
|
|
55
|
+
return __create_nested_list(shape, lambda: __uniform(a, b))
|
|
56
|
+
return __uniform(a, b)
|
pypynum/utils.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from .confs import config
|
|
1
2
|
from .types import num
|
|
2
3
|
|
|
3
4
|
SetError = TypeError("The other object must be an OrderedSet")
|
|
@@ -249,7 +250,7 @@ class OrderedSet:
|
|
|
249
250
|
return self.to_set() != other.to_set()
|
|
250
251
|
|
|
251
252
|
def is_proper_superset(self, other):
|
|
252
|
-
return self > other
|
|
253
|
+
return self > other
|
|
253
254
|
|
|
254
255
|
def is_superset(self, other):
|
|
255
256
|
return self >= other
|
|
@@ -261,7 +262,7 @@ class OrderedSet:
|
|
|
261
262
|
return self <= other
|
|
262
263
|
|
|
263
264
|
def is_proper_subset(self, other):
|
|
264
|
-
return self < other
|
|
265
|
+
return self < other
|
|
265
266
|
|
|
266
267
|
def is_not_equal(self, other):
|
|
267
268
|
return self != other
|
|
@@ -460,3 +461,176 @@ class LinkedList:
|
|
|
460
461
|
linked_list_str += " -> "
|
|
461
462
|
current = current.next_node
|
|
462
463
|
return linked_list_str
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
class IntervalSet:
|
|
467
|
+
def __init__(self, intervals=None):
|
|
468
|
+
"""
|
|
469
|
+
It is a set of intervals and supports multiple operations.
|
|
470
|
+
:param intervals: A sequence containing multiple intervals
|
|
471
|
+
"""
|
|
472
|
+
self.intervals = []
|
|
473
|
+
if intervals:
|
|
474
|
+
self.add_intervals(intervals)
|
|
475
|
+
|
|
476
|
+
def add_intervals(self, intervals):
|
|
477
|
+
for interval in sorted(intervals, key=lambda x: x[0]):
|
|
478
|
+
self.add_interval(*interval)
|
|
479
|
+
|
|
480
|
+
def add_interval(self, start, end, start_open=False, end_open=False):
|
|
481
|
+
if start == float("-inf") or start == float("inf"):
|
|
482
|
+
start_open = True
|
|
483
|
+
if end == float("-inf") or end == float("inf"):
|
|
484
|
+
end_open = True
|
|
485
|
+
start_open = bool(start_open)
|
|
486
|
+
end_open = bool(end_open)
|
|
487
|
+
if start > end or (start == end and (start_open or end_open)) or start == end == float(
|
|
488
|
+
"inf") or start == end == float("-inf"):
|
|
489
|
+
return
|
|
490
|
+
intervals = []
|
|
491
|
+
added = False
|
|
492
|
+
for s, e, so, eo in self.intervals:
|
|
493
|
+
if s <= start < e or s < end <= e or start <= s < end or start < e <= end or start == e and not (
|
|
494
|
+
start_open and eo) or s == end and not (so and end_open):
|
|
495
|
+
start = min(s, start)
|
|
496
|
+
end = max(e, end)
|
|
497
|
+
start_open = start_open if start < s else so if start > s else start_open and so
|
|
498
|
+
end_open = end_open if end > e else eo if end < e else end_open and eo
|
|
499
|
+
elif start > e:
|
|
500
|
+
intervals.append((s, e, so, eo))
|
|
501
|
+
else:
|
|
502
|
+
if not added:
|
|
503
|
+
intervals.append((start, end, start_open, end_open))
|
|
504
|
+
added = True
|
|
505
|
+
intervals.append((s, e, so, eo))
|
|
506
|
+
if not added:
|
|
507
|
+
intervals.append((start, end, start_open, end_open))
|
|
508
|
+
self.intervals = intervals
|
|
509
|
+
|
|
510
|
+
def remove_interval(self, start, end, start_open=False, end_open=False):
|
|
511
|
+
intervals = []
|
|
512
|
+
start_open = bool(start_open)
|
|
513
|
+
end_open = bool(end_open)
|
|
514
|
+
for s, e, so, eo in self.intervals:
|
|
515
|
+
if e <= start:
|
|
516
|
+
intervals.append((s, e, so, eo))
|
|
517
|
+
elif s >= end:
|
|
518
|
+
intervals.append((s, e, so, eo))
|
|
519
|
+
else:
|
|
520
|
+
if s < start:
|
|
521
|
+
intervals.append((s, start, so, not start_open))
|
|
522
|
+
if e > end:
|
|
523
|
+
intervals.append((end, e, not end_open, eo))
|
|
524
|
+
self.intervals = intervals
|
|
525
|
+
|
|
526
|
+
def is_superset(self, other):
|
|
527
|
+
def contains_interval(a, b):
|
|
528
|
+
s1, e1, so1, eo1 = a
|
|
529
|
+
s2, e2, so2, eo2 = b
|
|
530
|
+
return (s2 <= s1 if not so2 else s2 < s1) and (e1 <= e2 if not eo1 else e1 < e2)
|
|
531
|
+
|
|
532
|
+
for interval in other.intervals:
|
|
533
|
+
if not any([contains_interval(interval, other_interval) for other_interval in self.intervals]):
|
|
534
|
+
return False
|
|
535
|
+
return True
|
|
536
|
+
|
|
537
|
+
def is_proper_superset(self, other):
|
|
538
|
+
return self.is_superset(other) and self.is_not_equal(other)
|
|
539
|
+
|
|
540
|
+
def is_equal(self, other):
|
|
541
|
+
return self.intervals == other.intervals
|
|
542
|
+
|
|
543
|
+
def is_proper_subset(self, other):
|
|
544
|
+
return other.is_proper_superset(self)
|
|
545
|
+
|
|
546
|
+
def is_subset(self, other):
|
|
547
|
+
return other.is_superset(self)
|
|
548
|
+
|
|
549
|
+
def is_not_equal(self, other):
|
|
550
|
+
return self.intervals != other.intervals
|
|
551
|
+
|
|
552
|
+
__gt__ = is_proper_superset
|
|
553
|
+
__ge__ = is_superset
|
|
554
|
+
__eq__ = is_equal
|
|
555
|
+
__le__ = is_subset
|
|
556
|
+
__lt__ = is_proper_subset
|
|
557
|
+
__ne__ = is_not_equal
|
|
558
|
+
|
|
559
|
+
def intersection(self, other):
|
|
560
|
+
result = IntervalSet()
|
|
561
|
+
i, j = 0, 0
|
|
562
|
+
while i < len(self.intervals) and j < len(other.intervals):
|
|
563
|
+
s1, e1, so1, eo1 = self.intervals[i]
|
|
564
|
+
s2, e2, so2, eo2 = other.intervals[j]
|
|
565
|
+
start = max(s1, s2)
|
|
566
|
+
end = min(e1, e2)
|
|
567
|
+
start_open = so1 if s1 > s2 else so2 if s1 < s2 else so1 or so2
|
|
568
|
+
end_open = eo1 if e1 < e2 else eo2 if e1 > e2 else eo1 or eo2
|
|
569
|
+
if start < end or (start == end and not (start_open and end_open)):
|
|
570
|
+
result.add_interval(start, end, start_open, end_open)
|
|
571
|
+
if e1 <= e2:
|
|
572
|
+
i += 1
|
|
573
|
+
if e2 <= e1:
|
|
574
|
+
j += 1
|
|
575
|
+
return result
|
|
576
|
+
|
|
577
|
+
def union(self, other):
|
|
578
|
+
result = IntervalSet(self.intervals)
|
|
579
|
+
for interval in other.intervals:
|
|
580
|
+
result.add_interval(*interval)
|
|
581
|
+
return result
|
|
582
|
+
|
|
583
|
+
def difference(self, other):
|
|
584
|
+
result = IntervalSet(self.intervals)
|
|
585
|
+
for s, e, so, eo in other.intervals:
|
|
586
|
+
result.remove_interval(s, e, so, eo)
|
|
587
|
+
return result
|
|
588
|
+
|
|
589
|
+
def complement(self, other):
|
|
590
|
+
return other.difference(self)
|
|
591
|
+
|
|
592
|
+
def symmetric_difference(self, other):
|
|
593
|
+
return self.union(other).difference(self.intersection(other))
|
|
594
|
+
|
|
595
|
+
__and__ = intersection
|
|
596
|
+
__or__ = union
|
|
597
|
+
__sub__ = difference
|
|
598
|
+
__matmul__ = complement
|
|
599
|
+
__xor__ = symmetric_difference
|
|
600
|
+
|
|
601
|
+
def latex(self):
|
|
602
|
+
return self.__repr__(True)
|
|
603
|
+
|
|
604
|
+
def __repr__(self, use_latex=False):
|
|
605
|
+
use_latex = config.use_latex or use_latex
|
|
606
|
+
intervals = self.intervals
|
|
607
|
+
n = len(intervals)
|
|
608
|
+
if n == 0:
|
|
609
|
+
if use_latex:
|
|
610
|
+
return "\\emptyset"
|
|
611
|
+
elif config.use_unicode:
|
|
612
|
+
return "∅"
|
|
613
|
+
else:
|
|
614
|
+
return "EmptySet"
|
|
615
|
+
|
|
616
|
+
def format_interval(s, e, so, eo):
|
|
617
|
+
infinity = "\\infty" if use_latex else "∞" if config.use_unicode else "inf"
|
|
618
|
+
if s == e:
|
|
619
|
+
if use_latex:
|
|
620
|
+
return "\\left\\{" + str(s) + "\\right\\}"
|
|
621
|
+
else:
|
|
622
|
+
return "{{{}}}".format(s)
|
|
623
|
+
else:
|
|
624
|
+
start_str = str(s).replace("inf", infinity)
|
|
625
|
+
end_str = str(e).replace("inf", infinity)
|
|
626
|
+
if use_latex:
|
|
627
|
+
start_bracket = "\\left(" if so else "\\left["
|
|
628
|
+
end_bracket = "\\right)" if eo else "\\right]"
|
|
629
|
+
else:
|
|
630
|
+
start_bracket = "(" if so else "["
|
|
631
|
+
end_bracket = ")" if eo else "]"
|
|
632
|
+
return "{}{}, {}{}".format(start_bracket, start_str, end_str, end_bracket)
|
|
633
|
+
|
|
634
|
+
formatted_intervals = [format_interval(*interval) for interval in intervals]
|
|
635
|
+
union = " \\cup " if use_latex else " ∪ " if config.use_unicode else " U "
|
|
636
|
+
return union.join(formatted_intervals)
|
|
File without changes
|
|
File without changes
|