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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyPyNum
3
- Version: 1.11.1
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
  [![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.11.1 | PyPI -> https://pypi.org/project/PyPyNum/ | Gitee -> https://www.gitee.com/PythonSJL/PyPyNum | GitHub -> https://github.com/PythonSJL/PyPyNum
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
  ![LOGO](PyPyNum.png)
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
- <<<New functions added>>>
342
+ Added Config class
342
343
 
343
- ├── highprec
344
- │ └── FUNCTION
345
- │ ├── calc_e(digits: int, method: str) -> decimal.Decimal
346
- │ ├── calc_phi(digits: int, method: str) -> decimal.Decimal
347
- │ └── calc_pi(digits: int, method: str) -> decimal.Decimal
348
- ├── pprinters
349
- │ └── FUNCTION
350
- │ └── pprint_matrix(matrix: Any, style: Any, output: Any) -> Any
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
- 新增的highprec模块用于高精度计算
355
-
356
- The newly added highprec module
357
- is used for high-precision
358
- calculations
359
-
360
- =!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
361
-
362
- 函数pprint_matrix支持五种矩阵美化输出
363
- 风格:["numpy", "mpmath", "sympy",
364
- "borderless", "numbered"]
365
-
366
- The function pprint_matrix
367
- supports five types of matrix
368
- beautification output styles:
369
- ["numpy", "mpmath", "sympy",
370
- "borderless", "numbered"]
371
-
372
- [[-81 -3 83 36 19 -77 -29 14]
373
- [-73 -14 34 58 -55 6 -84 4]
374
- [ 33 80 -31 -36 49 -22 66 -1]
375
- [-78 69 91 -59 89 40 2 68]
376
- [-62 59 -54 -92 -80 -13 60 -99]
377
- [ 96 -35 -34 65 -31 -88 -1 -31]
378
- [ 13 96 -72 26 -44 -74 -48 -49]
379
- [ 96 19 96 -94 -95 75 40 -74]]
380
-
381
- [-81 -3 83 36 19 -77 -29 14]
382
- [-73 -14 34 58 -55 6 -84 4]
383
- [ 33 80 -31 -36 49 -22 66 -1]
384
- [-78 69 91 -59 89 40 2 68]
385
- [-62 59 -54 -92 -80 -13 60 -99]
386
- [ 96 -35 -34 65 -31 -88 -1 -31]
387
- [ 13 96 -72 26 -44 -74 -48 -49]
388
- [ 96 19 96 -94 -95 75 40 -74]
389
-
390
- ⎡-81 -3 83 36 19 -77 -29 14⎤
391
- ⎢ ⎥
392
- ⎢-73 -14 34 58 -55 6 -84 4⎥
393
- ⎢ ⎥
394
- 33 80 -31 -36 49 -22 66 -1⎥
395
- ⎢ ⎥
396
- ⎢-78 69 91 -59 89 40 2 68⎥
397
- ⎢ ⎥
398
- ⎢-62 59 -54 -92 -80 -13 60 -99⎥
399
- ⎢ ⎥
400
- 96 -35 -34 65 -31 -88 -1 -31⎥
401
- ⎢ ⎥
402
- 13 96 -72 26 -44 -74 -48 -49⎥
403
- ⎢ ⎥
404
- 96 19 96 -94 -95 75 40 -74⎦
405
-
406
- -81 -3 83 36 19 -77 -29 14
407
- -73 -14 34 58 -55 6 -84 4
408
- 33 80 -31 -36 49 -22 66 -1
409
- -78 69 91 -59 89 40 2 68
410
- -62 59 -54 -92 -80 -13 60 -99
411
- 96 -35 -34 65 -31 -88 -1 -31
412
- 13 96 -72 26 -44 -74 -48 -49
413
- 96 19 96 -94 -95 75 40 -74
414
-
415
- | 1 2 3 4 5 6 7 8
416
- -----------------------------------
417
- 1 | -81 -3 83 36 19 -77 -29 14
418
- 2 | -73 -14 34 58 -55 6 -84 4
419
- 3 | 33 80 -31 -36 49 -22 66 -1
420
- 4 | -78 69 91 -59 89 40 2 68
421
- 5 | -62 59 -54 -92 -80 -13 60 -99
422
- 6 | 96 -35 -34 65 -31 -88 -1 -31
423
- 7 | 13 96 -72 26 -44 -74 -48 -49
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=gYxSxrRlWlGdkKp6QtkwvotAKOkTUWcSprzUwD65F0s,19038
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=-Pnlf97kz1Yz1dCQ6AL3YML_XF839RJLDjKjqdZnTU8,61028
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=XqnQdXCNj3zkCMU75RDP5SyeGcdyhKcHwiRFsEI4reQ,2743
17
- pypynum/chars.py,sha256=VcK9w0i73FMCzc-9aIibjdHqyMsofJXdoBq0d8L7Vr0,1001
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=qRNITUY5Tcx43bccs2kx_dmvL_heLM0v-IcR-FyQBl8,9465
30
+ pypynum/polynomial.py,sha256=gF2KRLqBHItJ8tdTjFT4FOJqVkWiHTBdGREp3roppB0,9778
30
31
  pypynum/pprinters.py,sha256=Qt9-V5SUyoOqC3lsUU5D5zSSM-MmcnFCUyUtLxhS4pE,2514
31
- pypynum/random.py,sha256=vfTtyH5yOSKJoSI_-NT_Tg8wC-ZXT0wt34f87oaSpJY,4610
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=oeHpAMFItWXfKjb0UQITPwMVKZBd3H5JT3R-jBgn2_w,14466
41
- PyPyNum-1.11.1.dist-info/METADATA,sha256=66IUHOc7kFjd5cLLnkuQDFdwV45kHmLyXkQbtO80RQA,75407
42
- PyPyNum-1.11.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
43
- PyPyNum-1.11.1.dist-info/top_level.txt,sha256=4wW_Xb4bRglmiMsdPAe9f75MkXhNpuN88H17g_Cr5u8,8
44
- PyPyNum-1.11.1.dist-info/RECORD,,
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
  [![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.11.1 | PyPI -> https://pypi.org/project/PyPyNum/ | Gitee -> https://www.gitee.com/PythonSJL/PyPyNum | GitHub -> https://github.com/PythonSJL/PyPyNum
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
  ![LOGO](PyPyNum.png)
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
- <<<New functions added>>>
128
+ Added Config class
128
129
 
129
- ├── highprec
130
- │ └── FUNCTION
131
- │ ├── calc_e(digits: int, method: str) -> decimal.Decimal
132
- │ ├── calc_phi(digits: int, method: str) -> decimal.Decimal
133
- │ └── calc_pi(digits: int, method: str) -> decimal.Decimal
134
- ├── pprinters
135
- │ └── FUNCTION
136
- │ └── pprint_matrix(matrix: Any, style: Any, output: Any) -> Any
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
- 新增的highprec模块用于高精度计算
141
-
142
- The newly added highprec module
143
- is used for high-precision
144
- calculations
145
-
146
- =!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
147
-
148
- 函数pprint_matrix支持五种矩阵美化输出
149
- 风格:["numpy", "mpmath", "sympy",
150
- "borderless", "numbered"]
151
-
152
- The function pprint_matrix
153
- supports five types of matrix
154
- beautification output styles:
155
- ["numpy", "mpmath", "sympy",
156
- "borderless", "numbered"]
157
-
158
- [[-81 -3 83 36 19 -77 -29 14]
159
- [-73 -14 34 58 -55 6 -84 4]
160
- [ 33 80 -31 -36 49 -22 66 -1]
161
- [-78 69 91 -59 89 40 2 68]
162
- [-62 59 -54 -92 -80 -13 60 -99]
163
- [ 96 -35 -34 65 -31 -88 -1 -31]
164
- [ 13 96 -72 26 -44 -74 -48 -49]
165
- [ 96 19 96 -94 -95 75 40 -74]]
166
-
167
- [-81 -3 83 36 19 -77 -29 14]
168
- [-73 -14 34 58 -55 6 -84 4]
169
- [ 33 80 -31 -36 49 -22 66 -1]
170
- [-78 69 91 -59 89 40 2 68]
171
- [-62 59 -54 -92 -80 -13 60 -99]
172
- [ 96 -35 -34 65 -31 -88 -1 -31]
173
- [ 13 96 -72 26 -44 -74 -48 -49]
174
- [ 96 19 96 -94 -95 75 40 -74]
175
-
176
- ⎡-81 -3 83 36 19 -77 -29 14⎤
177
- ⎢ ⎥
178
- ⎢-73 -14 34 58 -55 6 -84 4⎥
179
- ⎢ ⎥
180
- 33 80 -31 -36 49 -22 66 -1⎥
181
- ⎢ ⎥
182
- ⎢-78 69 91 -59 89 40 2 68⎥
183
- ⎢ ⎥
184
- ⎢-62 59 -54 -92 -80 -13 60 -99⎥
185
- ⎢ ⎥
186
- 96 -35 -34 65 -31 -88 -1 -31⎥
187
- ⎢ ⎥
188
- 13 96 -72 26 -44 -74 -48 -49⎥
189
- ⎢ ⎥
190
- 96 19 96 -94 -95 75 40 -74⎦
191
-
192
- -81 -3 83 36 19 -77 -29 14
193
- -73 -14 34 58 -55 6 -84 4
194
- 33 80 -31 -36 49 -22 66 -1
195
- -78 69 91 -59 89 40 2 68
196
- -62 59 -54 -92 -80 -13 60 -99
197
- 96 -35 -34 65 -31 -88 -1 -31
198
- 13 96 -72 26 -44 -74 -48 -49
199
- 96 19 96 -94 -95 75 40 -74
200
-
201
- | 1 2 3 4 5 6 7 8
202
- -----------------------------------
203
- 1 | -81 -3 83 36 19 -77 -29 14
204
- 2 | -73 -14 34 58 -55 6 -84 4
205
- 3 | 33 80 -31 -36 49 -22 66 -1
206
- 4 | -78 69 91 -59 89 40 2 68
207
- 5 | -62 59 -54 -92 -80 -13 60 -99
208
- 6 | 96 -35 -34 65 -31 -88 -1 -31
209
- 7 | 13 96 -72 26 -44 -74 -48 -49
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 chars
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.1"
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 coefficient < 0:
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 _choice, gauss as _gauss, randint as _randint, random as _random, uniform as _uniform
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 choice(seq: ite, shape: arr = None):
8
- if not isinstance(seq, (list, tuple, str)):
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
- return inner(shape)
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
- return inner(shape)
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 gauss_error(original: arr, mu: real = 0, sigma: real = 1) -> list:
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
- array(original)
55
-
56
- def inner(_nested_list):
57
- if isinstance(_nested_list, list):
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
- return _randint(a, b)
73
- if not (isinstance(shape, (list, tuple)) and all([isinstance(item, int) and item and abs(
74
- item) == item for item in shape])):
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
- return _random()
93
- if not (isinstance(shape, (list, tuple)) and all([isinstance(item, int) and item and abs(
94
- item) == item for item in shape])):
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
- return _uniform(a, b)
115
- if not (isinstance(shape, (list, tuple)) and all([isinstance(item, int) and item and abs(
116
- item) == item for item in shape])):
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 and 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 and 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)