BUCToolkit 1.0b0__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.
Files changed (88) hide show
  1. BUCToolkit/BatchGenerate/CheckStructures.py +198 -0
  2. BUCToolkit/BatchGenerate/__init__.py +6 -0
  3. BUCToolkit/BatchGenerate/coords_interp.py +127 -0
  4. BUCToolkit/BatchGenerate/initial_ads_structures.py +351 -0
  5. BUCToolkit/BatchGenerate/random_replace.py +88 -0
  6. BUCToolkit/BatchMC/MetropolisMC.py +210 -0
  7. BUCToolkit/BatchMC/_BaseMC.py +863 -0
  8. BUCToolkit/BatchMC/__init__.py +8 -0
  9. BUCToolkit/BatchMD/BiasedMD.py +276 -0
  10. BUCToolkit/BatchMD/NVE.py +92 -0
  11. BUCToolkit/BatchMD/NVT.py +510 -0
  12. BUCToolkit/BatchMD/_BaseMD.py +1251 -0
  13. BUCToolkit/BatchMD/__init__.py +18 -0
  14. BUCToolkit/BatchMD/constrained_md/BiasedMD.py +273 -0
  15. BUCToolkit/BatchMD/constrained_md/ConstrNVE.py +169 -0
  16. BUCToolkit/BatchMD/constrained_md/ConstrNVT.py +462 -0
  17. BUCToolkit/BatchMD/constrained_md/NVE.py +78 -0
  18. BUCToolkit/BatchMD/constrained_md/NVT.py +346 -0
  19. BUCToolkit/BatchMD/constrained_md/_BaseMD.py +440 -0
  20. BUCToolkit/BatchMD/constrained_md/_ConstrBaseMD.py +607 -0
  21. BUCToolkit/BatchMD/constrained_md/__init__.py +18 -0
  22. BUCToolkit/BatchOptim/TS/CI_NEB.py +286 -0
  23. BUCToolkit/BatchOptim/TS/Dimer.py +950 -0
  24. BUCToolkit/BatchOptim/TS/__init__.py +10 -0
  25. BUCToolkit/BatchOptim/_BaseOpt.py +702 -0
  26. BUCToolkit/BatchOptim/__init__.py +22 -0
  27. BUCToolkit/BatchOptim/_utils/__init__.py +6 -0
  28. BUCToolkit/BatchOptim/_utils/_line_search.py +972 -0
  29. BUCToolkit/BatchOptim/_utils/_warnings.py +11 -0
  30. BUCToolkit/BatchOptim/frequency.py +496 -0
  31. BUCToolkit/BatchOptim/minimize/CG.py +256 -0
  32. BUCToolkit/BatchOptim/minimize/FIRE.py +310 -0
  33. BUCToolkit/BatchOptim/minimize/QN.py +205 -0
  34. BUCToolkit/BatchOptim/minimize/__init__.py +17 -0
  35. BUCToolkit/BatchStructures/BatchStructuresBase.py +2261 -0
  36. BUCToolkit/BatchStructures/StructuresIO.py +1394 -0
  37. BUCToolkit/BatchStructures/__init__.py +15 -0
  38. BUCToolkit/Preprocessing/__init__.py +7 -0
  39. BUCToolkit/Preprocessing/load_files.py +1680 -0
  40. BUCToolkit/Preprocessing/preprocessing.py +923 -0
  41. BUCToolkit/Preprocessing/sampling.py +299 -0
  42. BUCToolkit/Preprocessing/supercells.py +140 -0
  43. BUCToolkit/Preprocessing/write_files.py +524 -0
  44. BUCToolkit/StandardTemplate.py +417 -0
  45. BUCToolkit/__init__.py +33 -0
  46. BUCToolkit/_version.py +7 -0
  47. BUCToolkit/api/ConstrainedMolecularDynamics.py +347 -0
  48. BUCToolkit/api/DataLoaders.py +321 -0
  49. BUCToolkit/api/Losses.py +170 -0
  50. BUCToolkit/api/Metrics.py +84 -0
  51. BUCToolkit/api/ModelOptims.py +296 -0
  52. BUCToolkit/api/MolecularDynamics.py +282 -0
  53. BUCToolkit/api/MonteCarlo.py +280 -0
  54. BUCToolkit/api/NEB.py +325 -0
  55. BUCToolkit/api/Predictor.py +292 -0
  56. BUCToolkit/api/StructureOptimization.py +484 -0
  57. BUCToolkit/api/Trainer.py +635 -0
  58. BUCToolkit/api/VibrationAnalysis.py +279 -0
  59. BUCToolkit/api/__init__.py +38 -0
  60. BUCToolkit/api/_io.py +1026 -0
  61. BUCToolkit/cli/__init__.py +20 -0
  62. BUCToolkit/cli/cli.py +934 -0
  63. BUCToolkit/cli/input_stub.py +140 -0
  64. BUCToolkit/cli/main.py +368 -0
  65. BUCToolkit/cli/print_logo.py +149 -0
  66. BUCToolkit/cli/template_model.py +6 -0
  67. BUCToolkit/io.py +30 -0
  68. BUCToolkit/utils/AtomSelector.py +64 -0
  69. BUCToolkit/utils/AtomicNumber2Properties.py +39 -0
  70. BUCToolkit/utils/ElemListReduce.py +52 -0
  71. BUCToolkit/utils/Ewald.py +210 -0
  72. BUCToolkit/utils/IrregularTensorReformat.py +59 -0
  73. BUCToolkit/utils/_CheckModules.py +30 -0
  74. BUCToolkit/utils/_Element_info.py +527 -0
  75. BUCToolkit/utils/__init__.py +22 -0
  76. BUCToolkit/utils/_para_flatt_list.py +131 -0
  77. BUCToolkit/utils/_print_formatter.py +59 -0
  78. BUCToolkit/utils/check_structures.py +204 -0
  79. BUCToolkit/utils/function_utils.py +147 -0
  80. BUCToolkit/utils/grad_functions.py +69 -0
  81. BUCToolkit/utils/index_ops.py +432 -0
  82. BUCToolkit/utils/setup_loggers.py +137 -0
  83. buctoolkit-1.0b0.dist-info/METADATA +28 -0
  84. buctoolkit-1.0b0.dist-info/RECORD +88 -0
  85. buctoolkit-1.0b0.dist-info/WHEEL +5 -0
  86. buctoolkit-1.0b0.dist-info/entry_points.txt +6 -0
  87. buctoolkit-1.0b0.dist-info/licenses/LICENSE +21 -0
  88. buctoolkit-1.0b0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,527 @@
1
+ """
2
+ Atomic masses & number information
3
+
4
+ Constants:
5
+ MASS: Dict[element symbol : atomic mass]
6
+
7
+ N_MASS: Dict[atomic number: atomic mass]
8
+
9
+ ATOMIC_NUMBER: Dict[atomic number : element symbol]
10
+
11
+ ATOMIC_SYMBOL: Dict[element symbol : atomic number]
12
+
13
+ NONRADIOACTIVE_METALS: The set of non-radioactive metals
14
+
15
+ TRANSITION_METALS: The set of transition metals
16
+
17
+ TRANSITION_P_METALS: The set of transition metals & p-zone metals
18
+
19
+ NOBLE_METALS: The set of noble metals
20
+ """
21
+
22
+ # Copyright (c) 2024-2025.7.4, BUCToolkit.
23
+ # Authors: Pu Pengxin, Song Xin
24
+ # Version: 0.9a
25
+ # File: _Element_info.py
26
+ # Environment: Python 3.12
27
+
28
+ MASS = {
29
+ "X": 1., # A placeholder
30
+ "H": 1.008,
31
+ "He": 4.0026,
32
+ "Li": 6.94,
33
+ "Be": 9.0122,
34
+ "B": 10.81,
35
+ "C": 12.011,
36
+ "N": 14.007,
37
+ "O": 15.999,
38
+ "F": 18.998,
39
+ "Ne": 20.180,
40
+ "Na": 22.990,
41
+ "Mg": 24.305,
42
+ "Al": 26.982,
43
+ "Si": 28.085,
44
+ "P": 30.974,
45
+ "S": 32.06,
46
+ "Cl": 35.45,
47
+ "Ar": 39.948,
48
+ "K": 39.098,
49
+ "Ca": 40.078,
50
+ "Sc": 44.956,
51
+ "Ti": 47.867,
52
+ "V": 50.942,
53
+ "Cr": 51.996,
54
+ "Mn": 54.938,
55
+ "Fe": 55.845,
56
+ "Co": 58.933,
57
+ "Ni": 58.693,
58
+ "Cu": 63.546,
59
+ "Zn": 65.38,
60
+ "Ga": 69.723,
61
+ "Ge": 72.630,
62
+ "As": 74.922,
63
+ "Se": 78.971,
64
+ "Br": 79.904,
65
+ "Kr": 83.798,
66
+ "Rb": 85.468,
67
+ "Sr": 87.62,
68
+ "Y": 88.906,
69
+ "Zr": 91.224,
70
+ "Nb": 92.906,
71
+ "Mo": 95.95,
72
+ "Tc": 98.0,
73
+ "Ru": 101.07,
74
+ "Rh": 102.91,
75
+ "Pd": 106.42,
76
+ "Ag": 107.87,
77
+ "Cd": 112.41,
78
+ "In": 114.82,
79
+ "Sn": 118.71,
80
+ "Sb": 121.76,
81
+ "Te": 127.60,
82
+ "I": 126.90,
83
+ "Xe": 131.29,
84
+ "Cs": 132.91,
85
+ "Ba": 137.33,
86
+ "La": 138.91,
87
+ "Ce": 140.12,
88
+ "Pr": 140.91,
89
+ "Nd": 144.24,
90
+ "Pm": 145.0,
91
+ "Sm": 150.36,
92
+ "Eu": 151.96,
93
+ "Gd": 157.25,
94
+ "Tb": 158.93,
95
+ "Dy": 162.50,
96
+ "Ho": 164.93,
97
+ "Er": 167.26,
98
+ "Tm": 168.93,
99
+ "Yb": 173.05,
100
+ "Lu": 174.97,
101
+ "Hf": 178.49,
102
+ "Ta": 180.95,
103
+ "W": 183.84,
104
+ "Re": 186.21,
105
+ "Os": 190.23,
106
+ "Ir": 192.22,
107
+ "Pt": 195.08,
108
+ "Au": 196.97,
109
+ "Hg": 200.59,
110
+ "Tl": 204.38,
111
+ "Pb": 207.2,
112
+ "Bi": 208.98,
113
+ "Po": 209.0,
114
+ "At": 210.0,
115
+ "Rn": 222.0,
116
+ } # element set
117
+
118
+ N_MASS = {
119
+ 0: 1., # A placeholder
120
+ 1: 1.008,
121
+ 2: 4.0026,
122
+ 3: 6.94,
123
+ 4: 9.0122,
124
+ 5: 10.81,
125
+ 6: 12.011,
126
+ 7: 14.007,
127
+ 8: 15.999,
128
+ 9: 18.998,
129
+ 10: 20.180,
130
+ 11: 22.990,
131
+ 12: 24.305,
132
+ 13: 26.982,
133
+ 14: 28.085,
134
+ 15: 30.974,
135
+ 16: 32.06,
136
+ 17: 35.45,
137
+ 18: 39.948,
138
+ 19: 39.098,
139
+ 20: 40.078,
140
+ 21: 44.956,
141
+ 22: 47.867,
142
+ 23: 50.942,
143
+ 24: 51.996,
144
+ 25: 54.938,
145
+ 26: 55.845,
146
+ 27: 58.933,
147
+ 28: 58.693,
148
+ 29: 63.546,
149
+ 30: 65.38,
150
+ 31: 69.723,
151
+ 32: 72.630,
152
+ 33: 74.922,
153
+ 34: 78.971,
154
+ 35: 79.904,
155
+ 36: 83.798,
156
+ 37: 85.468,
157
+ 38: 87.62,
158
+ 39: 88.906,
159
+ 40: 91.224,
160
+ 41: 92.906,
161
+ 42: 95.95,
162
+ 43: 98.0,
163
+ 44: 101.07,
164
+ 45: 102.91,
165
+ 46: 106.42,
166
+ 47: 107.87,
167
+ 48: 112.41,
168
+ 49: 114.82,
169
+ 50: 118.71,
170
+ 51: 121.76,
171
+ 52: 127.60,
172
+ 53: 126.90,
173
+ 54: 131.29,
174
+ 55: 132.91,
175
+ 56: 137.33,
176
+ 57: 138.91,
177
+ 58: 140.12,
178
+ 59: 140.91,
179
+ 60: 144.24,
180
+ 61: 145.0,
181
+ 62: 150.36,
182
+ 63: 151.96,
183
+ 64: 157.25,
184
+ 65: 158.93,
185
+ 66: 162.50,
186
+ 67: 164.93,
187
+ 68: 167.26,
188
+ 69: 168.93,
189
+ 70: 173.05,
190
+ 71: 174.97,
191
+ 72: 178.49,
192
+ 73: 180.95,
193
+ 74: 183.84,
194
+ 75: 186.21,
195
+ 76: 190.23,
196
+ 77: 192.22,
197
+ 78: 195.08,
198
+ 79: 196.97,
199
+ 80: 200.59,
200
+ 81: 204.38,
201
+ 82: 207.2,
202
+ 83: 208.98,
203
+ 84: 209.0,
204
+ 85: 210.0,
205
+ 86: 222.0,
206
+ } # element set
207
+
208
+ ATOMIC_NUMBER: 'dict(atomic number: element symbol)' = {
209
+ 0: "X", # A placeholder
210
+ 1: "H",
211
+ 2: "He",
212
+ 3: "Li",
213
+ 4: "Be",
214
+ 5: "B",
215
+ 6: "C",
216
+ 7: "N",
217
+ 8: "O",
218
+ 9: "F",
219
+ 10: "Ne",
220
+ 11: "Na",
221
+ 12: "Mg",
222
+ 13: "Al",
223
+ 14: "Si",
224
+ 15: "P",
225
+ 16: "S",
226
+ 17: "Cl",
227
+ 18: "Ar",
228
+ 19: "K",
229
+ 20: "Ca",
230
+ 21: "Sc",
231
+ 22: "Ti",
232
+ 23: "V",
233
+ 24: "Cr",
234
+ 25: "Mn",
235
+ 26: "Fe",
236
+ 27: "Co",
237
+ 28: "Ni",
238
+ 29: "Cu",
239
+ 30: "Zn",
240
+ 31: "Ga",
241
+ 32: "Ge",
242
+ 33: "As",
243
+ 34: "Se",
244
+ 35: "Br",
245
+ 36: "Kr",
246
+ 37: "Rb",
247
+ 38: "Sr",
248
+ 39: "Y",
249
+ 40: "Zr",
250
+ 41: "Nb",
251
+ 42: "Mo",
252
+ 43: "Tc",
253
+ 44: "Ru",
254
+ 45: "Rh",
255
+ 46: "Pd",
256
+ 47: "Ag",
257
+ 48: "Cd",
258
+ 49: "In",
259
+ 50: "Sn",
260
+ 51: "Sb",
261
+ 52: "Te",
262
+ 53: "I",
263
+ 54: "Xe",
264
+ 55: "Cs",
265
+ 56: "Ba",
266
+ 57: "La",
267
+ 58: "Ce",
268
+ 59: "Pr",
269
+ 60: "Nd",
270
+ 61: "Pm",
271
+ 62: "Sm",
272
+ 63: "Eu",
273
+ 64: "Gd",
274
+ 65: "Tb",
275
+ 66: "Dy",
276
+ 67: "Ho",
277
+ 68: "Er",
278
+ 69: "Tm",
279
+ 70: "Yb",
280
+ 71: "Lu",
281
+ 72: "Hf",
282
+ 73: "Ta",
283
+ 74: "W",
284
+ 75: "Re",
285
+ 76: "Os",
286
+ 77: "Ir",
287
+ 78: "Pt",
288
+ 79: "Au",
289
+ 80: "Hg",
290
+ 81: "Tl",
291
+ 82: "Pb",
292
+ 83: "Bi",
293
+ 84: "Po",
294
+ 85: "At",
295
+ 86: "Rn",
296
+ }
297
+
298
+ ATOMIC_SYMBOL: 'dict(element symbol : atomic number)' = {
299
+ "X": 0,
300
+ "H": 1,
301
+ "He": 2,
302
+ "Li": 3,
303
+ "Be": 4,
304
+ "B": 5,
305
+ "C": 6,
306
+ "N": 7,
307
+ "O": 8,
308
+ "F": 9,
309
+ "Ne": 10,
310
+ "Na": 11,
311
+ "Mg": 12,
312
+ "Al": 13,
313
+ "Si": 14,
314
+ "P": 15,
315
+ "S": 16,
316
+ "Cl": 17,
317
+ "Ar": 18,
318
+ "K": 19,
319
+ "Ca": 20,
320
+ "Sc": 21,
321
+ "Ti": 22,
322
+ "V": 23,
323
+ "Cr": 24,
324
+ "Mn": 25,
325
+ "Fe": 26,
326
+ "Co": 27,
327
+ "Ni": 28,
328
+ "Cu": 29,
329
+ "Zn": 30,
330
+ "Ga": 31,
331
+ "Ge": 32,
332
+ "As": 33,
333
+ "Se": 34,
334
+ "Br": 35,
335
+ "Kr": 36,
336
+ "Rb": 37,
337
+ "Sr": 38,
338
+ "Y": 39,
339
+ "Zr": 40,
340
+ "Nb": 41,
341
+ "Mo": 42,
342
+ "Tc": 43,
343
+ "Ru": 44,
344
+ "Rh": 45,
345
+ "Pd": 46,
346
+ "Ag": 47,
347
+ "Cd": 48,
348
+ "In": 49,
349
+ "Sn": 50,
350
+ "Sb": 51,
351
+ "Te": 52,
352
+ "I": 53,
353
+ "Xe": 54,
354
+ "Cs": 55,
355
+ "Ba": 56,
356
+ "La": 57,
357
+ "Ce": 58,
358
+ "Pr": 59,
359
+ "Nd": 60,
360
+ "Pm": 61,
361
+ "Sm": 62,
362
+ "Eu": 63,
363
+ "Gd": 64,
364
+ "Tb": 65,
365
+ "Dy": 66,
366
+ "Ho": 67,
367
+ "Er": 68,
368
+ "Tm": 69,
369
+ "Yb": 70,
370
+ "Lu": 71,
371
+ "Hf": 72,
372
+ "Ta": 73,
373
+ "W": 74,
374
+ "Re": 75,
375
+ "Os": 76,
376
+ "Ir": 77,
377
+ "Pt": 78,
378
+ "Au": 79,
379
+ "Hg": 80,
380
+ "Tl": 81,
381
+ "Pb": 82,
382
+ "Bi": 83,
383
+ "Po": 84,
384
+ "At": 85,
385
+ "Rn": 86,
386
+ }
387
+
388
+ NONRADIOACTIVE_METALS: "Te set of non-radioactive metals" = {
389
+ "Li", # 锂
390
+ "Be", # 铍
391
+ "Na", # 钠
392
+ "Mg", # 镁
393
+ "Al", # 铝
394
+ "K", # 钾
395
+ "Ca", # 钙
396
+ "Sc", # 钪
397
+ "Ti", # 钛
398
+ "V", # 钒
399
+ "Cr", # 铬
400
+ "Mn", # 锰
401
+ "Fe", # 铁
402
+ "Co", # 钴
403
+ "Ni", # 镍
404
+ "Cu", # 铜
405
+ "Zn", # 锌
406
+ "Ga", # 镓
407
+ "Rb", # 铷
408
+ "Sr", # 锶
409
+ "Y", # 钇
410
+ "Zr", # 锆
411
+ "Nb", # 铌
412
+ "Mo", # 钼
413
+ "Ru", # 钌
414
+ "Rh", # 铑
415
+ "Pd", # 钯
416
+ "Ag", # 银
417
+ "Cd", # 镉
418
+ "In", # 铟
419
+ "Sn", # 锡
420
+ "Cs", # 铯
421
+ "Ba", # 钡
422
+ "La", # 镧
423
+ "Ce", # 铈
424
+ "Pr", # 镨
425
+ "Nd", # 钕
426
+ "Sm", # 钐
427
+ "Eu", # 铕
428
+ "Gd", # 钆
429
+ "Tb", # 铽
430
+ "Dy", # 镝
431
+ "Ho", # 钬
432
+ "Er", # 铒
433
+ "Tm", # 铥
434
+ "Yb", # 镱
435
+ "Lu", # 镥
436
+ "Hf", # 铪
437
+ "Ta", # 钽
438
+ "W", # 钨
439
+ "Re", # 铼
440
+ "Os", # 锇
441
+ "Ir", # 铱
442
+ "Pt", # 铂
443
+ "Au", # 金
444
+ "Hg", # 汞
445
+ "Tl", # 铊
446
+ "Pb", # 铅
447
+ "Bi" # 铋
448
+ }
449
+
450
+ TRANSITION_METALS: "The set of transition metals" = {
451
+ "Sc",
452
+ "Ti",
453
+ "V",
454
+ "Cr",
455
+ "Mn",
456
+ "Fe",
457
+ "Co",
458
+ "Ni",
459
+ "Cu",
460
+ "Zn",
461
+ "Y",
462
+ "Zr",
463
+ "Nb",
464
+ "Mo",
465
+ "Ru",
466
+ "Rh",
467
+ "Pd",
468
+ "Ag",
469
+ "Cd",
470
+ "Hf",
471
+ "Ta",
472
+ "W",
473
+ "Re",
474
+ "Os",
475
+ "Ir",
476
+ "Pt",
477
+ "Au",
478
+ "Hg",
479
+ }
480
+
481
+ TRANSITION_P_METALS: "The set of transition metals & p-zone metals" = {
482
+ "Sc",
483
+ "Ti",
484
+ "V",
485
+ "Cr",
486
+ "Mn",
487
+ "Fe",
488
+ "Co",
489
+ "Ni",
490
+ "Cu",
491
+ "Zn",
492
+ "Y",
493
+ "Zr",
494
+ "Nb",
495
+ "Mo",
496
+ "Ru",
497
+ "Rh",
498
+ "Pd",
499
+ "Ag",
500
+ "Cd",
501
+ "Hf",
502
+ "Ta",
503
+ "W",
504
+ "Re",
505
+ "Os",
506
+ "Ir",
507
+ "Pt",
508
+ "Au",
509
+ "Hg",
510
+ "Al",
511
+ "Ga",
512
+ "In",
513
+ "Sn",
514
+ "Tl",
515
+ "Pb",
516
+ "Bi"
517
+ }
518
+
519
+ NOBLE_METALS: "The set of noble metals" = {
520
+ "Rh",
521
+ "Ru",
522
+ "Os",
523
+ "Pt",
524
+ "Ir",
525
+ "Pd",
526
+ "Au"
527
+ }
@@ -0,0 +1,22 @@
1
+ # Copyright (c) 2024-2025.7.4, BUCToolkit.
2
+ # Authors: Pu Pengxin, Song Xin
3
+ # Version: 0.9a
4
+ # File: __init__.py
5
+ # Environment: Python 3.12
6
+
7
+ from .IrregularTensorReformat import IrregularTensorReformat
8
+ from .AtomicNumber2Properties import atomic_numbers_to_masses, atomic_numbers_to_elements, elements_to_atomic_numbers
9
+ from .check_structures import check_if_abnormal, check_if_converge, batched_check_files
10
+ from .ElemListReduce import elem_list_reduce
11
+ from ._CheckModules import check_module
12
+
13
+ __all__ = [
14
+ 'IrregularTensorReformat',
15
+ 'atomic_numbers_to_elements',
16
+ 'atomic_numbers_to_masses',
17
+ 'elements_to_atomic_numbers',
18
+ 'check_if_converge',
19
+ 'check_if_abnormal',
20
+ 'batched_check_files',
21
+ 'elem_list_reduce'
22
+ ]
@@ -0,0 +1,131 @@
1
+ """ Flatten Python list into 1D in parallel """
2
+
3
+ # Copyright (c) 2024-2025.7.4, BUCToolkit.
4
+ # Authors: Pu Pengxin, Song Xin
5
+ # Version: 0.9a
6
+ # File: _para_flatt_list.py
7
+ # Environment: Python 3.12
8
+
9
+ import multiprocessing as mp
10
+ import warnings
11
+ from typing import List, Iterable, Tuple
12
+ from itertools import chain
13
+ import sys
14
+ import time
15
+
16
+ import numpy as np
17
+ import torch as th
18
+
19
+ def _flatten_until_1d_(x: List):
20
+ """
21
+ Recursively flatten x until (deprecated)
22
+
23
+ Args:
24
+ x: input list
25
+
26
+ Returns: flatten list
27
+
28
+ """
29
+ y = list()
30
+ for sub_x in x:
31
+ if isinstance(sub_x, (List, Tuple, np.ndarray)):
32
+ y.extend(_flatten_until_1d(sub_x))
33
+ else:
34
+ y.append(sub_x)
35
+ return y
36
+
37
+ def _flatten_until_1d(x: List) -> List:
38
+ """
39
+ Flatten x recursively until 1D using iterative approach. (iteration version)
40
+
41
+ Args:
42
+ x: input list
43
+
44
+ Returns: flattened list
45
+
46
+ """
47
+ result = []
48
+ stack = [x]
49
+ while stack:
50
+ current = stack.pop()
51
+ if isinstance(current, (list, tuple, np.ndarray)):
52
+ stack.extend(reversed(current))
53
+ else:
54
+ # check other type s
55
+ if isinstance(current, Iterable) and not isinstance(current, (str, bytes)):
56
+ stack.extend(reversed(list(current)))
57
+ else:
58
+ result.append(current)
59
+ return result
60
+
61
+
62
+ def _flatten_1time(x:List):
63
+ """
64
+ Flatten one layer of x
65
+
66
+ Args:
67
+ x:
68
+
69
+ Returns: List
70
+ """
71
+ y = list()
72
+ for sub_x in x:
73
+ if isinstance(sub_x, (List, Tuple, np.ndarray)):
74
+ y.extend(sub_x)
75
+ else:
76
+ y.append(sub_x)
77
+ return y
78
+
79
+ def flatten(x, flat_num: int=-1, ncore: int=1):
80
+ """
81
+ flatten x in parallel
82
+
83
+ Args:
84
+ x: input list.
85
+ flat_num: number of flattens. -1 for flatten x until 1d-list.
86
+ ncore: number of parallel cores.
87
+
88
+ Returns:
89
+
90
+ """
91
+ #mp.set_start_method('spawn', force=True)
92
+ tot_core = mp.cpu_count()
93
+ if ncore == -1:
94
+ ncore = tot_core
95
+ elif (ncore > tot_core) or (ncore <= 0) or (not isinstance(ncore, int)):
96
+ raise ValueError('`ncore` must be an integer between 0 and total cpu cores.')
97
+ if sys.platform == 'win32' and ncore != 1:
98
+ warnings.warn('Windows OS does not support multi-process yet. `ncore` was automatically set to 1.', RuntimeWarning)
99
+ ncore = 1
100
+
101
+ n_chunk = len(x)//(ncore - 1) if ncore > 1 else len(x)
102
+ if n_chunk == 0:
103
+ n_chunk = len(x)
104
+ ncore = 1
105
+ # Process Pools
106
+ pools = mp.Pool(ncore)
107
+ # run
108
+ if flat_num == -1: # flatten until 1D
109
+ z = list()
110
+ result = [pools.apply_async(_flatten_until_1d, args=(x[i * n_chunk: (i + 1) * n_chunk],)) for i in range(ncore)]
111
+ [z.extend(_.get()) for _ in result]
112
+
113
+ elif isinstance(flat_num, int) and (flat_num > 0): # flatten specified times
114
+ z = x
115
+ for i in range(flat_num):
116
+ n_chunk = len(z) // (ncore - 1) if ncore > 1 else len(z)
117
+ if n_chunk == 0: n_chunk = len(z)
118
+ result = [pools.apply_async(_flatten_1time, args=(z[i * n_chunk: (i + 1) * n_chunk],)) for i in range(ncore)]
119
+ z = list()
120
+ [z.extend(_.get()) for _ in result]
121
+ else:
122
+ raise ValueError('`flat_num` must be an integer greater than 0, or == -1')
123
+
124
+ pools.close()
125
+ pools.join()
126
+
127
+ return z
128
+
129
+ if __name__ == '__main__':
130
+ a = [[[22]]*3, [[[124., 24.]]*2, ['44', 'fas', [222.]]], 45., 'gqw']
131
+ print(flatten(a, 2))