koichi12 commited on
Commit
b4a4a78
·
verified ·
1 Parent(s): f1e8896

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. .venv/lib/python3.11/site-packages/dotenv/__pycache__/__init__.cpython-311.pyc +0 -0
  3. .venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/INSTALLER +1 -0
  4. .venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/LICENSE +201 -0
  5. .venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/METADATA +150 -0
  6. .venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/RECORD +574 -0
  7. .venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/WHEEL +6 -0
  8. .venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/top_level.txt +3 -0
  9. .venv/lib/python3.11/site-packages/networkx/__init__.py +53 -0
  10. .venv/lib/python3.11/site-packages/networkx/convert.py +502 -0
  11. .venv/lib/python3.11/site-packages/networkx/exception.py +131 -0
  12. .venv/lib/python3.11/site-packages/networkx/linalg/__init__.py +13 -0
  13. .venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/__init__.cpython-311.pyc +0 -0
  14. .venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/algebraicconnectivity.cpython-311.pyc +0 -0
  15. .venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/attrmatrix.cpython-311.pyc +0 -0
  16. .venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/bethehessianmatrix.cpython-311.pyc +0 -0
  17. .venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/graphmatrix.cpython-311.pyc +0 -0
  18. .venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/laplacianmatrix.cpython-311.pyc +0 -0
  19. .venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/modularitymatrix.cpython-311.pyc +0 -0
  20. .venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/spectrum.cpython-311.pyc +0 -0
  21. .venv/lib/python3.11/site-packages/networkx/linalg/algebraicconnectivity.py +657 -0
  22. .venv/lib/python3.11/site-packages/networkx/linalg/attrmatrix.py +465 -0
  23. .venv/lib/python3.11/site-packages/networkx/linalg/bethehessianmatrix.py +79 -0
  24. .venv/lib/python3.11/site-packages/networkx/linalg/graphmatrix.py +168 -0
  25. .venv/lib/python3.11/site-packages/networkx/linalg/laplacianmatrix.py +617 -0
  26. .venv/lib/python3.11/site-packages/networkx/linalg/modularitymatrix.py +166 -0
  27. .venv/lib/python3.11/site-packages/networkx/linalg/spectrum.py +186 -0
  28. .venv/lib/python3.11/site-packages/networkx/linalg/tests/__init__.py +0 -0
  29. .venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/__init__.cpython-311.pyc +0 -0
  30. .venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_algebraic_connectivity.cpython-311.pyc +0 -0
  31. .venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_attrmatrix.cpython-311.pyc +0 -0
  32. .venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_bethehessian.cpython-311.pyc +0 -0
  33. .venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_graphmatrix.cpython-311.pyc +0 -0
  34. .venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_laplacian.cpython-311.pyc +0 -0
  35. .venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_modularity.cpython-311.pyc +0 -0
  36. .venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_spectrum.cpython-311.pyc +0 -0
  37. .venv/lib/python3.11/site-packages/networkx/linalg/tests/test_algebraic_connectivity.py +402 -0
  38. .venv/lib/python3.11/site-packages/networkx/linalg/tests/test_attrmatrix.py +108 -0
  39. .venv/lib/python3.11/site-packages/networkx/linalg/tests/test_bethehessian.py +41 -0
  40. .venv/lib/python3.11/site-packages/networkx/linalg/tests/test_graphmatrix.py +276 -0
  41. .venv/lib/python3.11/site-packages/networkx/linalg/tests/test_laplacian.py +336 -0
  42. .venv/lib/python3.11/site-packages/networkx/linalg/tests/test_modularity.py +87 -0
  43. .venv/lib/python3.11/site-packages/networkx/linalg/tests/test_spectrum.py +71 -0
  44. .venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/adjlist.cpython-311.pyc +0 -0
  45. .venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/edgelist.cpython-311.pyc +0 -0
  46. .venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/graphml.cpython-311.pyc +0 -0
  47. .venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/leda.cpython-311.pyc +0 -0
  48. .venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/p2g.cpython-311.pyc +0 -0
  49. .venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/pajek.cpython-311.pyc +0 -0
  50. .venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/sparse6.cpython-311.pyc +0 -0
.gitattributes CHANGED
@@ -296,3 +296,5 @@ tuning-competition-baseline/.venv/lib/python3.11/site-packages/nvidia/cudnn/lib/
296
  .venv/lib/python3.11/site-packages/_cffi_backend.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
297
  .venv/lib/python3.11/site-packages/jsonschema/tests/__pycache__/test_validators.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
298
  .venv/lib/python3.11/site-packages/torchaudio/functional/__pycache__/functional.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
 
 
 
296
  .venv/lib/python3.11/site-packages/_cffi_backend.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
297
  .venv/lib/python3.11/site-packages/jsonschema/tests/__pycache__/test_validators.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
298
  .venv/lib/python3.11/site-packages/torchaudio/functional/__pycache__/functional.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
299
+ .venv/lib/python3.11/site-packages/torchaudio/lib/_torchaudio.so filter=lfs diff=lfs merge=lfs -text
300
+ .venv/lib/python3.11/site-packages/torchaudio/lib/libtorchaudio.so filter=lfs diff=lfs merge=lfs -text
.venv/lib/python3.11/site-packages/dotenv/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (2.02 kB). View file
 
.venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
.venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/LICENSE ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
.venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/METADATA ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: google-api-python-client
3
+ Version: 2.159.0
4
+ Summary: Google API Client Library for Python
5
+ Home-page: https://github.com/googleapis/google-api-python-client/
6
+ Author: Google LLC
7
+ Author-email: googleapis-packages@google.com
8
+ License: Apache 2.0
9
+ Keywords: google api client
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.7
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Development Status :: 5 - Production/Stable
18
+ Classifier: Intended Audience :: Developers
19
+ Classifier: License :: OSI Approved :: Apache Software License
20
+ Classifier: Operating System :: OS Independent
21
+ Classifier: Topic :: Internet :: WWW/HTTP
22
+ Requires-Python: >=3.7
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: httplib2<1.dev0,>=0.19.0
26
+ Requires-Dist: google-auth!=2.24.0,!=2.25.0,<3.0.0.dev0,>=1.32.0
27
+ Requires-Dist: google-auth-httplib2<1.0.0,>=0.2.0
28
+ Requires-Dist: google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0.dev0,>=1.31.5
29
+ Requires-Dist: uritemplate<5,>=3.0.1
30
+
31
+ # Google API Client
32
+
33
+ [![PyPI version](https://badge.fury.io/py/google-api-python-client.svg)](https://badge.fury.io/py/google-api-python-client)
34
+
35
+ This is the [Google API Python client library](https://cloud.google.com/apis/docs/client-libraries-explained#google_api_client_libraries)
36
+ for Google's discovery based APIs. To get started, please see the
37
+ [docs folder](https://github.com/googleapis/google-api-python-client/blob/main/docs/README.md).
38
+
39
+ This library is considered complete and is in maintenance mode. This means
40
+ that we will address critical bugs and security issues but will not add any
41
+ new features.
42
+
43
+ This library is officially supported by Google. However, the maintainers of
44
+ this repository recommend using [Cloud Client Libraries for Python](https://github.com/googleapis/google-cloud-python),
45
+ where possible, for new code development. For more information, please visit
46
+ [Client Libraries Explained](https://cloud.google.com/apis/docs/client-libraries-explained).
47
+
48
+ ## Version 2.0 Release
49
+ The 2.0 release of `google-api-python-client` includes a substantial reliability
50
+ improvement, compared with 1.x, as discovery documents are now cached in the library
51
+ rather than fetched dynamically. It is highly recommended to upgrade from v1.x to v2.x.
52
+
53
+ Only python 3.7 and newer is supported. If you are not able to upgrade python, then
54
+ please continue to use version 1.x as we will continue supporting python 2.7+ in
55
+ [v1](https://github.com/googleapis/google-api-python-client/tree/v1).
56
+
57
+ Discovery documents will no longer be retrieved dynamically when
58
+ you call `discovery.build()`. The discovery documents will instead be retrieved
59
+ from the client library directly. New versions of this library are released weekly.
60
+ As a result of caching the discovery documents, the size of this package is at least
61
+ 50 MB larger compared to the previous version.
62
+
63
+ Please see the [Migration Guide](https://github.com/googleapis/google-api-python-client/blob/main/UPGRADING.md)
64
+ for more information.
65
+
66
+ ## Documentation
67
+
68
+ See the [docs folder](https://github.com/googleapis/google-api-python-client/blob/main/docs/README.md) for more detailed instructions and additional documentation.
69
+
70
+ ## Other Google API libraries
71
+
72
+ The maintainers of this repository recommend using
73
+ [Cloud Client Libraries for Python](https://github.com/googleapis/google-cloud-python),
74
+ where possible, for new code development due to the following reasons:
75
+
76
+ With [Cloud Client Libraries for Python](https://github.com/googleapis/google-cloud-python):
77
+ - There is a separate client library for each API, so you can choose
78
+ which client libraries to download. Whereas, `google-api-python-client` is a
79
+ single client library for all APIs. As a result, the total package size for
80
+ `google-api-python-client` exceeds 50MB.
81
+ - There are stricter controls for breaking changes to the underlying APIs
82
+ as each client library is focused on a specific API.
83
+ - There are more features in these Cloud Client Libraries as each library is
84
+ focused on a specific API, and in some cases, the libraries are owned by team
85
+ who specialized in that API.
86
+ - Developers will benefit from intellisense.
87
+
88
+ For more information, please visit
89
+ [Client Libraries Explained](https://cloud.google.com/apis/docs/client-libraries-explained).
90
+
91
+ Although there are many benefits to moving to
92
+ [Cloud Client Libraries for Python](https://github.com/googleapis/google-cloud-python),
93
+ the maintainers want to emphasize that `google-api-python-client` will continue
94
+ to be supported.
95
+
96
+ For Google Ads API, we recommend using [Google Ads API Client Library for Python](https://github.com/googleads/google-ads-python/).
97
+
98
+ For Google Firebase Admin API, we recommend using [Firebase Admin Python SDK](https://github.com/firebase/firebase-admin-python).
99
+
100
+ ## Installation
101
+
102
+ Install this library in a [virtualenv](https://virtualenv.pypa.io/en/latest/) using pip. virtualenv is a tool to
103
+ create isolated Python environments. The basic problem it addresses is one of
104
+ dependencies and versions, and indirectly permissions.
105
+
106
+ With virtualenv, it's possible to install this library without needing system
107
+ install permissions, and without clashing with the installed system
108
+ dependencies.
109
+
110
+ ### Mac/Linux
111
+
112
+ ```bash
113
+ pip3 install virtualenv
114
+ virtualenv <your-env>
115
+ source <your-env>/bin/activate
116
+ <your-env>/bin/pip install google-api-python-client
117
+ ```
118
+
119
+ ### Windows
120
+
121
+ ```batch
122
+ pip install virtualenv
123
+ virtualenv <your-env>
124
+ <your-env>\Scripts\activate
125
+ <your-env>\Scripts\pip.exe install google-api-python-client
126
+ ```
127
+
128
+ ## Supported Python Versions
129
+
130
+ Python 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 are fully supported and tested. This library may work on later versions of 3, but we do not currently run tests against those versions.
131
+
132
+ ## Unsupported Python Versions
133
+
134
+ Python < 3.7
135
+
136
+ ## Third Party Libraries and Dependencies
137
+
138
+ The following libraries will be installed when you install the client library:
139
+ * [httplib2](https://github.com/httplib2/httplib2)
140
+ * [uritemplate](https://github.com/sigmavirus24/uritemplate)
141
+
142
+ For development you will also need the following libraries:
143
+ * [WebTest](https://pypi.org/project/WebTest/)
144
+ * [pyopenssl](https://pypi.python.org/pypi/pyOpenSSL)
145
+
146
+ ## Contributing
147
+
148
+ Please see our [Contribution Guide](https://github.com/googleapis/google-api-python-client/blob/main/CONTRIBUTING.rst).
149
+ In particular, we love pull requests - but please make sure to sign
150
+ the contributor license agreement.
.venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/RECORD ADDED
@@ -0,0 +1,574 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ apiclient/__init__.py,sha256=U1SOZ1GeeF3uCr0fzO5Od-rpe17R12-Ppyq25NTSbow,746
2
+ apiclient/__pycache__/__init__.cpython-311.pyc,,
3
+ google_api_python_client-2.159.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
4
+ google_api_python_client-2.159.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
5
+ google_api_python_client-2.159.0.dist-info/METADATA,sha256=1bOByFTIV3avnDyYSM-tf-bJmzgQQH_1hYX3k0evMhE,6652
6
+ google_api_python_client-2.159.0.dist-info/RECORD,,
7
+ google_api_python_client-2.159.0.dist-info/WHEEL,sha256=OpXWERl2xLPRHTvd2ZXo_iluPEQd8uSbYkJ53NAER_Y,109
8
+ google_api_python_client-2.159.0.dist-info/top_level.txt,sha256=lbWgdDwQ3oww0ub0pmZ3fmIYAOTHf18Two4U9CxRlnw,58
9
+ googleapiclient/__init__.py,sha256=kFWxKShJalbnrCuV0klL7mjZaiXfPpjlqmyKyI8yfTU,904
10
+ googleapiclient/__pycache__/__init__.cpython-311.pyc,,
11
+ googleapiclient/__pycache__/_auth.cpython-311.pyc,,
12
+ googleapiclient/__pycache__/_helpers.cpython-311.pyc,,
13
+ googleapiclient/__pycache__/channel.cpython-311.pyc,,
14
+ googleapiclient/__pycache__/discovery.cpython-311.pyc,,
15
+ googleapiclient/__pycache__/errors.cpython-311.pyc,,
16
+ googleapiclient/__pycache__/http.cpython-311.pyc,,
17
+ googleapiclient/__pycache__/mimeparse.cpython-311.pyc,,
18
+ googleapiclient/__pycache__/model.cpython-311.pyc,,
19
+ googleapiclient/__pycache__/sample_tools.cpython-311.pyc,,
20
+ googleapiclient/__pycache__/schema.cpython-311.pyc,,
21
+ googleapiclient/__pycache__/version.cpython-311.pyc,,
22
+ googleapiclient/_auth.py,sha256=QttUwhmp7BmhW5CReaAOVGH6kEtITYmEHhVCVmsnDPs,5736
23
+ googleapiclient/_helpers.py,sha256=iNxILG6iNNFukr7lhaYfVqX4oFM5SERvcsU3JxeOo6I,6723
24
+ googleapiclient/channel.py,sha256=Fc4nxu-RxGkjY_STp9bwJfZaLan6VdX-DNniH-ANSuE,11054
25
+ googleapiclient/discovery.py,sha256=9TKz9stsr8Q9TPTjKG1I6yHoPH1ISRvh58q_NoX3mOM,66341
26
+ googleapiclient/discovery_cache/__init__.py,sha256=ww_vl0vhVLuHSEdRTv3-gq6EDG--Ff7rILYHHFifnzc,2315
27
+ googleapiclient/discovery_cache/__pycache__/__init__.cpython-311.pyc,,
28
+ googleapiclient/discovery_cache/__pycache__/appengine_memcache.cpython-311.pyc,,
29
+ googleapiclient/discovery_cache/__pycache__/base.cpython-311.pyc,,
30
+ googleapiclient/discovery_cache/__pycache__/file_cache.cpython-311.pyc,,
31
+ googleapiclient/discovery_cache/appengine_memcache.py,sha256=6T1pQj-toAhDwfgLuiggFGhxKNGw5y-NnLUzLIF_M4s,1657
32
+ googleapiclient/discovery_cache/base.py,sha256=yCDPtxnbNN-p5_9fzBacC6P3wcUPlaCQIy5v_dXTons,1389
33
+ googleapiclient/discovery_cache/documents/abusiveexperiencereport.v1.json,sha256=S71sOgX6Jaa_CVbAYzdQANp6oxb8poocJieP6Q0KW0E,5671
34
+ googleapiclient/discovery_cache/documents/acceleratedmobilepageurl.v1.json,sha256=pyMbFLPRkHJ-j_vpoXoTgLeJmB_Ff8aGoY94qtSIjC4,6729
35
+ googleapiclient/discovery_cache/documents/accessapproval.v1.json,sha256=zk7qnoDt9iLceoLvoqKvyCfYMmMs4g_wO21SwHQktTY,49990
36
+ googleapiclient/discovery_cache/documents/accesscontextmanager.v1.json,sha256=DWXJ0iCxI9UhxsxfOG0OFXic7cstDmHKAXGAV-5Fuoc,116991
37
+ googleapiclient/discovery_cache/documents/accesscontextmanager.v1beta.json,sha256=Vsv_nz7ubkkbGwNgxirN2AWgUuYH0mADUx9LFaqKu_c,51062
38
+ googleapiclient/discovery_cache/documents/acmedns.v1.json,sha256=l4yO_s08Dowy9AdSBd857ZVqw6Ea4PWt1KE1OqOb9mE,6858
39
+ googleapiclient/discovery_cache/documents/addressvalidation.v1.json,sha256=QBLcYw1_WBJJs7tYZyZc_rlfzCz4w_dqZilvazf11HQ,47286
40
+ googleapiclient/discovery_cache/documents/adexchangebuyer.v1.2.json,sha256=0-XVzUa3kcqFiCZYk_W0au5mIV5-w3AgBtQJsSnWL9w,20475
41
+ googleapiclient/discovery_cache/documents/adexchangebuyer.v1.3.json,sha256=6lFs8ULCDsQuo8s48oBpFdDCVbwICk6MNaCvDVrhP9Q,59967
42
+ googleapiclient/discovery_cache/documents/adexchangebuyer.v1.4.json,sha256=pgYvRj3gK2vBxH7Dh4YoCqd7TXTzTDPQqVqOlVRxITk,136987
43
+ googleapiclient/discovery_cache/documents/adexchangebuyer2.v2beta1.json,sha256=DsPe2AUTiMhcL_RQl_DIP6jVj_C_6BwM9knbgdt6auY,231740
44
+ googleapiclient/discovery_cache/documents/adexperiencereport.v1.json,sha256=ZcB2Sna6t35lyCS6gJZ-FBePqKfGK9y1m2K8zVNDkN0,6644
45
+ googleapiclient/discovery_cache/documents/admin.datatransfer_v1.json,sha256=cvllELDkZ78kNbbgK7uz1DLCuPwJwg-2sB5jhPEYgB4,12021
46
+ googleapiclient/discovery_cache/documents/admin.datatransferv1.json,sha256=cvllELDkZ78kNbbgK7uz1DLCuPwJwg-2sB5jhPEYgB4,12021
47
+ googleapiclient/discovery_cache/documents/admin.directory_v1.json,sha256=S0rjTVAqMdFfXiZzPtDdLx64RzT2QA0kpPHIhkB4Vzg,274561
48
+ googleapiclient/discovery_cache/documents/admin.directoryv1.json,sha256=S0rjTVAqMdFfXiZzPtDdLx64RzT2QA0kpPHIhkB4Vzg,274561
49
+ googleapiclient/discovery_cache/documents/admin.reports_v1.json,sha256=D2jiASxzuDM7MVJOWXkwvAOrAUtGfHxBI0_BB24f1ls,52363
50
+ googleapiclient/discovery_cache/documents/admin.reportsv1.json,sha256=D2jiASxzuDM7MVJOWXkwvAOrAUtGfHxBI0_BB24f1ls,52363
51
+ googleapiclient/discovery_cache/documents/admob.v1.json,sha256=KqHlEbdrL6m9INFAwhX9wFuqvR5Kjk_rdfu6mtc4XY4,52164
52
+ googleapiclient/discovery_cache/documents/admob.v1beta.json,sha256=gcGNiedgQiUsitwzTPPv-yTsWzcR7iCV3_A9VO5G2f8,91957
53
+ googleapiclient/discovery_cache/documents/adsense.v2.json,sha256=4JKnIONHrO-Ihxq8y7YayZIXhazygAs8Y7KB1iRc7RQ,103441
54
+ googleapiclient/discovery_cache/documents/adsensehost.v4.1.json,sha256=kKGnNG3aFbYwLFOLJkIGph3m7vC2heaob68rlmV4J28,37965
55
+ googleapiclient/discovery_cache/documents/adsenseplatform.v1.json,sha256=sxqJvzMQS0OW7i_spxKrvmpI2BTZ-fPguABRUzEeKWs,20170
56
+ googleapiclient/discovery_cache/documents/adsenseplatform.v1alpha.json,sha256=m0CwvUttBXWPHiOhje588U-g1KPe2XBgs9_xrSSe85I,23225
57
+ googleapiclient/discovery_cache/documents/advisorynotifications.v1.json,sha256=LjKYP_4Fy_is5k-nccRqXa9usXF5_rBxhE_qdN9FkqE,20673
58
+ googleapiclient/discovery_cache/documents/aiplatform.v1.json,sha256=kJ8yKsY0yymywj6zqjs6vzMgEZ9zXCmNPQe7_tBzXpU,1741177
59
+ googleapiclient/discovery_cache/documents/aiplatform.v1beta1.json,sha256=KmKuUR-xAXK7rCxpM5MbKYof6KrzYWotTcbPDE4dBhE,1986081
60
+ googleapiclient/discovery_cache/documents/airquality.v1.json,sha256=Jid1ijxffWKiYwOdpwu_toVra3fOeowW8QuMkz2wpao,40963
61
+ googleapiclient/discovery_cache/documents/alertcenter.v1beta1.json,sha256=N6jVO1PseL3z9zGnMDcdALRExUU1iKKorZFkXOarqoM,67802
62
+ googleapiclient/discovery_cache/documents/alloydb.v1.json,sha256=bAWuLVZQPdT3xOwso1EymTC5RW-hGlCBR0KjNXHD0nU,190970
63
+ googleapiclient/discovery_cache/documents/alloydb.v1alpha.json,sha256=tB-PZws1VIuznlqzE989Tp3_fGJlX-hHLnwtbsqc3oI,199022
64
+ googleapiclient/discovery_cache/documents/alloydb.v1beta.json,sha256=m5izNNXXbzCTuyXf0QwIgBPBShRRTbrxVdGUAJYxmeI,197279
65
+ googleapiclient/discovery_cache/documents/analytics.v3.json,sha256=pq5nLmdNvFR-k8Sre800U3mI2tU6hVZGdQCNX_VJNiE,195428
66
+ googleapiclient/discovery_cache/documents/analyticsadmin.v1alpha.json,sha256=LkYkxevtmPTe0RtWAT6T-eQvt46onnhYj0l4U4syrII,321489
67
+ googleapiclient/discovery_cache/documents/analyticsadmin.v1beta.json,sha256=axYy3nO8tOpaxIK1KGkTJ9ZpIgIsdFDEvFu4M2QipOk,123177
68
+ googleapiclient/discovery_cache/documents/analyticsdata.v1alpha.json,sha256=3rdVFqqDjQQ7-0qi_UkAYpRthvRKjoXJ8SJzulNHBn0,80445
69
+ googleapiclient/discovery_cache/documents/analyticsdata.v1beta.json,sha256=-ptvrqUp-0rNGlell3IyH12yzL7LQbz9nBKOukMThkE,97076
70
+ googleapiclient/discovery_cache/documents/analyticshub.v1.json,sha256=Kgg_XZ5mN7oj8MVyflAOa_lwkcUQKLwMM0Ix7uSIU2g,102096
71
+ googleapiclient/discovery_cache/documents/analyticshub.v1beta1.json,sha256=GHYQ2yb544a4cAceel10LI-mbs53yErbGWvykJpPiJw,56324
72
+ googleapiclient/discovery_cache/documents/analyticsreporting.v4.json,sha256=8S4FyrAstnlesJ3ss4fYM7V18YvJgMh9S9jIo-vAOY8,61333
73
+ googleapiclient/discovery_cache/documents/androiddeviceprovisioning.v1.json,sha256=HAGzsWbVR9lfecRlHW6S55tgQy1o1UWZ4YjX_ruMkIA,60978
74
+ googleapiclient/discovery_cache/documents/androidenterprise.v1.json,sha256=FCjc18uzyxU2-bQt2Lys-pNf3pKCnoy1Cz9D6RZqomE,155538
75
+ googleapiclient/discovery_cache/documents/androidmanagement.v1.json,sha256=cfHKkkHnm9cET7qqPMfQFwJowrliS0DXHGZelFnnEag,268145
76
+ googleapiclient/discovery_cache/documents/androidpublisher.v3.json,sha256=90iIRPt5cNZz88CoPh9cdSwy1sXuD_gCuG0fAFnulVY,313821
77
+ googleapiclient/discovery_cache/documents/apigateway.v1.json,sha256=xEY_-eczVl_UTFcrEO0GHrGNEDIIdls-MxvVbcZYC1w,67399
78
+ googleapiclient/discovery_cache/documents/apigateway.v1beta.json,sha256=xXuSF3RPRJ8q-_XaBNx4M2O-9IYlanSW5NVi5gtkoNs,69112
79
+ googleapiclient/discovery_cache/documents/apigee.v1.json,sha256=8NT7GiKG2y5cZ-MehLN7UK9cUFl6baZKjm_ZyGG7kiE,664811
80
+ googleapiclient/discovery_cache/documents/apigeeregistry.v1.json,sha256=hCu1irwJNFHGEQgiTM5HJtqvF1JUeqpBVA8SGUn9syQ,156027
81
+ googleapiclient/discovery_cache/documents/apikeys.v2.json,sha256=FZBL7LZgNkiOp8cChbkg38Xd0oRqDyn9MQRFouSiqRg,22352
82
+ googleapiclient/discovery_cache/documents/apim.v1alpha.json,sha256=kktY7aRouoMlByWAQ1dvEa89Uf_hu26exnk8D8mu5Fs,48179
83
+ googleapiclient/discovery_cache/documents/appengine.v1.json,sha256=LyGXgvqMb0rp_KAPOFh-55tcH2-3JRIFutz28SvMsGY,152632
84
+ googleapiclient/discovery_cache/documents/appengine.v1alpha.json,sha256=sNxfJZHgLFEZjEkogY8eA963iq6A3YGy3zfO8XWb-mQ,61632
85
+ googleapiclient/discovery_cache/documents/appengine.v1beta.json,sha256=SlY5xrxPEPiVhCBFpl1B57XmT9f8fuTOZ-AMIbbsZ-0,159979
86
+ googleapiclient/discovery_cache/documents/appengine.v1beta4.json,sha256=yELseCdExWSunuF7afIqEw_94UU7PvKCXDmWkyAbYWg,110912
87
+ googleapiclient/discovery_cache/documents/appengine.v1beta5.json,sha256=OHCPs6izs9jPAEuG8s9dr76KCn3f5lKdfWE5NaQBhZo,110227
88
+ googleapiclient/discovery_cache/documents/apphub.v1.json,sha256=ygrOA6zBTqjN_v4DgTxBbrbHl7Q1DKYkI2L-91zHG7c,99910
89
+ googleapiclient/discovery_cache/documents/apphub.v1alpha.json,sha256=flxM20XL_iSm-40n239ICU_OhWEAjAqTakClsQl_R4g,104528
90
+ googleapiclient/discovery_cache/documents/area120tables.v1alpha1.json,sha256=W3nRxsh01aYTWrEV05o-14Ubu4UvIqDelbu01_s9Ve0,26671
91
+ googleapiclient/discovery_cache/documents/areainsights.v1.json,sha256=-lvkKcQIt9weSu_Ksg1nWjOTV8WCjBYxj-BQKwlwVe0,13722
92
+ googleapiclient/discovery_cache/documents/artifactregistry.v1.json,sha256=xRYlS4T4C22eM_1v56tXuMwNhUEh52X2bfJ1saQJxlk,155456
93
+ googleapiclient/discovery_cache/documents/artifactregistry.v1beta1.json,sha256=OGs1TZeDA3V64ZBxAuXI3C2wtHeZLxUHjeYpbHqU3Xw,63052
94
+ googleapiclient/discovery_cache/documents/artifactregistry.v1beta2.json,sha256=Ch-AAmvOPXtRKwBrXZMHGxJlsMG5e621jsYITZ4FuHU,81649
95
+ googleapiclient/discovery_cache/documents/assuredworkloads.v1.json,sha256=wiMc9LzAN6PVHMikIMftKOXU76QmD54tZzFMer2mqng,60769
96
+ googleapiclient/discovery_cache/documents/assuredworkloads.v1beta1.json,sha256=MCzr0E1VbcRWXz1GO0wBbe-xPBEEcef2mP5cckG6Rrw,72924
97
+ googleapiclient/discovery_cache/documents/authorizedbuyersmarketplace.v1.json,sha256=C6-kWPE5tO5iklauUh8pa-ooSli3rVy5CKn3fKVqSmc,110586
98
+ googleapiclient/discovery_cache/documents/authorizedbuyersmarketplace.v1alpha.json,sha256=pH-ReY_ZuE4pkzlvkAa4godHOaSvmT3aULiwpwpIXnE,118917
99
+ googleapiclient/discovery_cache/documents/backupdr.v1.json,sha256=JNIEeu9osXfSDCioNHhvSEwGYGSBT1zvQDz_4cgcaYU,176146
100
+ googleapiclient/discovery_cache/documents/baremetalsolution.v1.json,sha256=DgpA2txkVyJ3FJmckMnRzB1LGtD8K6qo8F2eYT6Bi3c,13574
101
+ googleapiclient/discovery_cache/documents/baremetalsolution.v1alpha1.json,sha256=LWBZqVLJQlt0qgc4yoRJWQfwH0oPL8aS4wHGF8LRfzk,19186
102
+ googleapiclient/discovery_cache/documents/baremetalsolution.v2.json,sha256=hiQNSG63T3om5Hldrdn0CoUpOciITjxNmDuf9lsl11c,105593
103
+ googleapiclient/discovery_cache/documents/batch.v1.json,sha256=nwHoC9fWFc5QxSNfIM4N3tcL4DQgvqmL1avY_A7ZB8s,86651
104
+ googleapiclient/discovery_cache/documents/beyondcorp.v1.json,sha256=X-dzEo0czEXDzbdFZ4xbb-peetG66xdS8fAh5O1R4pw,170832
105
+ googleapiclient/discovery_cache/documents/beyondcorp.v1alpha.json,sha256=k6DBKchf0XygfOkO_XV6d9mUPG9x3O9G5cExOTXk2ws,295421
106
+ googleapiclient/discovery_cache/documents/biglake.v1.json,sha256=JiAvdp7lTnDjHSpeG0RZ_mZFOtNCW5lXWrok81NGECs,26554
107
+ googleapiclient/discovery_cache/documents/bigquery.v2.json,sha256=9Y88rM3uZj_jE-kynEy64-H60BNbLiOxPUARn12YQDM,389333
108
+ googleapiclient/discovery_cache/documents/bigqueryconnection.v1.json,sha256=uogtso7Bp7eexOLF2Syb3hapjEHyOU1Wx62pnBGwefI,43660
109
+ googleapiclient/discovery_cache/documents/bigqueryconnection.v1beta1.json,sha256=d45MeNg37AdYm_s8hO7ZqLd8hDw3qbpif9ecV1OMYIA,32721
110
+ googleapiclient/discovery_cache/documents/bigquerydatapolicy.v1.json,sha256=2p0Fd_kv8GXO5lhd0GOcZAcQ1jPmSxwX44z-aL3cOqo,35006
111
+ googleapiclient/discovery_cache/documents/bigquerydatatransfer.v1.json,sha256=gEOx_g1zz5SQUQiZCa3WyR681yPGOr3hOvA4Ol23F5M,86085
112
+ googleapiclient/discovery_cache/documents/bigqueryreservation.v1.json,sha256=lC_d23FlEL7LcARDPbOqT8Tcosliy9Z5e5gt-3EhEpU,55989
113
+ googleapiclient/discovery_cache/documents/bigqueryreservation.v1alpha2.json,sha256=u1WvY6zx7CYg_q9OhtqB5I8Su4b1kEA7p3VwegecO8U,44509
114
+ googleapiclient/discovery_cache/documents/bigqueryreservation.v1beta1.json,sha256=zVtHmOXJTgtYX3JK9YoFUW8uNNHwi-ZPHs4gQN-Y0cY,60957
115
+ googleapiclient/discovery_cache/documents/bigtableadmin.v1.json,sha256=udwAbAWXjShMSJcvAaxRNI-V5QFFQdE6InVOhHT-y7Q,32684
116
+ googleapiclient/discovery_cache/documents/bigtableadmin.v2.json,sha256=JMG5IFda7w0jyij1wtKw_rJ39GCmsFPkdG7c5Z5EW2A,178675
117
+ googleapiclient/discovery_cache/documents/billingbudgets.v1.json,sha256=v3YOJsAFLFb0dBL3DDh40t5RYi_K8YZUszEi-IY0XQM,27319
118
+ googleapiclient/discovery_cache/documents/billingbudgets.v1beta1.json,sha256=W1XxaGkQBjVGfxUdSJFFi2WIfppU-rP-rkFpSuTKvqk,26850
119
+ googleapiclient/discovery_cache/documents/binaryauthorization.v1.json,sha256=DFrj4rdbosJRJW3Qcf1I97QDhN40xfXKkiLgEijQgw8,84334
120
+ googleapiclient/discovery_cache/documents/binaryauthorization.v1beta1.json,sha256=9zlVIEnahifUYLArioJ_ycDpVZpet2mkIrclt_WkKQ4,50127
121
+ googleapiclient/discovery_cache/documents/blockchainnodeengine.v1.json,sha256=YSkmD97vugow4WGYJevxXFVS48menuu5lCAfSg8YgGA,33199
122
+ googleapiclient/discovery_cache/documents/blogger.v2.json,sha256=JXobWTAsHd4PoODg63CedVZHQaedheBQnvxjizGRmhc,21584
123
+ googleapiclient/discovery_cache/documents/blogger.v3.json,sha256=y-3kCIaujgK4YBiQziOXurJPzXjtEzmGUKJwcBxL-e8,44123
124
+ googleapiclient/discovery_cache/documents/books.v1.json,sha256=dWEew3bc3mDWbAhR-f26d9JqXKqiPtpXQ7We2VBfQVs,110062
125
+ googleapiclient/discovery_cache/documents/businessprofileperformance.v1.json,sha256=2FQwtRgx3ObOq_qdL-a_M9evFaluSAUCpPAXZ15JpmM,24459
126
+ googleapiclient/discovery_cache/documents/calendar.v3.json,sha256=obiH3_E4LOmalnwJs0oduIxQEteyiOz4E0RO4BUVsgw,117327
127
+ googleapiclient/discovery_cache/documents/certificatemanager.v1.json,sha256=wVbFC_h-aH7qeCdlto-d5Sx8jvcEehWw2VeBmG2zkqM,72783
128
+ googleapiclient/discovery_cache/documents/chat.v1.json,sha256=ytk2Q1odJ1-IKiPlet3FcDZMBeV799uZlWNwBux_5eA,265618
129
+ googleapiclient/discovery_cache/documents/checks.v1alpha.json,sha256=_Ko7Qb9yYJxCarWZa3mlQg08Y5azaxIAj7smjiqmviA,91808
130
+ googleapiclient/discovery_cache/documents/chromemanagement.v1.json,sha256=nmTclryXsGfcWh-SyUAZgVOdkezBfvPpu4kUONEKBEM,195311
131
+ googleapiclient/discovery_cache/documents/chromepolicy.v1.json,sha256=av8BIAE-PVDBuAvnIqnLuIqIFM-8G57lsZHLO_-8o2g,62003
132
+ googleapiclient/discovery_cache/documents/chromeuxreport.v1.json,sha256=airhc_AoDt3AlPYikhaq16oCnZ3SqpKfHRIZG-v_7xM,22401
133
+ googleapiclient/discovery_cache/documents/civicinfo.v2.json,sha256=89wbEDm24KZJ7NjNtDOWjFvf9kcG4dRhjJdk4KfzkLU,38357
134
+ googleapiclient/discovery_cache/documents/classroom.v1.json,sha256=KOyTZm1i8vKNmHK_EEtrRc3z3nSlg-pwLiBQMhbLHao,235902
135
+ googleapiclient/discovery_cache/documents/cloudasset.v1.json,sha256=oLPhj-xH8GO6z0UBwnrdFfShakb9t3oqCTZiazXFPPI,259122
136
+ googleapiclient/discovery_cache/documents/cloudasset.v1beta1.json,sha256=yE6WJ_RV0qR3NWkGqUA-gVQo6DMVGzP2Ef4ZMPklYoc,95251
137
+ googleapiclient/discovery_cache/documents/cloudasset.v1p1beta1.json,sha256=H1MEC776OSu8QDjeePqukBGYmDwrgFwzTkzp7_C0EzE,83418
138
+ googleapiclient/discovery_cache/documents/cloudasset.v1p4beta1.json,sha256=RT5pGxMQhQ_T9JKt97G6G94znnnweuqgSwEnby7Vkck,110574
139
+ googleapiclient/discovery_cache/documents/cloudasset.v1p5beta1.json,sha256=i_hOgsgH5yPJhR9EOGBzibq1M6yjFCtA6wOBjAAePRQ,82076
140
+ googleapiclient/discovery_cache/documents/cloudasset.v1p7beta1.json,sha256=m4-VUaiGQuHi-k1ez-nl5qxoINpJJw1bjo625f6UgM4,87731
141
+ googleapiclient/discovery_cache/documents/cloudbilling.v1.json,sha256=jg1-B4LYm5Dp-V9jUomBsLVOd9H4uPlgCTjME9AHUrs,61261
142
+ googleapiclient/discovery_cache/documents/cloudbilling.v1beta.json,sha256=SqLdm243EPaHYt08Zw_rblcz4XeXzo3jdFxO-A_ehno,98576
143
+ googleapiclient/discovery_cache/documents/cloudbuild.v1.json,sha256=lMPZlZ6X_p4l6IpyPxl3f7SHNBfDzwvWUIhHafbfSwI,190972
144
+ googleapiclient/discovery_cache/documents/cloudbuild.v1alpha1.json,sha256=tN8lxatpJZdx4mhuKWjgzYeBfbN3ZFgZOhdDI8HdMTc,103536
145
+ googleapiclient/discovery_cache/documents/cloudbuild.v1alpha2.json,sha256=FqGePJRUozQZ3MgYXXDeeBwhKb38oRdL3RDyfn5LKOA,102139
146
+ googleapiclient/discovery_cache/documents/cloudbuild.v1beta1.json,sha256=Z9D0XmsAbFI1Ug2BBm8i4hocf4dzGW0MP_3rprbHH2I,105268
147
+ googleapiclient/discovery_cache/documents/cloudbuild.v2.json,sha256=hqZ4sDw_312sDjJMy6Mbdzi53ZYjjxsnwBsUzj4qF7k,112786
148
+ googleapiclient/discovery_cache/documents/cloudchannel.v1.json,sha256=Y1T5zjX6moAfaui_zz-_6JC0-Au_XMQPgzTarPI5og0,249069
149
+ googleapiclient/discovery_cache/documents/cloudcommerceprocurement.v1.json,sha256=NtXgLDh60lxmnNf3YKeRYfUr2suT9B1KvXUyXvfeXuU,40056
150
+ googleapiclient/discovery_cache/documents/cloudcontrolspartner.v1.json,sha256=rMIB1jLBv1Hx5BP1XHy1P6SjL5dzpxtgQ0C2JrWdkE8,39795
151
+ googleapiclient/discovery_cache/documents/cloudcontrolspartner.v1beta.json,sha256=WMIVTmWBALeWRidAdfvDf5UMnsjHgJ0m8LZxez5XPQc,39907
152
+ googleapiclient/discovery_cache/documents/clouddebugger.v2.json,sha256=2IO6Cc_uKUbDzdXhyc02Xr2Y7vd8TIRq_2iWDhwGYPE,53446
153
+ googleapiclient/discovery_cache/documents/clouddeploy.v1.json,sha256=oubO9PymCKhRmH5y2LXc1BkNxlbc4mdhvIdQuASC0YQ,259405
154
+ googleapiclient/discovery_cache/documents/clouderrorreporting.v1beta1.json,sha256=LT3OJ_dSdWCJnai8IcrGZ5Gxr4xti3uIknpzRPbNzN8,46460
155
+ googleapiclient/discovery_cache/documents/cloudfunctions.v1.json,sha256=d5eawdrdmmEGVnzB0XUF3yng-tScc-pjmfn9P7HBTtM,64661
156
+ googleapiclient/discovery_cache/documents/cloudfunctions.v2.json,sha256=0XJglYg0YCJouT_-XAZL1bnVMMMbd2WfB5zzc9ubc_E,84746
157
+ googleapiclient/discovery_cache/documents/cloudfunctions.v2alpha.json,sha256=ARHr_yHNhGiUwTWhT9zmKM114kwRJXR2NX7iqYTJgCQ,85001
158
+ googleapiclient/discovery_cache/documents/cloudfunctions.v2beta.json,sha256=kCt1IA3ok8OgJ_SYWwUiQPagFLI_Aoigs6H7wT5td68,84950
159
+ googleapiclient/discovery_cache/documents/cloudidentity.v1.json,sha256=lckIKcXdNU_qgxvo-6LzcZ01aMUAKL8caUg5n_A_xL8,165285
160
+ googleapiclient/discovery_cache/documents/cloudidentity.v1beta1.json,sha256=tobyu7zftb1GWmW406G8cJBG9G7fKLn9ROhsIUKDDpU,194298
161
+ googleapiclient/discovery_cache/documents/cloudiot.v1.json,sha256=BLM9X9po2P0rn8osda4MgRc990yAYWFVbRMnoCTjN6w,94703
162
+ googleapiclient/discovery_cache/documents/cloudkms.v1.json,sha256=3gff_VurjeaXhFWYesDFM8IxN1mijRfDzmOAlJzYrHw,195785
163
+ googleapiclient/discovery_cache/documents/cloudprofiler.v2.json,sha256=DKiyeC2Z010ehm-WHvDJBGMnfVFow8daU56CAP1hlkE,14920
164
+ googleapiclient/discovery_cache/documents/cloudresourcemanager.v1.json,sha256=UDqQSYcntrGDWFUNoxTXOvAlc9gKD_lbBYBn9E6DddM,101363
165
+ googleapiclient/discovery_cache/documents/cloudresourcemanager.v1beta1.json,sha256=Ba-DH5hvtcWloOdelBeMh6Qe-4zgQclErPHmr-hsmbc,58393
166
+ googleapiclient/discovery_cache/documents/cloudresourcemanager.v2.json,sha256=8uhiXUbxf1fr85vhmvqNfvtp2rJ6NiptXFy8QFP7JDM,52001
167
+ googleapiclient/discovery_cache/documents/cloudresourcemanager.v2beta1.json,sha256=1bx2QsBddoYuUmrFtlKbQ4sRpd7HGcRoKW4AoLMBu5A,52011
168
+ googleapiclient/discovery_cache/documents/cloudresourcemanager.v3.json,sha256=zLIWRsnG4wabxo5Jppvxq4INDHXU_OazrJ4R8wZmrq8,126177
169
+ googleapiclient/discovery_cache/documents/cloudscheduler.v1.json,sha256=5szSb7NUR7Jr0guFehnwUvUd749_1IEDU9VLQa9akXQ,46718
170
+ googleapiclient/discovery_cache/documents/cloudscheduler.v1beta1.json,sha256=PeKbbI52f2i5z0XVndZfjrDCdmDvPtEcl3c5_W50FWw,42928
171
+ googleapiclient/discovery_cache/documents/cloudsearch.v1.json,sha256=zioYxBar0l7onDdnYAfGKjcguMEdRkybFuuQlawHHDE,247310
172
+ googleapiclient/discovery_cache/documents/cloudshell.v1.json,sha256=pRDGK9lNQ9_ADOmlBcTUVzBX422WFWCijv2LK--rzUA,22895
173
+ googleapiclient/discovery_cache/documents/cloudshell.v1alpha1.json,sha256=XoIskUrEjFBy7Saxe7cApOT6ShmcKZlwzRDAiIoxgSI,25615
174
+ googleapiclient/discovery_cache/documents/cloudsupport.v2.json,sha256=uW5kjaBY4fC_ZTPrCSKmsiT7m9h5LLCpnz2qC2kJIBE,52938
175
+ googleapiclient/discovery_cache/documents/cloudsupport.v2beta.json,sha256=yV-RtmOBsz7Vkvob7wzXa8sdVxxKTk8zKlL39ivHr1w,58928
176
+ googleapiclient/discovery_cache/documents/cloudtasks.v2.json,sha256=sS7OMASEA2oAj4bBCCGXeOzqWEkT-ZhGDE3H5r24xjM,96162
177
+ googleapiclient/discovery_cache/documents/cloudtasks.v2beta2.json,sha256=OYFSBiChmrIXvCZKqqxV7TXmODreStoBzmhpV1FTmkw,113198
178
+ googleapiclient/discovery_cache/documents/cloudtasks.v2beta3.json,sha256=NAzGvDNnJTXjz4CIj3qYNp9eOmCoOzW3r-eNVvjQAoM,103153
179
+ googleapiclient/discovery_cache/documents/cloudtrace.v1.json,sha256=s-TVg4l2KG8Xa9LYhl4Xvar3Sl4b2Btck2esIAVx8Ag,13573
180
+ googleapiclient/discovery_cache/documents/cloudtrace.v2.json,sha256=FYR7MlSneNHE1yqrY3FPqSw3syBJDXNaNMhid1taIX4,21080
181
+ googleapiclient/discovery_cache/documents/cloudtrace.v2beta1.json,sha256=C-rFqBUcGEdGeys6I18EtbUb-LV2oI5FL8D7EGbrLNk,11533
182
+ googleapiclient/discovery_cache/documents/composer.v1.json,sha256=y-7qAcZQUKDGxfPriYDlBnT9OVnxWAGnib-dOFZofVc,104729
183
+ googleapiclient/discovery_cache/documents/composer.v1beta1.json,sha256=4ZE6Ejxo2uZPOAtDJl46riN7BV-eyIAvCKUTRLtXGis,108619
184
+ googleapiclient/discovery_cache/documents/compute.alpha.json,sha256=Hq1w424Bnw24cJf5yqt5m_aurrCDVjdoXHJS28IE2ug,4666791
185
+ googleapiclient/discovery_cache/documents/compute.beta.json,sha256=Tx0wSyimxY03Ftv5XRHKZjV8KgGh2QZtURGfCWDG09I,4179173
186
+ googleapiclient/discovery_cache/documents/compute.v1.json,sha256=AThob4LZ03WjBniAug-gG3zsQkeJoay1q_u-1S3jKZw,3833242
187
+ googleapiclient/discovery_cache/documents/config.v1.json,sha256=uqfK15vv9vJ7nzYoxqTyBbG5bO0550iKpIJvBVoDxEk,101104
188
+ googleapiclient/discovery_cache/documents/connectors.v1.json,sha256=Qy6dCmMc6rB1624-G3FT4vGolNS_SUiGyO6YFSIgHjc,234527
189
+ googleapiclient/discovery_cache/documents/connectors.v2.json,sha256=3oFlR5Bk3brELU4t2y52i-fPRfwrY0Lj62EUBsSVMx4,70153
190
+ googleapiclient/discovery_cache/documents/contactcenteraiplatform.v1alpha1.json,sha256=YqDsesIVwnOMZfFQdoSWdImUhvlTBFU-Yj8MTA1BvwQ,43944
191
+ googleapiclient/discovery_cache/documents/contactcenterinsights.v1.json,sha256=OQsjog_QlFQPlfhX6WzlR07ymJeGkCLOtaMczUAI53k,327495
192
+ googleapiclient/discovery_cache/documents/container.v1.json,sha256=orAp0iOzD48JVay6P-b1OEAlmI9_enckWvgDDdlravI,310390
193
+ googleapiclient/discovery_cache/documents/container.v1beta1.json,sha256=X_-hdaANczxdK1S1-Q385WBDcRIZo4Hq5hr0TlScJ5c,346072
194
+ googleapiclient/discovery_cache/documents/containeranalysis.v1.json,sha256=UfbzOfSdF5AwiBfmEW-d-JVU7bpD28jjMsk4hgXpXaE,223841
195
+ googleapiclient/discovery_cache/documents/containeranalysis.v1alpha1.json,sha256=b7J1ha6J1BZnZKGoAp5l1LNj73yV2Ne2gp0sidv8dH0,247765
196
+ googleapiclient/discovery_cache/documents/containeranalysis.v1beta1.json,sha256=z9rOvR5m2M0ajXP_aCfRZFAWTTJe-wsKDgWhezu6BrQ,239061
197
+ googleapiclient/discovery_cache/documents/content.v2.1.json,sha256=ymgq0aLEknRSoO2CavtUe3f_7GOZSVyGDwkR99vlBbU,461136
198
+ googleapiclient/discovery_cache/documents/content.v2.json,sha256=PuV1X8AOtI9T1gaQphOf14GgA06gplme2e31cRNVSlU,389993
199
+ googleapiclient/discovery_cache/documents/contentwarehouse.v1.json,sha256=mvMFtg4zcLO64JQheZ2qUKQCg3I69Wm9TE3TMKuVn6U,226184
200
+ googleapiclient/discovery_cache/documents/css.v1.json,sha256=KJ2dzbEvmh5AviW8FrrVGLqjlqxFDIziUIW8RzD3k1U,39890
201
+ googleapiclient/discovery_cache/documents/customsearch.v1.json,sha256=gkOUqUMB14JgNUySDvnSooKihyAmZWmbBYJ6Jpz0wHs,63076
202
+ googleapiclient/discovery_cache/documents/datacatalog.v1.json,sha256=Qc9aGPU7flalDIjfmXSSAHIPeDc6RWklFWZJdnvU9Xs,190705
203
+ googleapiclient/discovery_cache/documents/datacatalog.v1beta1.json,sha256=c2ROJXcXGwQKZRJB6c3hvIFIMxWjDxBRnF_kwAsRFuE,181608
204
+ googleapiclient/discovery_cache/documents/dataflow.v1b3.json,sha256=sZw15obwzdR2eDprVd_yAk0S1-xOUGHgzON_539-ywo,269356
205
+ googleapiclient/discovery_cache/documents/dataform.v1beta1.json,sha256=iROyM1iknQEzvZFAkUcl5mJadS8jks8PnGUvGZAlLOI,136023
206
+ googleapiclient/discovery_cache/documents/datafusion.v1.json,sha256=8iHFfjfx3OPHB9FXdPGU9YvMOyr6rw5907UoESfPqWw,65057
207
+ googleapiclient/discovery_cache/documents/datafusion.v1beta1.json,sha256=XX79TAGCboA4YoKDQO0kK4mahYMdhomkuL5sLkBbov4,73850
208
+ googleapiclient/discovery_cache/documents/datalabeling.v1beta1.json,sha256=lns1w3E-3LgdtmfUfJyqVwbwZzQ3g6B74vHroVp6DAI,202101
209
+ googleapiclient/discovery_cache/documents/datalineage.v1.json,sha256=6AWaukW2Ga1WYNgxlrkit7tEkBkob53s3EEuL0tn3BE,52135
210
+ googleapiclient/discovery_cache/documents/datamigration.v1.json,sha256=nkesiVQs7Ec-ZA0-aUEejNe_C5SGp6V-vMMoVlgu6do,234856
211
+ googleapiclient/discovery_cache/documents/datamigration.v1beta1.json,sha256=T5QcBH2cZMvW_DeBUlaA722nIv72-aFp-wgK64Xamyk,83904
212
+ googleapiclient/discovery_cache/documents/datapipelines.v1.json,sha256=vocmGOA8i7K12Yy3kAeZ1IsUfm3fza3QWFE6taPqP6Y,38301
213
+ googleapiclient/discovery_cache/documents/dataplex.v1.json,sha256=NhmwhtTqZEEP6YQE78o2F3FDGoQMHLWowfavDS9rkMs,450804
214
+ googleapiclient/discovery_cache/documents/dataportability.v1.json,sha256=JIsYb0r4OeqJu3TnUjFMQsMM6RO6RLN1uSUyxB12qk4,36826
215
+ googleapiclient/discovery_cache/documents/dataportability.v1beta.json,sha256=0unNWcA2qDzlxPxuP2kSzeAehrfQ7FFNawSOnwhioBs,36866
216
+ googleapiclient/discovery_cache/documents/dataproc.v1.json,sha256=1vrGUIBFe13aDBIMCDfg1tEYIeroZcAjwj_GtdK2XQU,419763
217
+ googleapiclient/discovery_cache/documents/dataproc.v1beta2.json,sha256=jfuxbI0IJ3EFmdqwKxUp_DvxU6gLnDToTAicOhZM0qo,256974
218
+ googleapiclient/discovery_cache/documents/datastore.v1.json,sha256=xVUxCtp3Gjf2pEJpJe5QyT1JaAaEmsD_zz6a7bV70kU,100085
219
+ googleapiclient/discovery_cache/documents/datastore.v1beta1.json,sha256=VO7aIgeLjU5MmVCPFhUE8xpT0iKgN9C3huRHRh7Gq3o,28932
220
+ googleapiclient/discovery_cache/documents/datastore.v1beta3.json,sha256=qLI1HDg2B1L408Rxr2iJjHuxSNL1RorPuHJJ6q6BI-Y,77077
221
+ googleapiclient/discovery_cache/documents/datastream.v1.json,sha256=n9LDes0lTcEE1TRM3-n2iuB7agQ91PszgTDgcZsyZhA,103775
222
+ googleapiclient/discovery_cache/documents/datastream.v1alpha1.json,sha256=KmKvG9YWrllDYs58ftVhmvjhHmpOU_LrjEfuxzP6FtQ,78746
223
+ googleapiclient/discovery_cache/documents/deploymentmanager.alpha.json,sha256=L2eiYKSq7jXnNHzCiKvHsr8iDFEOb32-vye9zb16RwE,156381
224
+ googleapiclient/discovery_cache/documents/deploymentmanager.v2.json,sha256=AjumIeDDOEv1i8PFvUxjCq6xYMPOJ2GS_mc-WKXTX8w,110123
225
+ googleapiclient/discovery_cache/documents/deploymentmanager.v2beta.json,sha256=ZhxaduE9vyakPZy18EkHdLWhBZ0xX_CvHlSz7LpJnqw,152471
226
+ googleapiclient/discovery_cache/documents/developerconnect.v1.json,sha256=zCoiMEsZqTO5bRMEfWG8UEZDGYBf3WkWScTCZCtL2SU,60139
227
+ googleapiclient/discovery_cache/documents/dfareporting.v3.3.json,sha256=AaucsfQ-9Hx6evOCWHX3E6n6llRjAlvVFEqLD2bpYXE,721039
228
+ googleapiclient/discovery_cache/documents/dfareporting.v3.4.json,sha256=0KvRG3-gvfK5CunHotnX5uTGYwl8W_af_vg0LX0q_NU,748283
229
+ googleapiclient/discovery_cache/documents/dfareporting.v3.5.json,sha256=E0e7bs-i0WQg8X-rLjIOn5DpeCDtiE9yDB_-J4VuCAw,17300
230
+ googleapiclient/discovery_cache/documents/dfareporting.v4.json,sha256=23kvdMdJDjisuIu1O1MbQ9DRnU01m1tZpPpcoRtFKq8,561870
231
+ googleapiclient/discovery_cache/documents/dialogflow.v2.json,sha256=PyLxzU9cn2TnD82R3wEyTUa7ad-JysLsWjHHoooNpVA,904937
232
+ googleapiclient/discovery_cache/documents/dialogflow.v2beta1.json,sha256=Wg6HvfW_DURYqbmQyO2VijjOKXbSu8iRxuvPFVs0x1I,917635
233
+ googleapiclient/discovery_cache/documents/dialogflow.v3.json,sha256=IA3ZxPl0CZpoO69KfnpMNMZnwoCWhdYlaX51Hi6dKr0,721841
234
+ googleapiclient/discovery_cache/documents/dialogflow.v3beta1.json,sha256=wu_B0wqKmjnnzzL88PamtuVzaOsy2yfJD6gqA7uVP6Y,803132
235
+ googleapiclient/discovery_cache/documents/digitalassetlinks.v1.json,sha256=tBdQ_zbFY3nWgAoYEu7xENFSCGOPE8fdB4DP5AR0LmU,23160
236
+ googleapiclient/discovery_cache/documents/discovery.v1.json,sha256=OQvmfp6aUxzASZk9m__FvI0wuRXNWI_41RykyxtDkzU,18215
237
+ googleapiclient/discovery_cache/documents/discoveryengine.v1.json,sha256=u7uCTQgoS1Rn7UI4AqAT77D6ZWOXdOJDKQFsqg6I2zo,883797
238
+ googleapiclient/discovery_cache/documents/discoveryengine.v1alpha.json,sha256=wt8JMtvDu0XiRpb8Iri7g-Hq8jPje5xuAOE_Rr2Py2U,988792
239
+ googleapiclient/discovery_cache/documents/discoveryengine.v1beta.json,sha256=XP3WZa-Sq99eDhAvmjzevhflqMl3jrJLLwCDwCT3BK0,938629
240
+ googleapiclient/discovery_cache/documents/displayvideo.v1.json,sha256=RRZQfVKtGzhfs9Kx6Rp2mrBcfaRJ9p5B9I76uIcVf4c,737810
241
+ googleapiclient/discovery_cache/documents/displayvideo.v2.json,sha256=oSWt-G3-tMflgniO0-P8CeSQdHBBof8bugoGhoOLVlo,866709
242
+ googleapiclient/discovery_cache/documents/displayvideo.v3.json,sha256=a4ZWSkikc85rTgtrlxo0Yg9o-IwWo7kIWkLmQcoCtv0,890041
243
+ googleapiclient/discovery_cache/documents/displayvideo.v4.json,sha256=ZawYORuamvnE2jVpVNrXpFwg7zEdTwNcHKxcGREHJ1k,9032
244
+ googleapiclient/discovery_cache/documents/dlp.v2.json,sha256=ILofEDjRmbV_nRajCqB--gniX4jPDkatv1Dot8ac-5I,504049
245
+ googleapiclient/discovery_cache/documents/dns.v1.json,sha256=31VX45LnFzs_GAWTePOVNpydMKIy7ZGK8Fjon5rSCsE,120991
246
+ googleapiclient/discovery_cache/documents/dns.v1beta2.json,sha256=52oyyG4DQKMFARdbr_O7zuJr0pCiiFS6vdcCsAPXfBI,121375
247
+ googleapiclient/discovery_cache/documents/dns.v2.json,sha256=uMSPBTHSlq6gMc-OC9ap_C9WuE34lwbub8U8wOlwoTY,136579
248
+ googleapiclient/discovery_cache/documents/docs.v1.json,sha256=vQVgDlIF0_Q2k64NYL4moCNjX_vs6coUHA4soKIGNuE,179576
249
+ googleapiclient/discovery_cache/documents/documentai.v1.json,sha256=VUhun0E3Y008IHLZ0eFGuV-oRZx2gI8g-OWgf0RQA14,216499
250
+ googleapiclient/discovery_cache/documents/documentai.v1beta2.json,sha256=gOemdhcv2MjxnsArox4YiE7zXia3wVKtMsD6eqBauYw,213046
251
+ googleapiclient/discovery_cache/documents/documentai.v1beta3.json,sha256=Mgp0oe0TMtHDrTwGa-SSCKfpTyRpBUlxzb9J-LGwVJw,242036
252
+ googleapiclient/discovery_cache/documents/domains.v1.json,sha256=PwWqqc0xfoSTnPDD42gxDj2ImzrMVSgNsB7ZIbJuOjk,121316
253
+ googleapiclient/discovery_cache/documents/domains.v1alpha2.json,sha256=rs8IVr2mfpDheP6stPRORTsx3_KXcnjqVoWkIMnP8z8,121969
254
+ googleapiclient/discovery_cache/documents/domains.v1beta1.json,sha256=HUruKucE_B4mvemDN5JEM9JB75naeV7ElIHY7pMDj-s,121606
255
+ googleapiclient/discovery_cache/documents/domainsrdap.v1.json,sha256=0kMvTxrY_-Slq8YjmDxT3Q1LZsiE4EkltzeZvzj7R3s,11381
256
+ googleapiclient/discovery_cache/documents/doubleclickbidmanager.v1.1.json,sha256=jHYIGcAx7c3WN_5Mvr6LpEFpkB-VYgyz-rpoi41Fl-8,117347
257
+ googleapiclient/discovery_cache/documents/doubleclickbidmanager.v1.json,sha256=c-oeCNUdKAdNJa3Bm3sqAgb6LpgiCn-s6NUUp4rsUt8,3347
258
+ googleapiclient/discovery_cache/documents/doubleclickbidmanager.v2.json,sha256=6RTXu53BSvzuhG_XjyBAIyI8vc1Z7QWkJ_SggHTN-mI,21365
259
+ googleapiclient/discovery_cache/documents/doubleclicksearch.v2.json,sha256=nMNNU5Wh63p6VgzxMbwKymqzMi3TmZnMbsqjzeWuT3M,34837
260
+ googleapiclient/discovery_cache/documents/drive.v2.json,sha256=1JsmCK3ifu5GB1Pdc7PUSaEhuwzVSDuuNaXG5bjJJtI,202718
261
+ googleapiclient/discovery_cache/documents/drive.v3.json,sha256=au-64DTcQRsh-H-9nFoN1X6URNNp2Gm1L2WLzwhqReg,172775
262
+ googleapiclient/discovery_cache/documents/driveactivity.v2.json,sha256=8hW2V8ATuQ1vZVA-Dnvf68A76ZQ_sbrF0i_ZYC-Un84,36906
263
+ googleapiclient/discovery_cache/documents/drivelabels.v2.json,sha256=Ht1FQobkilICz2rSzJMAStHsyHCNnK8379lRIX4Qewc,105403
264
+ googleapiclient/discovery_cache/documents/drivelabels.v2beta.json,sha256=KllsdDh4AyvkzyqPDGNwMqPPDI7ELklHrDItFP24vNI,106827
265
+ googleapiclient/discovery_cache/documents/essentialcontacts.v1.json,sha256=QtOLZeKQ0sPdiDEBGqfvjxWQMxQQA5GJT6bN53yTWOk,34471
266
+ googleapiclient/discovery_cache/documents/eventarc.v1.json,sha256=nfE_eUTO4AQSL-d7jKnbcF-TLtPg7RXKYFuP11C3hgo,166722
267
+ googleapiclient/discovery_cache/documents/eventarc.v1beta1.json,sha256=mY2ecbNBWJyhuWfnF0fndnDH0Dqr1a38N8c36huuixw,46836
268
+ googleapiclient/discovery_cache/documents/factchecktools.v1alpha1.json,sha256=W4CxWFn3fyxidiE6iML3nT2EJg8FsBTVPgOOGjXKy6I,22449
269
+ googleapiclient/discovery_cache/documents/fcm.v1.json,sha256=m7236CktCpc2kWNwVCKG40qiL_lxqyIqwmAvvDosjHY,31035
270
+ googleapiclient/discovery_cache/documents/fcmdata.v1beta1.json,sha256=MyF9jSa11RwspABXDPfTYu7GVCMRxKoOOAeb6FkJiIY,15964
271
+ googleapiclient/discovery_cache/documents/file.v1.json,sha256=peVFkE2FejtY2dS208tSulzrk7-fUb3eK6fzo9ci-7s,83404
272
+ googleapiclient/discovery_cache/documents/file.v1beta1.json,sha256=PV7fB3cbJVOUpawLDPokrKl5o54-jj5wGvDpt51fxVQ,94032
273
+ googleapiclient/discovery_cache/documents/firebase.v1beta1.json,sha256=SIrVTCGEiXj2AnscnEHF_KRIik5y6f0DFbbY8iaa1aM,116101
274
+ googleapiclient/discovery_cache/documents/firebaseappcheck.v1.json,sha256=4sJ6aL6BDdt90T5PJa-4W5DbSIrHL0SvxCL4Dp5Xyxw,101098
275
+ googleapiclient/discovery_cache/documents/firebaseappcheck.v1beta.json,sha256=ZgX4sBB3YsiZzB1iKf47-uyZKWS4hKs9F9UriqctAcI,119685
276
+ googleapiclient/discovery_cache/documents/firebaseappdistribution.v1.json,sha256=mU5U6Iw-dcVvFKKcCWGDW9yf_gCJH3CxgYobhvNNqpU,65376
277
+ googleapiclient/discovery_cache/documents/firebaseappdistribution.v1alpha.json,sha256=5QrB2S7cFJAnVsXnwzqZ0cayStPJe37pkQzICzDXPbY,54017
278
+ googleapiclient/discovery_cache/documents/firebasedatabase.v1beta.json,sha256=CDrBLeHyVymSxQdwRs4RMA7M-WBCs5Jg79lnLExxtuE,15647
279
+ googleapiclient/discovery_cache/documents/firebasedataconnect.v1beta.json,sha256=aY8mh1PEA5W1OAAes0Uv-6gTJVbp8F2CNHEaQpGVFOo,66408
280
+ googleapiclient/discovery_cache/documents/firebasedynamiclinks.v1.json,sha256=rncuTrigAtLNh7coo5yBLG10g9E7qNRzMl7D9Lrs6Uo,33276
281
+ googleapiclient/discovery_cache/documents/firebasehosting.v1.json,sha256=iUmcrmwQcS2COWiCL1POQJOfbbFVMfnpo9eqWWUiyN0,26742
282
+ googleapiclient/discovery_cache/documents/firebasehosting.v1beta1.json,sha256=35WM0roy6_pJoCwTgml7DPn-xXi3QU5jaZZDMfESBfc,133655
283
+ googleapiclient/discovery_cache/documents/firebaseml.v1.json,sha256=fshZd5QIjB4RNnuMlW2r_7Sa50JKTyE-UHjmIEwDPik,10356
284
+ googleapiclient/discovery_cache/documents/firebaseml.v1beta2.json,sha256=1Ajl7yL81dyXtz5SQPKdh6GpKMR6W3dw-tdYjI1Sky4,16713
285
+ googleapiclient/discovery_cache/documents/firebaseml.v2beta.json,sha256=7luCzjXobG7Dwg608hOloGuQyAiRP5MXN8ZBkacwcsY,61961
286
+ googleapiclient/discovery_cache/documents/firebaserules.v1.json,sha256=ZJDkeRQTv28Vjex0ru4YEllbvnZbXMHPNxknLMZrUE4,34267
287
+ googleapiclient/discovery_cache/documents/firebasestorage.v1beta.json,sha256=zOjCJ_8yjwYhvWe_8RQmeFP5aACyZe0DpTFgS5YNyS4,11253
288
+ googleapiclient/discovery_cache/documents/firestore.v1.json,sha256=oUIEHZOtzHtn5Tr6YQAD71NmvUE7jC1NXHZrCBkO178,175534
289
+ googleapiclient/discovery_cache/documents/firestore.v1beta1.json,sha256=llxkWENlKf5nWPvMft44-5eUZAesVQ29QE_DupcN3Kg,115173
290
+ googleapiclient/discovery_cache/documents/firestore.v1beta2.json,sha256=JZ0NPEIf_QLVibDrdVQcj3EEKweoUqwcZR8Tqn4fa9M,42024
291
+ googleapiclient/discovery_cache/documents/fitness.v1.json,sha256=1MKnVrlqoJrCbnSw2dXGgsnVrTpsoUvAoPtF2bObQTE,62402
292
+ googleapiclient/discovery_cache/documents/forms.v1.json,sha256=9fTiidrmUpvtDVevcqARMFI7xR-0JI_riejral43mss,48971
293
+ googleapiclient/discovery_cache/documents/games.v1.json,sha256=WEdJWujsSDxHD53NxbOSlEAh-qaC19SuubQcCsjJmj4,102344
294
+ googleapiclient/discovery_cache/documents/gamesConfiguration.v1configuration.json,sha256=FwEt1QaCcASdBP9RIFgK5RaDjDrAx3SwEEvhFWZVrPE,19279
295
+ googleapiclient/discovery_cache/documents/gamesManagement.v1management.json,sha256=Q8V6mhQAe-fVjBSx3g8C5Nyy7KwyL7OW2htLTX6j4g8,23157
296
+ googleapiclient/discovery_cache/documents/gameservices.v1.json,sha256=E5MFFlyECvsMxSIdo45glqQhAagCDHzeRSo13RPcJ-o,54733
297
+ googleapiclient/discovery_cache/documents/gameservices.v1beta.json,sha256=amIruWItU7wwP_wTWMXY_g2eoY-2FW24EWyPxwQtMvs,54813
298
+ googleapiclient/discovery_cache/documents/genomics.v1.json,sha256=r75lm6eDRH0cxivOOnIQnsm-KkrMY0C8Kp1H6WirqHY,44128
299
+ googleapiclient/discovery_cache/documents/genomics.v1alpha2.json,sha256=OBijBJvThGSucv3G0IILtC8RNGFmdxYrZeLTDFMncsM,66239
300
+ googleapiclient/discovery_cache/documents/genomics.v2alpha1.json,sha256=80yCmc2cqlgSJfPYAxqPMCKFxDWRksFMZzsEkgcsQmI,63816
301
+ googleapiclient/discovery_cache/documents/gkebackup.v1.json,sha256=KnOQzdzf3TigrcI05irI38RRBKxln2S4qQfAK8hjxxg,153579
302
+ googleapiclient/discovery_cache/documents/gkehub.v1.json,sha256=vWsti_ndFL8QznyLPZJzel8_pxCSpegndQ9t6SeYonQ,229484
303
+ googleapiclient/discovery_cache/documents/gkehub.v1alpha.json,sha256=OUtri177JQm_KW2F5vDsEKlFO8RSu86PC9D2qNAnUNU,255349
304
+ googleapiclient/discovery_cache/documents/gkehub.v1alpha2.json,sha256=jIsXo_cDmHYf0RJNlhYTrM1ELjde46sbGHhrfbOGDc4,65373
305
+ googleapiclient/discovery_cache/documents/gkehub.v1beta.json,sha256=PbL9STV9b_RAbhz_M3nieQT4sfWYMwnOzo_RZKQS0Yc,234386
306
+ googleapiclient/discovery_cache/documents/gkehub.v1beta1.json,sha256=hDEstPQR1sd3b41LU5WVZnHjsGarCEzEsO6oH6WIWNE,70769
307
+ googleapiclient/discovery_cache/documents/gkehub.v2.json,sha256=gFoyTKKO2WkBi2IFJXyPPP9gw2qjJqxjK1MhKhtSkq8,105575
308
+ googleapiclient/discovery_cache/documents/gkehub.v2alpha.json,sha256=5cJBxMLZdxQz2rsBn-ButKasi6OSzD4vX_RW4K5JpJY,105685
309
+ googleapiclient/discovery_cache/documents/gkehub.v2beta.json,sha256=6_FlHxaPZ9ogWxzvsKNddMZE7rh6H2RDLSGQzRdB0_g,105663
310
+ googleapiclient/discovery_cache/documents/gkeonprem.v1.json,sha256=SB2ddnqilneRzAgLufYPcgQvEcOnGNJC3B6FjDFbgro,251420
311
+ googleapiclient/discovery_cache/documents/gmail.v1.json,sha256=uc1urdhwNDi3D4tXAqICCeyOWvDq2rj8LfiYyNtjbys,130285
312
+ googleapiclient/discovery_cache/documents/gmailpostmastertools.v1.json,sha256=VZ9GeZ9mWC-xOoTrHu-dGjgPbcoSf49GJjQYGaEsKz0,19146
313
+ googleapiclient/discovery_cache/documents/gmailpostmastertools.v1beta1.json,sha256=2AzegFtjBD7FyGwpyGjlsZKSKjWpHrhjEveNQWkMLJo,19533
314
+ googleapiclient/discovery_cache/documents/groupsmigration.v1.json,sha256=D1av9Pn3hJa_u2CCR0QiAOJzO4dnWVlxKPtcNpZzEa0,3947
315
+ googleapiclient/discovery_cache/documents/groupssettings.v1.json,sha256=PwxhV_pC71kBNg0BHpRw9Ten-Qbst58PfAXVY6Ua5j0,24702
316
+ googleapiclient/discovery_cache/documents/healthcare.v1.json,sha256=5S1AxogIXVgXETlNaqv3UxXgAxsATZfPh1xerwh0l7o,425514
317
+ googleapiclient/discovery_cache/documents/healthcare.v1beta1.json,sha256=PIan6_ZWCZRuwbbOFdcTp2IXaqOOtLd9Es5HEhFt_vI,517493
318
+ googleapiclient/discovery_cache/documents/homegraph.v1.json,sha256=qPTUCKu2hgemWV0ZD62RU5Am4q9OpZp5o-Ex-E1Cr8k,19439
319
+ googleapiclient/discovery_cache/documents/iam.v1.json,sha256=es6jlbAQh238pUd7_q_KBGl91BvCrppWLKVNsozNp-k,225363
320
+ googleapiclient/discovery_cache/documents/iam.v2.json,sha256=r1IFYfHw-MHMM3WAQXfsm_MPS8JHMvxaYZfy2FIb6y0,35610
321
+ googleapiclient/discovery_cache/documents/iam.v2beta.json,sha256=xSjJ1XkIsWKAJGYvGYFwz_A-bdcG7gz_gDHT7-ZqeZo,35734
322
+ googleapiclient/discovery_cache/documents/iamcredentials.v1.json,sha256=YY7DbQF-Oteh-PaeHyuwRCogvvRTcLo0GOWEfs76Gc0,15568
323
+ googleapiclient/discovery_cache/documents/iap.v1.json,sha256=sHrWTDyQu5unoKWB0z4iFSfVnYv8xr8O347B1zygpEk,59990
324
+ googleapiclient/discovery_cache/documents/iap.v1beta1.json,sha256=E-FmRVtEg5CcmV2MtJcrhp_5yYwbUnm1y0sYagRdwUQ,20190
325
+ googleapiclient/discovery_cache/documents/ideahub.v1alpha.json,sha256=PfWK6J_Vqz1f_-mYWGBlCxLWSc8iwHrn9QRu0fl3GBY,21042
326
+ googleapiclient/discovery_cache/documents/ideahub.v1beta.json,sha256=9N4Jk-jHWcWC-Cd5Hb_ARxh7nB6h2HVqrDNPRtei-GY,18785
327
+ googleapiclient/discovery_cache/documents/identitytoolkit.v1.json,sha256=eTazl2iKZAjAa9mncdX4fbzaMsG7V-8xCA8fJ1KeX-I,144415
328
+ googleapiclient/discovery_cache/documents/identitytoolkit.v2.json,sha256=2ymDalv9BVxei5zH18pCxBVp2S1XoIkKxmBuMbthXOI,135206
329
+ googleapiclient/discovery_cache/documents/identitytoolkit.v3.json,sha256=jg5fCSI6F9Ubd6pdyjUdL3KZboo1DwLrwX_fo1SQfIY,54662
330
+ googleapiclient/discovery_cache/documents/ids.v1.json,sha256=JPyf7bAC-g_avSj39DZ8OWEDQ4Kjtlc_DuOEL6QOdJc,45751
331
+ googleapiclient/discovery_cache/documents/index.json,sha256=aToo8a5LH-shdyLDo4-_QRwB6s1vFYEsF2w-gmO3-eg,213200
332
+ googleapiclient/discovery_cache/documents/indexing.v3.json,sha256=VniFOPVeV6ho_SPcRiHzZD1WuhDlrmib49WzGG6EUoU,5776
333
+ googleapiclient/discovery_cache/documents/integrations.v1.json,sha256=xs9QD_OraCxKQg5k1Z90oL-MjjaaTaPPiFaQ6oEe6Tg,456625
334
+ googleapiclient/discovery_cache/documents/integrations.v1alpha.json,sha256=-bp1QUgLeateldClVafXg6Z8lbasIk1B9x0Vc5UwSKk,376245
335
+ googleapiclient/discovery_cache/documents/jobs.v2.json,sha256=L-aDKIJ86eq-tEmOrHZfKD2MmQkCP_uTwCCTQHSJcoQ,227088
336
+ googleapiclient/discovery_cache/documents/jobs.v3.json,sha256=P-J5VqtIGG6H5Rxl2hevQTdxPTAjJO-orVKw_Fi2PfM,121084
337
+ googleapiclient/discovery_cache/documents/jobs.v3p1beta1.json,sha256=CZjL4LfwMkUytRs_RspqoFAD8jj_daJEqCho0OPFkNg,135073
338
+ googleapiclient/discovery_cache/documents/jobs.v4.json,sha256=-VKniKmKFhS7MMIwuCrmtz6ZDCHRuJm897uqJX0j6YU,135198
339
+ googleapiclient/discovery_cache/documents/keep.v1.json,sha256=H6RV6WhCGGmCNNLyLnwEAADc099e1wuw0vsnnJVrx34,16988
340
+ googleapiclient/discovery_cache/documents/kgsearch.v1.json,sha256=ZwTdiUrvYERjzOanj4JdPhI2Z9Y_A43vI79EmFRr6io,4886
341
+ googleapiclient/discovery_cache/documents/kmsinventory.v1.json,sha256=EOJj0RNpmBO4TdluNCDMC9x4bqM12kdSBbJyopJZJOs,37255
342
+ googleapiclient/discovery_cache/documents/language.v1.json,sha256=i9BbvkYQUc014TBtNgQIvAyOXa3AMRmHNaqL6AZTIQY,151044
343
+ googleapiclient/discovery_cache/documents/language.v1beta1.json,sha256=-Nwsr0Ls6nKWMZSQ3ZzkW1Zdvu2gEqb6yt4r65Z1xOU,38558
344
+ googleapiclient/discovery_cache/documents/language.v1beta2.json,sha256=2SCTKWN9wXpLK5jNvalszWpY0r5fiy3B1HCoJ-kosYY,151842
345
+ googleapiclient/discovery_cache/documents/language.v2.json,sha256=Ux-ogcW16fvhm1RbQekLGUWrlCpeZyZmg3T4M34dgEk,137510
346
+ googleapiclient/discovery_cache/documents/libraryagent.v1.json,sha256=DoFPi9frga11E11_DL9e8wQ6cZQfLrr1TqUJq3oNNBc,9898
347
+ googleapiclient/discovery_cache/documents/licensing.v1.json,sha256=oOeJCfktYayhq58J7h4D_QvuULKg_vpv_7lDEySg6r4,15821
348
+ googleapiclient/discovery_cache/documents/lifesciences.v2beta.json,sha256=4dAvNj0dYkEGW1fnfJDw50bdjXpybnuavtcv73MDNXY,52343
349
+ googleapiclient/discovery_cache/documents/localservices.v1.json,sha256=x6aX43jOnqyA7U-kk3WhT81I9IiVEzWXvlibZ8BjARw,18779
350
+ googleapiclient/discovery_cache/documents/logging.v2.json,sha256=BS0kjSFofWfQdY7yUmuMIfrw0i49aaSvbbhWWvxoPRk,499361
351
+ googleapiclient/discovery_cache/documents/looker.v1.json,sha256=63oHAMoKoZnoSuqxCLW2QQyqOC-UG2uq__-qyBQzL8A,62669
352
+ googleapiclient/discovery_cache/documents/managedidentities.v1.json,sha256=I6-Y_yAA6ziSnaSrM_l7YADwtiSuy6r16sPGmc97jck,118608
353
+ googleapiclient/discovery_cache/documents/managedidentities.v1alpha1.json,sha256=WnjLP7j2ViTJHVOD0SEr1ZY52r4fYOZv09cye6vs17U,118634
354
+ googleapiclient/discovery_cache/documents/managedidentities.v1beta1.json,sha256=Fo4FFL_Cay-WS4Nn5MF2_GHn5_PQpO880X-8xvzXEMU,119587
355
+ googleapiclient/discovery_cache/documents/manufacturers.v1.json,sha256=U88bUQKj4jTRJg_6sfwe0z8J_-Il9R9TO5nAIxASzLo,41060
356
+ googleapiclient/discovery_cache/documents/marketingplatformadmin.v1alpha.json,sha256=qTk0pcCjd6-CAIXuWIlogDucnUW-AU8Rde-UEsODlk0,12562
357
+ googleapiclient/discovery_cache/documents/meet.v2.json,sha256=BBEIyy5XViNkOgfMe65O-rw9KBb8_yTlwgMBtD7hnuA,37589
358
+ googleapiclient/discovery_cache/documents/memcache.v1.json,sha256=4i5N8zjO2CgySgFO_beCtfPNR43yErxoHLGjH3onSAE,71496
359
+ googleapiclient/discovery_cache/documents/memcache.v1beta2.json,sha256=lT4Tt833MA4YeoNAOHP7l8L_oVkRtYyLqkyVSyZ3FUU,73422
360
+ googleapiclient/discovery_cache/documents/merchantapi.accounts_v1beta.json,sha256=xpgGYUsO_vWunfZOu8rQDfaI6YEGgQ74vhZG_fZ-E0Y,124343
361
+ googleapiclient/discovery_cache/documents/merchantapi.conversions_v1beta.json,sha256=5zcG8e8Y6TA09dl-S2Qg6ng6M2-3TIQfVc9UIFW7Ang,19642
362
+ googleapiclient/discovery_cache/documents/merchantapi.datasources_v1beta.json,sha256=6w1rx3JrUYD4kQ5avPNTk-JFDQB8UNRYTvqRS7o3DdQ,33051
363
+ googleapiclient/discovery_cache/documents/merchantapi.inventories_v1beta.json,sha256=Vxj_Om5hnX52OjAZuqQ95yqTi3AFBQjsr4NnM00MatM,23280
364
+ googleapiclient/discovery_cache/documents/merchantapi.lfp_v1beta.json,sha256=VHfn9DdlpaNTifQyeuD39LjFMJ4sR0fACw3qaK4bgGU,21985
365
+ googleapiclient/discovery_cache/documents/merchantapi.notifications_v1beta.json,sha256=3KuiqB9rXb0KRXAGSEgZkgMkKZ5U1-1q6TPUTKUd4TU,14756
366
+ googleapiclient/discovery_cache/documents/merchantapi.products_v1beta.json,sha256=XumKJRmBkDh4PqXouuEMWt6_xyJqp_b0eKu5vK5FjL8,60221
367
+ googleapiclient/discovery_cache/documents/merchantapi.promotions_v1beta.json,sha256=7ZjVcPPamg5_s7uPocX8SGnWF8oDqLRYRknb9CdagI4,38469
368
+ googleapiclient/discovery_cache/documents/merchantapi.quota_v1beta.json,sha256=fHdAw0J-7XZfBpS1fGyBa6Pgbc6Sm9puiLMFu-Ok5M4,10803
369
+ googleapiclient/discovery_cache/documents/merchantapi.reports_v1beta.json,sha256=icEEi9IIHJEKPYIcQ0GwWanIrTvRx697OcCQFGl9VRs,57674
370
+ googleapiclient/discovery_cache/documents/merchantapi.reviews_v1beta.json,sha256=BmeYCB4nykwHEyAmdWTVhMpwPv5AgMFrgPf7t41Q508,41441
371
+ googleapiclient/discovery_cache/documents/metastore.v1.json,sha256=q4_E6ZQsz4vu7qRkmuY35Zcio2QSPwoPHJMFRuhUlD4,138387
372
+ googleapiclient/discovery_cache/documents/metastore.v1alpha.json,sha256=xDcn5pPHyTGM3mFo1sO8xB8iAI8Wd_aiqC07tlvs94Y,148142
373
+ googleapiclient/discovery_cache/documents/metastore.v1beta.json,sha256=DuG0CMMSsWxWMVT_zQB8kQPv0kIHTXnbgWfHud4fKY4,148036
374
+ googleapiclient/discovery_cache/documents/metastore.v2.json,sha256=VaZVzO_cq-76qmwfyuocvda5bbfDFgRXF3Rh5d6sDlg,65940
375
+ googleapiclient/discovery_cache/documents/metastore.v2alpha.json,sha256=4ihtsmqBSjloKlXpeJSzEAOKxY3gVZZ0FBsXQ15TizI,87082
376
+ googleapiclient/discovery_cache/documents/metastore.v2beta.json,sha256=mmZbhWSL0S2tI_rMSV3O9ykdcQNPhjLBxXfTw2gtANo,86926
377
+ googleapiclient/discovery_cache/documents/migrationcenter.v1.json,sha256=Y9OsRWLjxNr-sZjnWMDo7EUTsT0nEHmeU_NdIYZUnMc,201846
378
+ googleapiclient/discovery_cache/documents/migrationcenter.v1alpha1.json,sha256=6wzHokSknoipMJPtcWk6pEnsl-AFbzoGCdtLl-ZpPrc,260994
379
+ googleapiclient/discovery_cache/documents/ml.v1.json,sha256=40Cfcaow97DrLVDBP6ywNVc6vJnPRr3o8aYbJa9wNvk,175519
380
+ googleapiclient/discovery_cache/documents/monitoring.v1.json,sha256=khwaKAtHT_z_pDcpIbEnJ6oCXm72UR4e-iAYXG8Oyz0,111103
381
+ googleapiclient/discovery_cache/documents/monitoring.v3.json,sha256=pJSIVN51vLoymsxodRL1bWsJXBh3m2Omkwnn0ebSMug,340235
382
+ googleapiclient/discovery_cache/documents/mybusinessaccountmanagement.v1.json,sha256=U7RlX8MHt_8J5EjbR8Hd5AfnGxWixiSz8C3Bk-bkYNM,31877
383
+ googleapiclient/discovery_cache/documents/mybusinessbusinesscalls.v1.json,sha256=w_OnSvJZU62j-5J8o3Mt3CmA2Rk7_GKu5DuhsIV574Y,16209
384
+ googleapiclient/discovery_cache/documents/mybusinessbusinessinformation.v1.json,sha256=YM3qz1QaWvyDMqJFT3UKs9wX8Eqs06YUOnx3eLt70c4,66109
385
+ googleapiclient/discovery_cache/documents/mybusinesslodging.v1.json,sha256=3XznJiEG44cWQkgSHQrS0u8P7mX6J6Ck9P9hGN1Sf4Q,222770
386
+ googleapiclient/discovery_cache/documents/mybusinessnotifications.v1.json,sha256=iuA9q6GqeWcDfbXU-FrSAkrjOAXOeRBSPUXbSiIVA1I,8029
387
+ googleapiclient/discovery_cache/documents/mybusinessplaceactions.v1.json,sha256=EnWkiYLZggSlFINF0ujYooNwRMh1qPxdVLR2n-Ikhbk,14578
388
+ googleapiclient/discovery_cache/documents/mybusinessqanda.v1.json,sha256=MBjZalhwZNuin_Y54kxl13lctTp5ODRexqgaUK0BCBM,14263
389
+ googleapiclient/discovery_cache/documents/mybusinessverifications.v1.json,sha256=fundzoIO-hqaxj00NFEvNpvLB2o_V-Lq0g-Z-SEPUw0,25436
390
+ googleapiclient/discovery_cache/documents/netapp.v1.json,sha256=y4kFnBAydsWxXKol13mD84TvbAn60P744AMF-HJIwOU,119565
391
+ googleapiclient/discovery_cache/documents/netapp.v1beta1.json,sha256=6WJTti64muknSDPEB3HRKAOefUnsOL3yw1qgsweI5yA,120185
392
+ googleapiclient/discovery_cache/documents/networkconnectivity.v1.json,sha256=lG9TMypnujHxxrp-eeXJKw8PYkpzQxh_aT59e8tmrgU,218420
393
+ googleapiclient/discovery_cache/documents/networkconnectivity.v1alpha1.json,sha256=6rKUWRsfJBXVkslr7A4GfMG5z68SkQOh1NKeKwc0nYw,77946
394
+ googleapiclient/discovery_cache/documents/networkmanagement.v1.json,sha256=oL2ib2MdPcQGdEzmbMszdGFd35pibwPnb6nifuU9hqY,136309
395
+ googleapiclient/discovery_cache/documents/networkmanagement.v1beta1.json,sha256=HCow9RtTXotqPw5u9qpVFhb2p7qDPDVXoLR0cKVUUaU,136694
396
+ googleapiclient/discovery_cache/documents/networksecurity.v1.json,sha256=0MsKDzhUB9IEUoEf2j35J2_Vk7RX7mFw7hIM5EMCuZU,213715
397
+ googleapiclient/discovery_cache/documents/networksecurity.v1beta1.json,sha256=N38zifIZR9ruL6HMjWLhvjbhdJ8wvruTZqRvL1K-474,297955
398
+ googleapiclient/discovery_cache/documents/networkservices.v1.json,sha256=3F-2_pQj8BXc0X6VxOV4XkAxuASchwEVT178uQnAZX0,228821
399
+ googleapiclient/discovery_cache/documents/networkservices.v1beta1.json,sha256=wULV7HPEgN8b9fPpTla-V3sQw0RUQ80EHwk8TGHXB0g,201237
400
+ googleapiclient/discovery_cache/documents/notebooks.v1.json,sha256=__vD59fInJn3zUfKNttK6qgRaZyPE3VY_5s_IN02DTo,158820
401
+ googleapiclient/discovery_cache/documents/notebooks.v2.json,sha256=9I2cY-MwbzZAK2gVfRj9vXG0OGM69G-9Ty3K-zbqbuw,73615
402
+ googleapiclient/discovery_cache/documents/oauth2.v2.json,sha256=qbqQUKMu6g1IrIHIAfYwTAZZgIDf8j69Lr6i-rzbzLs,6601
403
+ googleapiclient/discovery_cache/documents/ondemandscanning.v1.json,sha256=h0ZDuz_0x4m4FvPK-alwleANgGafl5OPEECbXsSp41E,89079
404
+ googleapiclient/discovery_cache/documents/ondemandscanning.v1beta1.json,sha256=6qb8SkKIhBBRv5VMGxX3vDPO7HEL5TSb6CUbqTxEYUw,88930
405
+ googleapiclient/discovery_cache/documents/oracledatabase.v1.json,sha256=_PpS9gAqv0eOJjsa7ViTbjOjSGskhO2QWB-48JdAF3Q,113807
406
+ googleapiclient/discovery_cache/documents/orgpolicy.v2.json,sha256=PlrZ91XeWx8_1iPfrJWLdqeI_HfzU-O1wox_t2Wu96g,55001
407
+ googleapiclient/discovery_cache/documents/osconfig.v1.json,sha256=jnodAzCWzshL2kpHej4PfTkLatmYZRLHjajwBd-s1oM,138166
408
+ googleapiclient/discovery_cache/documents/osconfig.v1alpha.json,sha256=dz9rtdFFiGT0gs4tseVuQngkLKboE-40w5usXiJMvKM,102717
409
+ googleapiclient/discovery_cache/documents/osconfig.v1beta.json,sha256=viqTggYhH-64QgnGjnL1vHmSatY6rljm4fMBc0zoJto,84213
410
+ googleapiclient/discovery_cache/documents/osconfig.v2beta.json,sha256=QQnv2F3r7UOBh1zIsBZBdSbZpb_7OlN3baB9lAIHAjo,82834
411
+ googleapiclient/discovery_cache/documents/oslogin.v1.json,sha256=4ET1m0EGL0LRqHrMX2sb2bPlseYbvXREX8i5281ygPs,13069
412
+ googleapiclient/discovery_cache/documents/oslogin.v1alpha.json,sha256=mGq2JiLOp0wzSdRGyZ8jdeit9-PGW8GM2vo359H23Yk,18237
413
+ googleapiclient/discovery_cache/documents/oslogin.v1beta.json,sha256=LKp2K_NdUiOikukkd2toj-jRemOpu7dSAghx_9r1JY4,17332
414
+ googleapiclient/discovery_cache/documents/pagespeedonline.v5.json,sha256=HLFi19o2CGZYT-nR4oK9F-9tXBWrREeBDm9f3PKKcJY,28503
415
+ googleapiclient/discovery_cache/documents/parallelstore.v1.json,sha256=uPQmLV0bHVI_tjbvK6t8seVP98SdxKbTVecWNT1NTRU,33852
416
+ googleapiclient/discovery_cache/documents/parallelstore.v1beta.json,sha256=XHXxhqvfnUYlbjHUoiX9jMhv6aczOoVw71LZ3O-r30w,33747
417
+ googleapiclient/discovery_cache/documents/paymentsresellersubscription.v1.json,sha256=GMReyufqCc1r4q61sacnTqvCNti7oRlSoRBncFKt7Jw,63907
418
+ googleapiclient/discovery_cache/documents/people.v1.json,sha256=J4mQcN80Mg6uuLYNkT4mBIZsTRc7STO1J57hLurIhCg,112444
419
+ googleapiclient/discovery_cache/documents/places.v1.json,sha256=Ae8Bz1mSaVA9V1svetbl3hw9mI3tt3tjciM0ZJ_zEGQ,101979
420
+ googleapiclient/discovery_cache/documents/playablelocations.v3.json,sha256=wbkjdTm2IPCudHBKwwIOaAWwsRxfcinsOiKPR_C5G4M,25906
421
+ googleapiclient/discovery_cache/documents/playcustomapp.v1.json,sha256=pG8LwuC9yO1R9lSyNXVskFTrZaBm_MQCl3JPegK2yck,5201
422
+ googleapiclient/discovery_cache/documents/playdeveloperreporting.v1alpha1.json,sha256=3BaSj01eeG_qmG8QeeOp1jMzOe2jI8AEGDXkIxGVpnQ,138589
423
+ googleapiclient/discovery_cache/documents/playdeveloperreporting.v1beta1.json,sha256=H09ESl98kgRuS7Pu5bzdQQeW0i9c20TItmxe7mTkelg,138392
424
+ googleapiclient/discovery_cache/documents/playgrouping.v1alpha1.json,sha256=IiCHjssDE3DyDE09U8j9GumZpi2t6SZfFiy_myuQm-s,6307
425
+ googleapiclient/discovery_cache/documents/playintegrity.v1.json,sha256=K8X2HuHOCuRoynghaOnf_DHkuqydQKJHMPMNtyp5yyY,21561
426
+ googleapiclient/discovery_cache/documents/policyanalyzer.v1.json,sha256=UbzYQTXuhZcV_f8klEA9ps8syc4RTJ_30TpRYiLa5AE,11965
427
+ googleapiclient/discovery_cache/documents/policyanalyzer.v1beta1.json,sha256=uc6Tw0al4RaKcVAwNyNoA2nEUNP7uzUdPxnZxnz6isQ,10922
428
+ googleapiclient/discovery_cache/documents/policysimulator.v1.json,sha256=PYwp_Gjxv4AmP7rybR45q706VAnHXTdoMxx-AfcobRs,94572
429
+ googleapiclient/discovery_cache/documents/policysimulator.v1alpha.json,sha256=sCxxvlvmUJpC-Wj7zQQ4FKC6WptAo6rbshCQP3LAQtk,114597
430
+ googleapiclient/discovery_cache/documents/policysimulator.v1beta.json,sha256=e04UeFXURBxKh2YeFL8xLwwBEPOLYuOOjp9sTZ3mwTo,114473
431
+ googleapiclient/discovery_cache/documents/policysimulator.v1beta1.json,sha256=Q1ufGYQSG04J4ufoZ0JH4hgwdeN1QeW1dhREOv-b0Pw,54107
432
+ googleapiclient/discovery_cache/documents/policytroubleshooter.v1.json,sha256=3WWpBNOwDE2E_9qN56IAkB_QoNxbKa656bHHCbmGbB8,31718
433
+ googleapiclient/discovery_cache/documents/policytroubleshooter.v1beta.json,sha256=k5NV64Ld0v4t3sr3ajAP0LfK9-k6OgfaR_AyZxJPQko,30156
434
+ googleapiclient/discovery_cache/documents/pollen.v1.json,sha256=5yHEc8-STvhGa8G0J929bXjT8-YR4aUBN-U0yf4e6NA,21526
435
+ googleapiclient/discovery_cache/documents/poly.v1.json,sha256=MI1zdlmWLLalpCwlx22n33nkszug6pksZb9_1x96K90,27091
436
+ googleapiclient/discovery_cache/documents/privateca.v1.json,sha256=YW6nT_1nPnrEzNFZ1qLDOsMB88Y6dJIJu4qrvgITSD4,148349
437
+ googleapiclient/discovery_cache/documents/privateca.v1beta1.json,sha256=o_tQcn7Z4-Wd2OYB7-Mv1M9vp3MrPhhJfcZAdekivtk,44003
438
+ googleapiclient/discovery_cache/documents/prod_tt_sasportal.v1alpha1.json,sha256=96j345PnT94kQzeYPHlixWSiQk6hQ_AGYkSe7190DEs,100005
439
+ googleapiclient/discovery_cache/documents/publicca.v1.json,sha256=msybmT2yjAQKtsnvMrA37fvWwf6i92SS9zU5RiUMne0,4849
440
+ googleapiclient/discovery_cache/documents/publicca.v1alpha1.json,sha256=lZTujGOmJFdOVOrYFlqse4jJOM85qOAYcV_4WhALNcU,4873
441
+ googleapiclient/discovery_cache/documents/publicca.v1beta1.json,sha256=TamTpQDX3VRyn6vt6k89HyKLcMSf9UaI8pebzVqpWSw,4869
442
+ googleapiclient/discovery_cache/documents/pubsub.v1.json,sha256=8zk_pUWPdiaV4SRdWuBkVDkez52vGz8ihnYoJhFgO7U,129095
443
+ googleapiclient/discovery_cache/documents/pubsub.v1beta1a.json,sha256=BANlfJnV40qmdfOkDwirxdhSc11PDRjaeV7lh2QsBuQ,26028
444
+ googleapiclient/discovery_cache/documents/pubsub.v1beta2.json,sha256=3Y211hPblsfNRtfZ1J1PhPJy3sn5y_knPVAaxndVWPU,51138
445
+ googleapiclient/discovery_cache/documents/pubsublite.v1.json,sha256=WMbpgrapU3kLiHERlUxjwYWKRYbm5FRYPQd4j514NI4,53052
446
+ googleapiclient/discovery_cache/documents/rapidmigrationassessment.v1.json,sha256=oXVbBsMiTzrqLdbiKEMlLcQCJprBDtgAgESkZmO2EVI,32481
447
+ googleapiclient/discovery_cache/documents/readerrevenuesubscriptionlinking.v1.json,sha256=JOu8DhlAMWpRZ5g8I56l7bdSkxgoj4oIb-JBxAk_rLs,8706
448
+ googleapiclient/discovery_cache/documents/realtimebidding.v1.json,sha256=xQOSp1oYf1siTtqt6bqK4DhO_hSAYo2W_ne-fS-aays,118354
449
+ googleapiclient/discovery_cache/documents/realtimebidding.v1alpha.json,sha256=0aZYwk8L6hmk_xVK_rr4BwT4FPEn56oiZWKVqin92rs,18365
450
+ googleapiclient/discovery_cache/documents/recaptchaenterprise.v1.json,sha256=tQVYiks1RnSQAqbqVqWBGCdQDAdPa5ue7cZfQjI75YY,94614
451
+ googleapiclient/discovery_cache/documents/recommendationengine.v1beta1.json,sha256=k0aW98mk8r7nsXNx8-yE_x0AIfu9uBMvo2XE14KkfeI,87898
452
+ googleapiclient/discovery_cache/documents/recommender.v1.json,sha256=opxLJE3suZOJxlGLWEBWJCNdYVb2WAXiuuo5L42bHyE,98951
453
+ googleapiclient/discovery_cache/documents/recommender.v1beta1.json,sha256=Omjt4eqkiA3MB0WwSQvD7NL_57N7_MXpff4xe6yC37o,110537
454
+ googleapiclient/discovery_cache/documents/redis.v1.json,sha256=4BhewN8TBYeuSjePP4A0ppigvttIBDqaGUUaD3Ne2Gc,157176
455
+ googleapiclient/discovery_cache/documents/redis.v1beta1.json,sha256=5KpLwVhBRYTo7OaPpdQLFWwDDATdQzbsVCpNbYyR32k,158083
456
+ googleapiclient/discovery_cache/documents/remotebuildexecution.v1.json,sha256=7GFLt5IiI_-OYe68YsVR99EYWAZbRDdQ7MBSu2yU8n4,117609
457
+ googleapiclient/discovery_cache/documents/remotebuildexecution.v1alpha.json,sha256=hSDoD01FhwXYIVbrOwSe7cLI19DoN1AwZm4ylBQzTgU,124864
458
+ googleapiclient/discovery_cache/documents/remotebuildexecution.v2.json,sha256=EII61EfJ8sqYPcx-Ilk5j-XosxGTIfrN48mLKLkGfnQ,148991
459
+ googleapiclient/discovery_cache/documents/reseller.v1.json,sha256=MMZDdYWwbKSR_7hjA60PCGweytxQc56EQN_NvbnppY4,48941
460
+ googleapiclient/discovery_cache/documents/resourcesettings.v1.json,sha256=PBtggh9NeN9JMcNY29fETTCUnggc6vP3cjwFXEEp_jo,22442
461
+ googleapiclient/discovery_cache/documents/retail.v2.json,sha256=ZIdkcGX2uTlxPIBeoCPsbo3vtE6oCtInqgONyoXGQC8,370710
462
+ googleapiclient/discovery_cache/documents/retail.v2alpha.json,sha256=S0CMVwtILr7SEGyDdpATQWMDHcK74asP6cBLVgs9nfw,416459
463
+ googleapiclient/discovery_cache/documents/retail.v2beta.json,sha256=LRww4zTaZ1xldSIQZyTn9gB1E5lrNhf4_EQs-jvMeo0,389764
464
+ googleapiclient/discovery_cache/documents/run.v1.json,sha256=8vCM3Mi7NK_Xw8s8z4Garmaqj7Jy9nlACS_3v3CdWIs,237881
465
+ googleapiclient/discovery_cache/documents/run.v1alpha1.json,sha256=Z0H_iXudGt7JDmcS4XZx09xCSBXPBv9MCktQqrAiayA,69965
466
+ googleapiclient/discovery_cache/documents/run.v1beta1.json,sha256=huF9CDeN1HdW5tai_neIoAPtXOqg1t_KxstLag14WiE,40411
467
+ googleapiclient/discovery_cache/documents/run.v2.json,sha256=H9yvAUFlq_dWaX8mrpXSh5norKubufyC9rn-ID7_jaI,222990
468
+ googleapiclient/discovery_cache/documents/runtimeconfig.v1.json,sha256=a9eko6S6zJLWmkOlnqRstqEfiRhdFG2KKWgrFmk2NCY,10289
469
+ googleapiclient/discovery_cache/documents/runtimeconfig.v1beta1.json,sha256=U-Eglt6hR7I2J8zmVDlWhGK3R2gs1Iy4SRZ25Z9TmD8,55381
470
+ googleapiclient/discovery_cache/documents/safebrowsing.v4.json,sha256=swfVWEKVKLtGSoSNbRdA0LdXy48qohgK8Pnwf6yiIjE,38346
471
+ googleapiclient/discovery_cache/documents/safebrowsing.v5.json,sha256=3oJ7cp9dBRijO_NtBpVIsfppwxMmm-L11zmWH3EQUP4,9639
472
+ googleapiclient/discovery_cache/documents/sasportal.v1alpha1.json,sha256=MYsQcG35bK_r5XtPy_fGHq9fhWGRDCbfyftXSDP9K8c,99260
473
+ googleapiclient/discovery_cache/documents/script.v1.json,sha256=APh7dOahCmuIJ2Qoua-EeljIP_bYn6_rsYMEfu1fOjg,52104
474
+ googleapiclient/discovery_cache/documents/searchads360.v0.json,sha256=E6KQAKDpfsQH7li9ePnpxlMobCigsKnuUPfgSA_UVyI,330024
475
+ googleapiclient/discovery_cache/documents/searchconsole.v1.json,sha256=z80bL4ZefQey12t3kF3j2anRBcO3Ni2-Z88iinj9u2I,40054
476
+ googleapiclient/discovery_cache/documents/secretmanager.v1.json,sha256=4j_TOKcHQDFzRm6pVB1WQ4pzd2_Qhk87JNwWCwpVnYw,73570
477
+ googleapiclient/discovery_cache/documents/secretmanager.v1beta1.json,sha256=PVzAlxt5L-DebguBrG-d1VkLoRiwhzGAYWN8-lwCNgg,45391
478
+ googleapiclient/discovery_cache/documents/secretmanager.v1beta2.json,sha256=4_t6eRqdq-SnmwOGqHueUI-af1EchWfXdt1gd70xzrE,73896
479
+ googleapiclient/discovery_cache/documents/securitycenter.v1.json,sha256=wd5rPSf5ZMYhOmPCv3zTTsqKTaroZSTtZeRs8tkk8oI,574113
480
+ googleapiclient/discovery_cache/documents/securitycenter.v1beta1.json,sha256=em6-3a31x6-z_dTB47PBaAUdpYe3R95o_qTCT34smu0,332322
481
+ googleapiclient/discovery_cache/documents/securitycenter.v1beta2.json,sha256=V_Xijbcu3mcGaeVlIM6EzFCIWQ26Yj79ulGpLzRzccM,355154
482
+ googleapiclient/discovery_cache/documents/securityposture.v1.json,sha256=zgsy-R2KfQLxl6qocgr1Mv_T9iALdMSvdHk7ewz0QbU,71185
483
+ googleapiclient/discovery_cache/documents/serviceconsumermanagement.v1.json,sha256=TIUPq5N4g6h1iU_CcqpitaLFdQe88aKdoobGW5me6mg,159824
484
+ googleapiclient/discovery_cache/documents/serviceconsumermanagement.v1beta1.json,sha256=oucIio6BLajJAs64ywZdY2tvfhZuA3w9pYlg4GwAcq4,167066
485
+ googleapiclient/discovery_cache/documents/servicecontrol.v1.json,sha256=53tpnS6Tolt6xpA_Q4HjT4fLJjDb_DZNjlswBMc8YRE,98114
486
+ googleapiclient/discovery_cache/documents/servicecontrol.v2.json,sha256=ZNfLbE1Z7gIXMT3jojuGVedXslqQBVE7P6Lzm2se75g,54704
487
+ googleapiclient/discovery_cache/documents/servicedirectory.v1.json,sha256=5MQZHzsxFcgQU4ShBy_KujENFAFlWwsrCMicG5ZHUvw,54213
488
+ googleapiclient/discovery_cache/documents/servicedirectory.v1beta1.json,sha256=PhEcmkAf-CJYxUVRHzQDX64pN8YnTDzfUpe8dVotZPY,58715
489
+ googleapiclient/discovery_cache/documents/servicemanagement.v1.json,sha256=pqdWtW3MyJsXLaclbJoZ06qY8t5X_nrY2R6dF7OgVjg,180450
490
+ googleapiclient/discovery_cache/documents/servicenetworking.v1.json,sha256=udmxaNtHh9S8EmBxIkSz_SNSiDqswh-hMgrZeEEH_T8,194523
491
+ googleapiclient/discovery_cache/documents/servicenetworking.v1beta.json,sha256=IkpBsVi9PUGCQRtwz9eEex7SROOXM1MwaJUXIWVJUOw,147234
492
+ googleapiclient/discovery_cache/documents/serviceusage.v1.json,sha256=KNqeYY9mGch3iimfRU2HLOfSfx-OMGqJydXyzD6yONI,165913
493
+ googleapiclient/discovery_cache/documents/serviceusage.v1beta1.json,sha256=dEe1yToSlvKH9OLcUPHsySZwvSs9lJdn5KusSJriYaw,203511
494
+ googleapiclient/discovery_cache/documents/sheets.v4.json,sha256=cnLmZD2F-H2KmcUKsvb0iPwZWtV6Nz1KGcsp1g8wb0s,290122
495
+ googleapiclient/discovery_cache/documents/siteVerification.v1.json,sha256=xvq_xsL575_6zsUckW9eo-jWWdxW6Ng13g8ohB2uGLA,8419
496
+ googleapiclient/discovery_cache/documents/slides.v1.json,sha256=zJid0TPXb1gvEe8QX6RihzxQqaXLsxCMKjbBPjQiuOQ,184797
497
+ googleapiclient/discovery_cache/documents/smartdevicemanagement.v1.json,sha256=VRNJs4ILczG5VbEi7-_jw3YjEkzGG78gRfeTwHHkUvM,12914
498
+ googleapiclient/discovery_cache/documents/solar.v1.json,sha256=5yZ2rtmNcSGdq7R5TVBjQa5aENgGquWgty-wkdf5K5U,37771
499
+ googleapiclient/discovery_cache/documents/sourcerepo.v1.json,sha256=PpTvPOAbVUYvw7py9gMn6bT_zn01aR939Fj9WvoSoTM,38672
500
+ googleapiclient/discovery_cache/documents/spanner.v1.json,sha256=n5L7-KO2EvZqrjsIhJYcuhF8yZg5ystmyjlJ1A6r_k0,354544
501
+ googleapiclient/discovery_cache/documents/speech.v1.json,sha256=GGEKtQoIBpaSPC5aUoJ2ITnTKiz6pdQDynndl3t5xvQ,64012
502
+ googleapiclient/discovery_cache/documents/speech.v1p1beta1.json,sha256=DRXTB7k62NiHvh0Ba2x1DZKAot2Hs6svqTAuKtOhVEU,65166
503
+ googleapiclient/discovery_cache/documents/speech.v2beta1.json,sha256=uKUcKcn6zNl_egbyhzSYNTlr_o2tpGelQ0WctfRAU54,18493
504
+ googleapiclient/discovery_cache/documents/sqladmin.v1.json,sha256=denBcqpJWyWNSQRIJB0CjHCx8RZW1yqpPS3fNyBKJo8,202735
505
+ googleapiclient/discovery_cache/documents/sqladmin.v1beta4.json,sha256=Ff-V3MDed7-gG8cGiujozC1706lbvq9E8XLHqBbmOqM,203992
506
+ googleapiclient/discovery_cache/documents/storage.v1.json,sha256=2cHmcdOMLDaBE70IJdLPshboKARsCMxizBvB5x1m2Mk,192296
507
+ googleapiclient/discovery_cache/documents/storagetransfer.v1.json,sha256=7ia7DoUsn5RPGGPoDpssg-zxVbDOJBIaFpo_ns37djw,82953
508
+ googleapiclient/discovery_cache/documents/streetviewpublish.v1.json,sha256=6yewpIR1whuQeotQcU0Z5FM9nNBtK4KxCT2nE6ihTz0,48408
509
+ googleapiclient/discovery_cache/documents/sts.v1.json,sha256=a6srJyiBGAygRjlDo4DYFBkfmbYetBzMZPEcGlgcvl8,27412
510
+ googleapiclient/discovery_cache/documents/sts.v1beta.json,sha256=ehLhFjz7BpJx-iMbsbVp2uZ8ai7L55buvDelF5xHCP4,26039
511
+ googleapiclient/discovery_cache/documents/tagmanager.v1.json,sha256=9u8cRaa2VO73YcijZyb32qCs5dSqz5pgaKCjk7aaFJQ,90841
512
+ googleapiclient/discovery_cache/documents/tagmanager.v2.json,sha256=9J9qOoc1aNsGoKJN5vxK5VSnll5zAv3g4_bLfJXFHuY,182143
513
+ googleapiclient/discovery_cache/documents/tasks.v1.json,sha256=QwUv_qhAMaNuPGrm_2PRb_64eqMeYD6jxwcYqS3_m1E,23350
514
+ googleapiclient/discovery_cache/documents/testing.v1.json,sha256=ErfSznw1TuhDGknp5PpvGU0dlohFtSZL1NrvV6V2hYE,96517
515
+ googleapiclient/discovery_cache/documents/texttospeech.v1.json,sha256=iiSSItIP3Bv8enBtFz5H1lKQQUouEqd079_zC6M_qMI,28320
516
+ googleapiclient/discovery_cache/documents/texttospeech.v1beta1.json,sha256=Hp9IgnoLIe9FKePOjSaZmlg7TlPSSdFfGhDtuDhqPGg,27159
517
+ googleapiclient/discovery_cache/documents/toolresults.v1beta3.json,sha256=aqB8d2Kyf1og8vOrKeqefs7FyViD8R312S-_j9dFpAw,129572
518
+ googleapiclient/discovery_cache/documents/tpu.v1.json,sha256=igugYiMzWlYHyIf_RrAsSWSewSPU6RlX8qorT0gu6ig,32177
519
+ googleapiclient/discovery_cache/documents/tpu.v1alpha1.json,sha256=h70ROvpgj-SJ2bx_8kubK7xTIBkx7IW-Td-WA2Im3Jw,32592
520
+ googleapiclient/discovery_cache/documents/tpu.v2.json,sha256=xuLZjr0GZBd-cS7C7wJ8MlzouYV8Kyt3ZFWDW-KlbIE,55790
521
+ googleapiclient/discovery_cache/documents/tpu.v2alpha1.json,sha256=zwh2sg5b1SCYRlPNWswxBF1x8CyAkxm8YOD5hz_epXI,65788
522
+ googleapiclient/discovery_cache/documents/trafficdirector.v2.json,sha256=Mwr5Rl2tgkRXEwvkVxuYeYBMR1TlkznDoMZvp4TobFQ,32631
523
+ googleapiclient/discovery_cache/documents/trafficdirector.v3.json,sha256=XEqVGLMARZhwrhcJgkbaht9RXTxFch6OspyqggWJZNg,49583
524
+ googleapiclient/discovery_cache/documents/transcoder.v1.json,sha256=exIC2RnxSzTHHPhw_hOpsdv8ttiBQKiRys2ZfF7q4xA,68230
525
+ googleapiclient/discovery_cache/documents/transcoder.v1beta1.json,sha256=nj-9u_qqRm_1H3tlaTpWZ2AEkXlgI6uIzwTqj7DZQYg,60514
526
+ googleapiclient/discovery_cache/documents/translate.v2.json,sha256=uIVhWVyniBow5R6_BxTdei59xpeUcu2hPy_fLyX8Jig,11984
527
+ googleapiclient/discovery_cache/documents/translate.v3.json,sha256=HrtBCxOpNG7Hri8Lfujl8wbLiB6QqObKW9I5pAw7Eaw,119552
528
+ googleapiclient/discovery_cache/documents/translate.v3beta1.json,sha256=aasVPL7Ane3L5JyALevOO-QaOx1gxQ-yFV7klIXf8sU,68811
529
+ googleapiclient/discovery_cache/documents/travelimpactmodel.v1.json,sha256=eDKYeRQqM2TzYd6p5wtwmApjKvJxBBmcsC_YFSxfhNY,9794
530
+ googleapiclient/discovery_cache/documents/vault.v1.json,sha256=1SkrgZdLQzz1GPlHNTBK0r1j5yIeXZ_821BasBvKzgQ,74876
531
+ googleapiclient/discovery_cache/documents/vectortile.v1.json,sha256=ox05W0ZLG7Yn-6uUQOP3yeXgibQfaQ6tqA6iv865DQg,47652
532
+ googleapiclient/discovery_cache/documents/verifiedaccess.v1.json,sha256=ZkV9tEhH50MT-olunVV3JgrrUGBAOEjvqGlYD4bEaOg,6762
533
+ googleapiclient/discovery_cache/documents/verifiedaccess.v2.json,sha256=s6ul_w8_t_hWmapmY9HTbfOqobscqQgFDXLfgKkyFNY,17399
534
+ googleapiclient/discovery_cache/documents/versionhistory.v1.json,sha256=BwYMLgoRxklbjB4vPgJAmVcxeuFcfxuNqmU2UpzwFaI,17208
535
+ googleapiclient/discovery_cache/documents/videointelligence.v1.json,sha256=bS5RJTw0RmnzN_959Lcswnr1EkBjZKFyJr6D3PkCouU,177769
536
+ googleapiclient/discovery_cache/documents/videointelligence.v1beta2.json,sha256=VXXJIfS-HTi3NerPmbwo8PG8AxyG34eQkNu4SDs6NGw,169935
537
+ googleapiclient/discovery_cache/documents/videointelligence.v1p1beta1.json,sha256=5NmWrlOSASJCUOxHjg2PdMNt74ZK6o3oF4P9HtbJE4M,170011
538
+ googleapiclient/discovery_cache/documents/videointelligence.v1p2beta1.json,sha256=su-l5Hevu5penBXa4CjRjekw3PrQaEhkhahC3IveJRk,170011
539
+ googleapiclient/discovery_cache/documents/videointelligence.v1p3beta1.json,sha256=NdbSeRYC9drqIMZ-ksNv-_n5sR7bHvYeaUTCJswhJ4o,170062
540
+ googleapiclient/discovery_cache/documents/vision.v1.json,sha256=h4oQU338yEcP8F9Ux5L9GRuUklohw0-BwS_nrzxbeLI,313435
541
+ googleapiclient/discovery_cache/documents/vision.v1p1beta1.json,sha256=WLUhg3ah5PTFA_cV0gc1tuVy_mcwhTE7muurC0mKHeM,278159
542
+ googleapiclient/discovery_cache/documents/vision.v1p2beta1.json,sha256=FRMYZPzEEih3EmJB48C0S0BaWaF8qy2JRvG58QC2gt8,278159
543
+ googleapiclient/discovery_cache/documents/vmmigration.v1.json,sha256=6Szpeh1WgqwJ-Cq2hwq1bNfGGLJeVidOpGt2AHNG8cQ,186747
544
+ googleapiclient/discovery_cache/documents/vmmigration.v1alpha1.json,sha256=LAJYXqVxGkmMJo-1EMmX9UsHSWJ3PWFqg2_YXHBXqFA,194350
545
+ googleapiclient/discovery_cache/documents/vmwareengine.v1.json,sha256=A53DnykSnFlSWRcsgrOfJ50htMLYiM4pKjwR_V_qy4w,256218
546
+ googleapiclient/discovery_cache/documents/vpcaccess.v1.json,sha256=7qrUllrWKdu7F0H1JpVsr2eYCQEul_w3PW_ECPnFzrA,21178
547
+ googleapiclient/discovery_cache/documents/vpcaccess.v1beta1.json,sha256=r3FqAwy19cLLhb8Hkp7FiLIVpH0syQt7oUUX4TM7CcU,21577
548
+ googleapiclient/discovery_cache/documents/walletobjects.v1.json,sha256=1CDFgjzSC4SlYakgTY5AM0ZgPCkIqK7vgSnDncUT7kA,352754
549
+ googleapiclient/discovery_cache/documents/webfonts.v1.json,sha256=2rRNnUYk-ciNDxKVHxdZ0oDav0fJK9weyEZuxy895SM,6307
550
+ googleapiclient/discovery_cache/documents/webmasters.v3.json,sha256=TOTCcpZyUk-dbmnjFVFoQam0hq2wFQg2UV9x-4fuVLY,20097
551
+ googleapiclient/discovery_cache/documents/webrisk.v1.json,sha256=so8K_q7m91psDyyd3aZ_7fKz3CqxLChoz2_El0Pbaig,26588
552
+ googleapiclient/discovery_cache/documents/websecurityscanner.v1.json,sha256=l7GYs5aNeyH3_bUuVGdUWxFHfk49VIKcXLl7kRJkZEI,44164
553
+ googleapiclient/discovery_cache/documents/websecurityscanner.v1alpha.json,sha256=QDkWVUfvc0d8Bw95U-_IKqyD3aJ1xXcIcsun53gHdaU,36660
554
+ googleapiclient/discovery_cache/documents/websecurityscanner.v1beta.json,sha256=Cy-vHk51aVECUYd1QFrnow39K0KwVF_RVD9qPdUS9l8,42878
555
+ googleapiclient/discovery_cache/documents/workflowexecutions.v1.json,sha256=MePGvzvFlN5rjJgBIvRwERWUOXhBtENYO_mR8Er-7eA,39209
556
+ googleapiclient/discovery_cache/documents/workflowexecutions.v1beta.json,sha256=tERDKKmiGTK-l3wOrCAhVaA1SjA9d2Wp2fcbqaScb4E,14318
557
+ googleapiclient/discovery_cache/documents/workflows.v1.json,sha256=CAw0DCnGVvqZL6PzCfQ5j3Zs_0O5nClVjmsOReI1jgM,28611
558
+ googleapiclient/discovery_cache/documents/workflows.v1beta.json,sha256=uzRGy5XU0VF1X9yjB5cVgfnnUDAOWrSoNYIvdAeYHsk,22461
559
+ googleapiclient/discovery_cache/documents/workloadmanager.v1.json,sha256=DgV3tXKBcX-wECgZ7s0svBuWNIlVh3VqsnYl3qpROc8,67964
560
+ googleapiclient/discovery_cache/documents/workspaceevents.v1.json,sha256=xyHj_UBJyQrs7Soj4IqyvOq5OsqQlWHMuXSS2pk1btA,30827
561
+ googleapiclient/discovery_cache/documents/workstations.v1.json,sha256=IXjqVydLESbVTMBE5f5_Ic4nxLb4ch2gctD8l3yXnWY,104610
562
+ googleapiclient/discovery_cache/documents/workstations.v1beta.json,sha256=XWSL6Hd1rZV3GnqUw2ME0WBH16jQSZN_DkCnMnn7jC4,104108
563
+ googleapiclient/discovery_cache/documents/youtube.v3.json,sha256=W0gQY8maCA1W8mYW6aTa3mFEYT_oDLT_ty9LgLvB8S0,372790
564
+ googleapiclient/discovery_cache/documents/youtubeAnalytics.v1.json,sha256=KLPoKHO_XT4-LyIZjwSGh44f_htMwjePD2PXR8MH-YY,3220
565
+ googleapiclient/discovery_cache/documents/youtubeAnalytics.v2.json,sha256=Ixl98t7bVU4LpG2rai6RgzSeW-TUmk4abOVGzzttGKQ,28888
566
+ googleapiclient/discovery_cache/documents/youtubereporting.v1.json,sha256=fez-pYUk5gzTFG4W4mPJ7crQV1F1msk1Zdxf2DzpLl0,23094
567
+ googleapiclient/discovery_cache/file_cache.py,sha256=sim3Mg4HgRYo3vX75jvcKy_aV568EvIrtBfvfbw-044,4774
568
+ googleapiclient/errors.py,sha256=9h3uimcMcczBHZJFWAX_YDABzJeJugWB0jmj11rp-LI,5460
569
+ googleapiclient/http.py,sha256=ITE51oqDBqN1-AA5D-Tnlj3egGc_5O0V5xSzBw3UTKI,68241
570
+ googleapiclient/mimeparse.py,sha256=wwouQMCjppTocJtiQhkkTa27kocYwlFRALL2z11Xo1Y,6530
571
+ googleapiclient/model.py,sha256=NQDO1GhOGNVCJlSSCLOecdA11yf8RDXfSLFxYb3R7EE,14085
572
+ googleapiclient/sample_tools.py,sha256=hDBLJNwLluN6AGhaBR-3GXWDrOwRNPvXyseLOyz9l30,4315
573
+ googleapiclient/schema.py,sha256=rR3u8WPQ_V8a7GCUsNuvtf6GxzwuMO0HaqsTBp3tnyM,10414
574
+ googleapiclient/version.py,sha256=i41lsW2z1sl9n_bGRT7un47ma9dWmwY4ESL1bEHiHmI,599
.venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/WHEEL ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.3.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py2-none-any
5
+ Tag: py3-none-any
6
+
.venv/lib/python3.11/site-packages/google_api_python_client-2.159.0.dist-info/top_level.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ apiclient
2
+ googleapiclient
3
+ googleapiclient/discovery_cache
.venv/lib/python3.11/site-packages/networkx/__init__.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ NetworkX
3
+ ========
4
+
5
+ NetworkX is a Python package for the creation, manipulation, and study of the
6
+ structure, dynamics, and functions of complex networks.
7
+
8
+ See https://networkx.org for complete documentation.
9
+ """
10
+
11
+ __version__ = "3.4.2"
12
+
13
+
14
+ # These are imported in order as listed
15
+ from networkx.lazy_imports import _lazy_import
16
+
17
+ from networkx.exception import *
18
+
19
+ from networkx import utils
20
+ from networkx.utils import _clear_cache, _dispatchable
21
+
22
+ # load_and_call entry_points, set configs
23
+ config = utils.backends._set_configs_from_environment()
24
+ utils.config = utils.configs.config = config # type: ignore[attr-defined]
25
+
26
+ from networkx import classes
27
+ from networkx.classes import filters
28
+ from networkx.classes import *
29
+
30
+ from networkx import convert
31
+ from networkx.convert import *
32
+
33
+ from networkx import convert_matrix
34
+ from networkx.convert_matrix import *
35
+
36
+ from networkx import relabel
37
+ from networkx.relabel import *
38
+
39
+ from networkx import generators
40
+ from networkx.generators import *
41
+
42
+ from networkx import readwrite
43
+ from networkx.readwrite import *
44
+
45
+ # Need to test with SciPy, when available
46
+ from networkx import algorithms
47
+ from networkx.algorithms import *
48
+
49
+ from networkx import linalg
50
+ from networkx.linalg import *
51
+
52
+ from networkx import drawing
53
+ from networkx.drawing import *
.venv/lib/python3.11/site-packages/networkx/convert.py ADDED
@@ -0,0 +1,502 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Functions to convert NetworkX graphs to and from other formats.
2
+
3
+ The preferred way of converting data to a NetworkX graph is through the
4
+ graph constructor. The constructor calls the to_networkx_graph() function
5
+ which attempts to guess the input type and convert it automatically.
6
+
7
+ Examples
8
+ --------
9
+ Create a graph with a single edge from a dictionary of dictionaries
10
+
11
+ >>> d = {0: {1: 1}} # dict-of-dicts single edge (0,1)
12
+ >>> G = nx.Graph(d)
13
+
14
+ See Also
15
+ --------
16
+ nx_agraph, nx_pydot
17
+ """
18
+
19
+ import warnings
20
+ from collections.abc import Collection, Generator, Iterator
21
+
22
+ import networkx as nx
23
+
24
+ __all__ = [
25
+ "to_networkx_graph",
26
+ "from_dict_of_dicts",
27
+ "to_dict_of_dicts",
28
+ "from_dict_of_lists",
29
+ "to_dict_of_lists",
30
+ "from_edgelist",
31
+ "to_edgelist",
32
+ ]
33
+
34
+
35
+ def to_networkx_graph(data, create_using=None, multigraph_input=False):
36
+ """Make a NetworkX graph from a known data structure.
37
+
38
+ The preferred way to call this is automatically
39
+ from the class constructor
40
+
41
+ >>> d = {0: {1: {"weight": 1}}} # dict-of-dicts single edge (0,1)
42
+ >>> G = nx.Graph(d)
43
+
44
+ instead of the equivalent
45
+
46
+ >>> G = nx.from_dict_of_dicts(d)
47
+
48
+ Parameters
49
+ ----------
50
+ data : object to be converted
51
+
52
+ Current known types are:
53
+ any NetworkX graph
54
+ dict-of-dicts
55
+ dict-of-lists
56
+ container (e.g. set, list, tuple) of edges
57
+ iterator (e.g. itertools.chain) that produces edges
58
+ generator of edges
59
+ Pandas DataFrame (row per edge)
60
+ 2D numpy array
61
+ scipy sparse array
62
+ pygraphviz agraph
63
+
64
+ create_using : NetworkX graph constructor, optional (default=nx.Graph)
65
+ Graph type to create. If graph instance, then cleared before populated.
66
+
67
+ multigraph_input : bool (default False)
68
+ If True and data is a dict_of_dicts,
69
+ try to create a multigraph assuming dict_of_dict_of_lists.
70
+ If data and create_using are both multigraphs then create
71
+ a multigraph from a multigraph.
72
+
73
+ """
74
+ # NX graph
75
+ if hasattr(data, "adj"):
76
+ try:
77
+ result = from_dict_of_dicts(
78
+ data.adj,
79
+ create_using=create_using,
80
+ multigraph_input=data.is_multigraph(),
81
+ )
82
+ # data.graph should be dict-like
83
+ result.graph.update(data.graph)
84
+ # data.nodes should be dict-like
85
+ # result.add_node_from(data.nodes.items()) possible but
86
+ # for custom node_attr_dict_factory which may be hashable
87
+ # will be unexpected behavior
88
+ for n, dd in data.nodes.items():
89
+ result._node[n].update(dd)
90
+ return result
91
+ except Exception as err:
92
+ raise nx.NetworkXError("Input is not a correct NetworkX graph.") from err
93
+
94
+ # dict of dicts/lists
95
+ if isinstance(data, dict):
96
+ try:
97
+ return from_dict_of_dicts(
98
+ data, create_using=create_using, multigraph_input=multigraph_input
99
+ )
100
+ except Exception as err1:
101
+ if multigraph_input is True:
102
+ raise nx.NetworkXError(
103
+ f"converting multigraph_input raised:\n{type(err1)}: {err1}"
104
+ )
105
+ try:
106
+ return from_dict_of_lists(data, create_using=create_using)
107
+ except Exception as err2:
108
+ raise TypeError("Input is not known type.") from err2
109
+
110
+ # edgelists
111
+ if isinstance(data, list | tuple | nx.reportviews.EdgeViewABC | Iterator):
112
+ try:
113
+ return from_edgelist(data, create_using=create_using)
114
+ except:
115
+ pass
116
+
117
+ # pygraphviz agraph
118
+ if hasattr(data, "is_strict"):
119
+ try:
120
+ return nx.nx_agraph.from_agraph(data, create_using=create_using)
121
+ except Exception as err:
122
+ raise nx.NetworkXError("Input is not a correct pygraphviz graph.") from err
123
+
124
+ # Pandas DataFrame
125
+ try:
126
+ import pandas as pd
127
+
128
+ if isinstance(data, pd.DataFrame):
129
+ if data.shape[0] == data.shape[1]:
130
+ try:
131
+ return nx.from_pandas_adjacency(data, create_using=create_using)
132
+ except Exception as err:
133
+ msg = "Input is not a correct Pandas DataFrame adjacency matrix."
134
+ raise nx.NetworkXError(msg) from err
135
+ else:
136
+ try:
137
+ return nx.from_pandas_edgelist(
138
+ data, edge_attr=True, create_using=create_using
139
+ )
140
+ except Exception as err:
141
+ msg = "Input is not a correct Pandas DataFrame edge-list."
142
+ raise nx.NetworkXError(msg) from err
143
+ except ImportError:
144
+ pass
145
+
146
+ # numpy array
147
+ try:
148
+ import numpy as np
149
+
150
+ if isinstance(data, np.ndarray):
151
+ try:
152
+ return nx.from_numpy_array(data, create_using=create_using)
153
+ except Exception as err:
154
+ raise nx.NetworkXError(
155
+ f"Failed to interpret array as an adjacency matrix."
156
+ ) from err
157
+ except ImportError:
158
+ pass
159
+
160
+ # scipy sparse array - any format
161
+ try:
162
+ import scipy
163
+
164
+ if hasattr(data, "format"):
165
+ try:
166
+ return nx.from_scipy_sparse_array(data, create_using=create_using)
167
+ except Exception as err:
168
+ raise nx.NetworkXError(
169
+ "Input is not a correct scipy sparse array type."
170
+ ) from err
171
+ except ImportError:
172
+ pass
173
+
174
+ # Note: most general check - should remain last in order of execution
175
+ # Includes containers (e.g. list, set, dict, etc.), generators, and
176
+ # iterators (e.g. itertools.chain) of edges
177
+
178
+ if isinstance(data, Collection | Generator | Iterator):
179
+ try:
180
+ return from_edgelist(data, create_using=create_using)
181
+ except Exception as err:
182
+ raise nx.NetworkXError("Input is not a valid edge list") from err
183
+
184
+ raise nx.NetworkXError("Input is not a known data type for conversion.")
185
+
186
+
187
+ @nx._dispatchable
188
+ def to_dict_of_lists(G, nodelist=None):
189
+ """Returns adjacency representation of graph as a dictionary of lists.
190
+
191
+ Parameters
192
+ ----------
193
+ G : graph
194
+ A NetworkX graph
195
+
196
+ nodelist : list
197
+ Use only nodes specified in nodelist
198
+
199
+ Notes
200
+ -----
201
+ Completely ignores edge data for MultiGraph and MultiDiGraph.
202
+
203
+ """
204
+ if nodelist is None:
205
+ nodelist = G
206
+
207
+ d = {}
208
+ for n in nodelist:
209
+ d[n] = [nbr for nbr in G.neighbors(n) if nbr in nodelist]
210
+ return d
211
+
212
+
213
+ @nx._dispatchable(graphs=None, returns_graph=True)
214
+ def from_dict_of_lists(d, create_using=None):
215
+ """Returns a graph from a dictionary of lists.
216
+
217
+ Parameters
218
+ ----------
219
+ d : dictionary of lists
220
+ A dictionary of lists adjacency representation.
221
+
222
+ create_using : NetworkX graph constructor, optional (default=nx.Graph)
223
+ Graph type to create. If graph instance, then cleared before populated.
224
+
225
+ Examples
226
+ --------
227
+ >>> dol = {0: [1]} # single edge (0,1)
228
+ >>> G = nx.from_dict_of_lists(dol)
229
+
230
+ or
231
+
232
+ >>> G = nx.Graph(dol) # use Graph constructor
233
+
234
+ """
235
+ G = nx.empty_graph(0, create_using)
236
+ G.add_nodes_from(d)
237
+ if G.is_multigraph() and not G.is_directed():
238
+ # a dict_of_lists can't show multiedges. BUT for undirected graphs,
239
+ # each edge shows up twice in the dict_of_lists.
240
+ # So we need to treat this case separately.
241
+ seen = {}
242
+ for node, nbrlist in d.items():
243
+ for nbr in nbrlist:
244
+ if nbr not in seen:
245
+ G.add_edge(node, nbr)
246
+ seen[node] = 1 # don't allow reverse edge to show up
247
+ else:
248
+ G.add_edges_from(
249
+ ((node, nbr) for node, nbrlist in d.items() for nbr in nbrlist)
250
+ )
251
+ return G
252
+
253
+
254
+ def to_dict_of_dicts(G, nodelist=None, edge_data=None):
255
+ """Returns adjacency representation of graph as a dictionary of dictionaries.
256
+
257
+ Parameters
258
+ ----------
259
+ G : graph
260
+ A NetworkX graph
261
+
262
+ nodelist : list
263
+ Use only nodes specified in nodelist
264
+
265
+ edge_data : scalar, optional
266
+ If provided, the value of the dictionary will be set to `edge_data` for
267
+ all edges. Usual values could be `1` or `True`. If `edge_data` is
268
+ `None` (the default), the edgedata in `G` is used, resulting in a
269
+ dict-of-dict-of-dicts. If `G` is a MultiGraph, the result will be a
270
+ dict-of-dict-of-dict-of-dicts. See Notes for an approach to customize
271
+ handling edge data. `edge_data` should *not* be a container.
272
+
273
+ Returns
274
+ -------
275
+ dod : dict
276
+ A nested dictionary representation of `G`. Note that the level of
277
+ nesting depends on the type of `G` and the value of `edge_data`
278
+ (see Examples).
279
+
280
+ See Also
281
+ --------
282
+ from_dict_of_dicts, to_dict_of_lists
283
+
284
+ Notes
285
+ -----
286
+ For a more custom approach to handling edge data, try::
287
+
288
+ dod = {
289
+ n: {nbr: custom(n, nbr, dd) for nbr, dd in nbrdict.items()}
290
+ for n, nbrdict in G.adj.items()
291
+ }
292
+
293
+ where `custom` returns the desired edge data for each edge between `n` and
294
+ `nbr`, given existing edge data `dd`.
295
+
296
+ Examples
297
+ --------
298
+ >>> G = nx.path_graph(3)
299
+ >>> nx.to_dict_of_dicts(G)
300
+ {0: {1: {}}, 1: {0: {}, 2: {}}, 2: {1: {}}}
301
+
302
+ Edge data is preserved by default (``edge_data=None``), resulting
303
+ in dict-of-dict-of-dicts where the innermost dictionary contains the
304
+ edge data:
305
+
306
+ >>> G = nx.Graph()
307
+ >>> G.add_edges_from(
308
+ ... [
309
+ ... (0, 1, {"weight": 1.0}),
310
+ ... (1, 2, {"weight": 2.0}),
311
+ ... (2, 0, {"weight": 1.0}),
312
+ ... ]
313
+ ... )
314
+ >>> d = nx.to_dict_of_dicts(G)
315
+ >>> d # doctest: +SKIP
316
+ {0: {1: {'weight': 1.0}, 2: {'weight': 1.0}},
317
+ 1: {0: {'weight': 1.0}, 2: {'weight': 2.0}},
318
+ 2: {1: {'weight': 2.0}, 0: {'weight': 1.0}}}
319
+ >>> d[1][2]["weight"]
320
+ 2.0
321
+
322
+ If `edge_data` is not `None`, edge data in the original graph (if any) is
323
+ replaced:
324
+
325
+ >>> d = nx.to_dict_of_dicts(G, edge_data=1)
326
+ >>> d
327
+ {0: {1: 1, 2: 1}, 1: {0: 1, 2: 1}, 2: {1: 1, 0: 1}}
328
+ >>> d[1][2]
329
+ 1
330
+
331
+ This also applies to MultiGraphs: edge data is preserved by default:
332
+
333
+ >>> G = nx.MultiGraph()
334
+ >>> G.add_edge(0, 1, key="a", weight=1.0)
335
+ 'a'
336
+ >>> G.add_edge(0, 1, key="b", weight=5.0)
337
+ 'b'
338
+ >>> d = nx.to_dict_of_dicts(G)
339
+ >>> d # doctest: +SKIP
340
+ {0: {1: {'a': {'weight': 1.0}, 'b': {'weight': 5.0}}},
341
+ 1: {0: {'a': {'weight': 1.0}, 'b': {'weight': 5.0}}}}
342
+ >>> d[0][1]["b"]["weight"]
343
+ 5.0
344
+
345
+ But multi edge data is lost if `edge_data` is not `None`:
346
+
347
+ >>> d = nx.to_dict_of_dicts(G, edge_data=10)
348
+ >>> d
349
+ {0: {1: 10}, 1: {0: 10}}
350
+ """
351
+ dod = {}
352
+ if nodelist is None:
353
+ if edge_data is None:
354
+ for u, nbrdict in G.adjacency():
355
+ dod[u] = nbrdict.copy()
356
+ else: # edge_data is not None
357
+ for u, nbrdict in G.adjacency():
358
+ dod[u] = dod.fromkeys(nbrdict, edge_data)
359
+ else: # nodelist is not None
360
+ if edge_data is None:
361
+ for u in nodelist:
362
+ dod[u] = {}
363
+ for v, data in ((v, data) for v, data in G[u].items() if v in nodelist):
364
+ dod[u][v] = data
365
+ else: # nodelist and edge_data are not None
366
+ for u in nodelist:
367
+ dod[u] = {}
368
+ for v in (v for v in G[u] if v in nodelist):
369
+ dod[u][v] = edge_data
370
+ return dod
371
+
372
+
373
+ @nx._dispatchable(graphs=None, returns_graph=True)
374
+ def from_dict_of_dicts(d, create_using=None, multigraph_input=False):
375
+ """Returns a graph from a dictionary of dictionaries.
376
+
377
+ Parameters
378
+ ----------
379
+ d : dictionary of dictionaries
380
+ A dictionary of dictionaries adjacency representation.
381
+
382
+ create_using : NetworkX graph constructor, optional (default=nx.Graph)
383
+ Graph type to create. If graph instance, then cleared before populated.
384
+
385
+ multigraph_input : bool (default False)
386
+ When True, the dict `d` is assumed
387
+ to be a dict-of-dict-of-dict-of-dict structure keyed by
388
+ node to neighbor to edge keys to edge data for multi-edges.
389
+ Otherwise this routine assumes dict-of-dict-of-dict keyed by
390
+ node to neighbor to edge data.
391
+
392
+ Examples
393
+ --------
394
+ >>> dod = {0: {1: {"weight": 1}}} # single edge (0,1)
395
+ >>> G = nx.from_dict_of_dicts(dod)
396
+
397
+ or
398
+
399
+ >>> G = nx.Graph(dod) # use Graph constructor
400
+
401
+ """
402
+ G = nx.empty_graph(0, create_using)
403
+ G.add_nodes_from(d)
404
+ # does dict d represent a MultiGraph or MultiDiGraph?
405
+ if multigraph_input:
406
+ if G.is_directed():
407
+ if G.is_multigraph():
408
+ G.add_edges_from(
409
+ (u, v, key, data)
410
+ for u, nbrs in d.items()
411
+ for v, datadict in nbrs.items()
412
+ for key, data in datadict.items()
413
+ )
414
+ else:
415
+ G.add_edges_from(
416
+ (u, v, data)
417
+ for u, nbrs in d.items()
418
+ for v, datadict in nbrs.items()
419
+ for key, data in datadict.items()
420
+ )
421
+ else: # Undirected
422
+ if G.is_multigraph():
423
+ seen = set() # don't add both directions of undirected graph
424
+ for u, nbrs in d.items():
425
+ for v, datadict in nbrs.items():
426
+ if (u, v) not in seen:
427
+ G.add_edges_from(
428
+ (u, v, key, data) for key, data in datadict.items()
429
+ )
430
+ seen.add((v, u))
431
+ else:
432
+ seen = set() # don't add both directions of undirected graph
433
+ for u, nbrs in d.items():
434
+ for v, datadict in nbrs.items():
435
+ if (u, v) not in seen:
436
+ G.add_edges_from(
437
+ (u, v, data) for key, data in datadict.items()
438
+ )
439
+ seen.add((v, u))
440
+
441
+ else: # not a multigraph to multigraph transfer
442
+ if G.is_multigraph() and not G.is_directed():
443
+ # d can have both representations u-v, v-u in dict. Only add one.
444
+ # We don't need this check for digraphs since we add both directions,
445
+ # or for Graph() since it is done implicitly (parallel edges not allowed)
446
+ seen = set()
447
+ for u, nbrs in d.items():
448
+ for v, data in nbrs.items():
449
+ if (u, v) not in seen:
450
+ G.add_edge(u, v, key=0)
451
+ G[u][v][0].update(data)
452
+ seen.add((v, u))
453
+ else:
454
+ G.add_edges_from(
455
+ ((u, v, data) for u, nbrs in d.items() for v, data in nbrs.items())
456
+ )
457
+ return G
458
+
459
+
460
+ @nx._dispatchable(preserve_edge_attrs=True)
461
+ def to_edgelist(G, nodelist=None):
462
+ """Returns a list of edges in the graph.
463
+
464
+ Parameters
465
+ ----------
466
+ G : graph
467
+ A NetworkX graph
468
+
469
+ nodelist : list
470
+ Use only nodes specified in nodelist
471
+
472
+ """
473
+ if nodelist is None:
474
+ return G.edges(data=True)
475
+ return G.edges(nodelist, data=True)
476
+
477
+
478
+ @nx._dispatchable(graphs=None, returns_graph=True)
479
+ def from_edgelist(edgelist, create_using=None):
480
+ """Returns a graph from a list of edges.
481
+
482
+ Parameters
483
+ ----------
484
+ edgelist : list or iterator
485
+ Edge tuples
486
+
487
+ create_using : NetworkX graph constructor, optional (default=nx.Graph)
488
+ Graph type to create. If graph instance, then cleared before populated.
489
+
490
+ Examples
491
+ --------
492
+ >>> edgelist = [(0, 1)] # single edge (0,1)
493
+ >>> G = nx.from_edgelist(edgelist)
494
+
495
+ or
496
+
497
+ >>> G = nx.Graph(edgelist) # use Graph constructor
498
+
499
+ """
500
+ G = nx.empty_graph(0, create_using)
501
+ G.add_edges_from(edgelist)
502
+ return G
.venv/lib/python3.11/site-packages/networkx/exception.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ **********
3
+ Exceptions
4
+ **********
5
+
6
+ Base exceptions and errors for NetworkX.
7
+ """
8
+
9
+ __all__ = [
10
+ "HasACycle",
11
+ "NodeNotFound",
12
+ "PowerIterationFailedConvergence",
13
+ "ExceededMaxIterations",
14
+ "AmbiguousSolution",
15
+ "NetworkXAlgorithmError",
16
+ "NetworkXException",
17
+ "NetworkXError",
18
+ "NetworkXNoCycle",
19
+ "NetworkXNoPath",
20
+ "NetworkXNotImplemented",
21
+ "NetworkXPointlessConcept",
22
+ "NetworkXUnbounded",
23
+ "NetworkXUnfeasible",
24
+ ]
25
+
26
+
27
+ class NetworkXException(Exception):
28
+ """Base class for exceptions in NetworkX."""
29
+
30
+
31
+ class NetworkXError(NetworkXException):
32
+ """Exception for a serious error in NetworkX"""
33
+
34
+
35
+ class NetworkXPointlessConcept(NetworkXException):
36
+ """Raised when a null graph is provided as input to an algorithm
37
+ that cannot use it.
38
+
39
+ The null graph is sometimes considered a pointless concept [1]_,
40
+ thus the name of the exception.
41
+
42
+ Notes
43
+ -----
44
+ Null graphs and empty graphs are often used interchangeably but they
45
+ are well defined in NetworkX. An ``empty_graph`` is a graph with ``n`` nodes
46
+ and 0 edges, and a ``null_graph`` is a graph with 0 nodes and 0 edges.
47
+
48
+ References
49
+ ----------
50
+ .. [1] Harary, F. and Read, R. "Is the Null Graph a Pointless
51
+ Concept?" In Graphs and Combinatorics Conference, George
52
+ Washington University. New York: Springer-Verlag, 1973.
53
+
54
+ """
55
+
56
+
57
+ class NetworkXAlgorithmError(NetworkXException):
58
+ """Exception for unexpected termination of algorithms."""
59
+
60
+
61
+ class NetworkXUnfeasible(NetworkXAlgorithmError):
62
+ """Exception raised by algorithms trying to solve a problem
63
+ instance that has no feasible solution."""
64
+
65
+
66
+ class NetworkXNoPath(NetworkXUnfeasible):
67
+ """Exception for algorithms that should return a path when running
68
+ on graphs where such a path does not exist."""
69
+
70
+
71
+ class NetworkXNoCycle(NetworkXUnfeasible):
72
+ """Exception for algorithms that should return a cycle when running
73
+ on graphs where such a cycle does not exist."""
74
+
75
+
76
+ class HasACycle(NetworkXException):
77
+ """Raised if a graph has a cycle when an algorithm expects that it
78
+ will have no cycles.
79
+
80
+ """
81
+
82
+
83
+ class NetworkXUnbounded(NetworkXAlgorithmError):
84
+ """Exception raised by algorithms trying to solve a maximization
85
+ or a minimization problem instance that is unbounded."""
86
+
87
+
88
+ class NetworkXNotImplemented(NetworkXException):
89
+ """Exception raised by algorithms not implemented for a type of graph."""
90
+
91
+
92
+ class NodeNotFound(NetworkXException):
93
+ """Exception raised if requested node is not present in the graph"""
94
+
95
+
96
+ class AmbiguousSolution(NetworkXException):
97
+ """Raised if more than one valid solution exists for an intermediary step
98
+ of an algorithm.
99
+
100
+ In the face of ambiguity, refuse the temptation to guess.
101
+ This may occur, for example, when trying to determine the
102
+ bipartite node sets in a disconnected bipartite graph when
103
+ computing bipartite matchings.
104
+
105
+ """
106
+
107
+
108
+ class ExceededMaxIterations(NetworkXException):
109
+ """Raised if a loop iterates too many times without breaking.
110
+
111
+ This may occur, for example, in an algorithm that computes
112
+ progressively better approximations to a value but exceeds an
113
+ iteration bound specified by the user.
114
+
115
+ """
116
+
117
+
118
+ class PowerIterationFailedConvergence(ExceededMaxIterations):
119
+ """Raised when the power iteration method fails to converge within a
120
+ specified iteration limit.
121
+
122
+ `num_iterations` is the number of iterations that have been
123
+ completed when this exception was raised.
124
+
125
+ """
126
+
127
+ def __init__(self, num_iterations, *args, **kw):
128
+ msg = f"power iteration failed to converge within {num_iterations} iterations"
129
+ exception_message = msg
130
+ superinit = super().__init__
131
+ superinit(self, exception_message, *args, **kw)
.venv/lib/python3.11/site-packages/networkx/linalg/__init__.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from networkx.linalg.attrmatrix import *
2
+ from networkx.linalg import attrmatrix
3
+ from networkx.linalg.spectrum import *
4
+ from networkx.linalg import spectrum
5
+ from networkx.linalg.graphmatrix import *
6
+ from networkx.linalg import graphmatrix
7
+ from networkx.linalg.laplacianmatrix import *
8
+ from networkx.linalg import laplacianmatrix
9
+ from networkx.linalg.algebraicconnectivity import *
10
+ from networkx.linalg.modularitymatrix import *
11
+ from networkx.linalg import modularitymatrix
12
+ from networkx.linalg.bethehessianmatrix import *
13
+ from networkx.linalg import bethehessianmatrix
.venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (885 Bytes). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/algebraicconnectivity.cpython-311.pyc ADDED
Binary file (30.4 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/attrmatrix.cpython-311.pyc ADDED
Binary file (18.2 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/bethehessianmatrix.cpython-311.pyc ADDED
Binary file (3.96 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/graphmatrix.cpython-311.pyc ADDED
Binary file (6.93 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/laplacianmatrix.cpython-311.pyc ADDED
Binary file (23 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/modularitymatrix.cpython-311.pyc ADDED
Binary file (5.71 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/__pycache__/spectrum.cpython-311.pyc ADDED
Binary file (5.8 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/algebraicconnectivity.py ADDED
@@ -0,0 +1,657 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Algebraic connectivity and Fiedler vectors of undirected graphs.
3
+ """
4
+
5
+ from functools import partial
6
+
7
+ import networkx as nx
8
+ from networkx.utils import (
9
+ not_implemented_for,
10
+ np_random_state,
11
+ reverse_cuthill_mckee_ordering,
12
+ )
13
+
14
+ __all__ = [
15
+ "algebraic_connectivity",
16
+ "fiedler_vector",
17
+ "spectral_ordering",
18
+ "spectral_bisection",
19
+ ]
20
+
21
+
22
+ class _PCGSolver:
23
+ """Preconditioned conjugate gradient method.
24
+
25
+ To solve Ax = b:
26
+ M = A.diagonal() # or some other preconditioner
27
+ solver = _PCGSolver(lambda x: A * x, lambda x: M * x)
28
+ x = solver.solve(b)
29
+
30
+ The inputs A and M are functions which compute
31
+ matrix multiplication on the argument.
32
+ A - multiply by the matrix A in Ax=b
33
+ M - multiply by M, the preconditioner surrogate for A
34
+
35
+ Warning: There is no limit on number of iterations.
36
+ """
37
+
38
+ def __init__(self, A, M):
39
+ self._A = A
40
+ self._M = M
41
+
42
+ def solve(self, B, tol):
43
+ import numpy as np
44
+
45
+ # Densifying step - can this be kept sparse?
46
+ B = np.asarray(B)
47
+ X = np.ndarray(B.shape, order="F")
48
+ for j in range(B.shape[1]):
49
+ X[:, j] = self._solve(B[:, j], tol)
50
+ return X
51
+
52
+ def _solve(self, b, tol):
53
+ import numpy as np
54
+ import scipy as sp
55
+
56
+ A = self._A
57
+ M = self._M
58
+ tol *= sp.linalg.blas.dasum(b)
59
+ # Initialize.
60
+ x = np.zeros(b.shape)
61
+ r = b.copy()
62
+ z = M(r)
63
+ rz = sp.linalg.blas.ddot(r, z)
64
+ p = z.copy()
65
+ # Iterate.
66
+ while True:
67
+ Ap = A(p)
68
+ alpha = rz / sp.linalg.blas.ddot(p, Ap)
69
+ x = sp.linalg.blas.daxpy(p, x, a=alpha)
70
+ r = sp.linalg.blas.daxpy(Ap, r, a=-alpha)
71
+ if sp.linalg.blas.dasum(r) < tol:
72
+ return x
73
+ z = M(r)
74
+ beta = sp.linalg.blas.ddot(r, z)
75
+ beta, rz = beta / rz, beta
76
+ p = sp.linalg.blas.daxpy(p, z, a=beta)
77
+
78
+
79
+ class _LUSolver:
80
+ """LU factorization.
81
+
82
+ To solve Ax = b:
83
+ solver = _LUSolver(A)
84
+ x = solver.solve(b)
85
+
86
+ optional argument `tol` on solve method is ignored but included
87
+ to match _PCGsolver API.
88
+ """
89
+
90
+ def __init__(self, A):
91
+ import scipy as sp
92
+
93
+ self._LU = sp.sparse.linalg.splu(
94
+ A,
95
+ permc_spec="MMD_AT_PLUS_A",
96
+ diag_pivot_thresh=0.0,
97
+ options={"Equil": True, "SymmetricMode": True},
98
+ )
99
+
100
+ def solve(self, B, tol=None):
101
+ import numpy as np
102
+
103
+ B = np.asarray(B)
104
+ X = np.ndarray(B.shape, order="F")
105
+ for j in range(B.shape[1]):
106
+ X[:, j] = self._LU.solve(B[:, j])
107
+ return X
108
+
109
+
110
+ def _preprocess_graph(G, weight):
111
+ """Compute edge weights and eliminate zero-weight edges."""
112
+ if G.is_directed():
113
+ H = nx.MultiGraph()
114
+ H.add_nodes_from(G)
115
+ H.add_weighted_edges_from(
116
+ ((u, v, e.get(weight, 1.0)) for u, v, e in G.edges(data=True) if u != v),
117
+ weight=weight,
118
+ )
119
+ G = H
120
+ if not G.is_multigraph():
121
+ edges = (
122
+ (u, v, abs(e.get(weight, 1.0))) for u, v, e in G.edges(data=True) if u != v
123
+ )
124
+ else:
125
+ edges = (
126
+ (u, v, sum(abs(e.get(weight, 1.0)) for e in G[u][v].values()))
127
+ for u, v in G.edges()
128
+ if u != v
129
+ )
130
+ H = nx.Graph()
131
+ H.add_nodes_from(G)
132
+ H.add_weighted_edges_from((u, v, e) for u, v, e in edges if e != 0)
133
+ return H
134
+
135
+
136
+ def _rcm_estimate(G, nodelist):
137
+ """Estimate the Fiedler vector using the reverse Cuthill-McKee ordering."""
138
+ import numpy as np
139
+
140
+ G = G.subgraph(nodelist)
141
+ order = reverse_cuthill_mckee_ordering(G)
142
+ n = len(nodelist)
143
+ index = dict(zip(nodelist, range(n)))
144
+ x = np.ndarray(n, dtype=float)
145
+ for i, u in enumerate(order):
146
+ x[index[u]] = i
147
+ x -= (n - 1) / 2.0
148
+ return x
149
+
150
+
151
+ def _tracemin_fiedler(L, X, normalized, tol, method):
152
+ """Compute the Fiedler vector of L using the TraceMIN-Fiedler algorithm.
153
+
154
+ The Fiedler vector of a connected undirected graph is the eigenvector
155
+ corresponding to the second smallest eigenvalue of the Laplacian matrix
156
+ of the graph. This function starts with the Laplacian L, not the Graph.
157
+
158
+ Parameters
159
+ ----------
160
+ L : Laplacian of a possibly weighted or normalized, but undirected graph
161
+
162
+ X : Initial guess for a solution. Usually a matrix of random numbers.
163
+ This function allows more than one column in X to identify more than
164
+ one eigenvector if desired.
165
+
166
+ normalized : bool
167
+ Whether the normalized Laplacian matrix is used.
168
+
169
+ tol : float
170
+ Tolerance of relative residual in eigenvalue computation.
171
+ Warning: There is no limit on number of iterations.
172
+
173
+ method : string
174
+ Should be 'tracemin_pcg' or 'tracemin_lu'.
175
+ Otherwise exception is raised.
176
+
177
+ Returns
178
+ -------
179
+ sigma, X : Two NumPy arrays of floats.
180
+ The lowest eigenvalues and corresponding eigenvectors of L.
181
+ The size of input X determines the size of these outputs.
182
+ As this is for Fiedler vectors, the zero eigenvalue (and
183
+ constant eigenvector) are avoided.
184
+ """
185
+ import numpy as np
186
+ import scipy as sp
187
+
188
+ n = X.shape[0]
189
+
190
+ if normalized:
191
+ # Form the normalized Laplacian matrix and determine the eigenvector of
192
+ # its nullspace.
193
+ e = np.sqrt(L.diagonal())
194
+ # TODO: rm csr_array wrapper when spdiags array creation becomes available
195
+ D = sp.sparse.csr_array(sp.sparse.spdiags(1 / e, 0, n, n, format="csr"))
196
+ L = D @ L @ D
197
+ e *= 1.0 / np.linalg.norm(e, 2)
198
+
199
+ if normalized:
200
+
201
+ def project(X):
202
+ """Make X orthogonal to the nullspace of L."""
203
+ X = np.asarray(X)
204
+ for j in range(X.shape[1]):
205
+ X[:, j] -= (X[:, j] @ e) * e
206
+
207
+ else:
208
+
209
+ def project(X):
210
+ """Make X orthogonal to the nullspace of L."""
211
+ X = np.asarray(X)
212
+ for j in range(X.shape[1]):
213
+ X[:, j] -= X[:, j].sum() / n
214
+
215
+ if method == "tracemin_pcg":
216
+ D = L.diagonal().astype(float)
217
+ solver = _PCGSolver(lambda x: L @ x, lambda x: D * x)
218
+ elif method == "tracemin_lu":
219
+ # Convert A to CSC to suppress SparseEfficiencyWarning.
220
+ A = sp.sparse.csc_array(L, dtype=float, copy=True)
221
+ # Force A to be nonsingular. Since A is the Laplacian matrix of a
222
+ # connected graph, its rank deficiency is one, and thus one diagonal
223
+ # element needs to modified. Changing to infinity forces a zero in the
224
+ # corresponding element in the solution.
225
+ i = (A.indptr[1:] - A.indptr[:-1]).argmax()
226
+ A[i, i] = np.inf
227
+ solver = _LUSolver(A)
228
+ else:
229
+ raise nx.NetworkXError(f"Unknown linear system solver: {method}")
230
+
231
+ # Initialize.
232
+ Lnorm = abs(L).sum(axis=1).flatten().max()
233
+ project(X)
234
+ W = np.ndarray(X.shape, order="F")
235
+
236
+ while True:
237
+ # Orthonormalize X.
238
+ X = np.linalg.qr(X)[0]
239
+ # Compute iteration matrix H.
240
+ W[:, :] = L @ X
241
+ H = X.T @ W
242
+ sigma, Y = sp.linalg.eigh(H, overwrite_a=True)
243
+ # Compute the Ritz vectors.
244
+ X = X @ Y
245
+ # Test for convergence exploiting the fact that L * X == W * Y.
246
+ res = sp.linalg.blas.dasum(W @ Y[:, 0] - sigma[0] * X[:, 0]) / Lnorm
247
+ if res < tol:
248
+ break
249
+ # Compute X = L \ X / (X' * (L \ X)).
250
+ # L \ X can have an arbitrary projection on the nullspace of L,
251
+ # which will be eliminated.
252
+ W[:, :] = solver.solve(X, tol)
253
+ X = (sp.linalg.inv(W.T @ X) @ W.T).T # Preserves Fortran storage order.
254
+ project(X)
255
+
256
+ return sigma, np.asarray(X)
257
+
258
+
259
+ def _get_fiedler_func(method):
260
+ """Returns a function that solves the Fiedler eigenvalue problem."""
261
+ import numpy as np
262
+
263
+ if method == "tracemin": # old style keyword <v2.1
264
+ method = "tracemin_pcg"
265
+ if method in ("tracemin_pcg", "tracemin_lu"):
266
+
267
+ def find_fiedler(L, x, normalized, tol, seed):
268
+ q = 1 if method == "tracemin_pcg" else min(4, L.shape[0] - 1)
269
+ X = np.asarray(seed.normal(size=(q, L.shape[0]))).T
270
+ sigma, X = _tracemin_fiedler(L, X, normalized, tol, method)
271
+ return sigma[0], X[:, 0]
272
+
273
+ elif method == "lanczos" or method == "lobpcg":
274
+
275
+ def find_fiedler(L, x, normalized, tol, seed):
276
+ import scipy as sp
277
+
278
+ L = sp.sparse.csc_array(L, dtype=float)
279
+ n = L.shape[0]
280
+ if normalized:
281
+ # TODO: rm csc_array wrapping when spdiags array becomes available
282
+ D = sp.sparse.csc_array(
283
+ sp.sparse.spdiags(
284
+ 1.0 / np.sqrt(L.diagonal()), [0], n, n, format="csc"
285
+ )
286
+ )
287
+ L = D @ L @ D
288
+ if method == "lanczos" or n < 10:
289
+ # Avoid LOBPCG when n < 10 due to
290
+ # https://github.com/scipy/scipy/issues/3592
291
+ # https://github.com/scipy/scipy/pull/3594
292
+ sigma, X = sp.sparse.linalg.eigsh(
293
+ L, 2, which="SM", tol=tol, return_eigenvectors=True
294
+ )
295
+ return sigma[1], X[:, 1]
296
+ else:
297
+ X = np.asarray(np.atleast_2d(x).T)
298
+ # TODO: rm csr_array wrapping when spdiags array becomes available
299
+ M = sp.sparse.csr_array(sp.sparse.spdiags(1.0 / L.diagonal(), 0, n, n))
300
+ Y = np.ones(n)
301
+ if normalized:
302
+ Y /= D.diagonal()
303
+ sigma, X = sp.sparse.linalg.lobpcg(
304
+ L, X, M=M, Y=np.atleast_2d(Y).T, tol=tol, maxiter=n, largest=False
305
+ )
306
+ return sigma[0], X[:, 0]
307
+
308
+ else:
309
+ raise nx.NetworkXError(f"unknown method {method!r}.")
310
+
311
+ return find_fiedler
312
+
313
+
314
+ @not_implemented_for("directed")
315
+ @np_random_state(5)
316
+ @nx._dispatchable(edge_attrs="weight")
317
+ def algebraic_connectivity(
318
+ G, weight="weight", normalized=False, tol=1e-8, method="tracemin_pcg", seed=None
319
+ ):
320
+ r"""Returns the algebraic connectivity of an undirected graph.
321
+
322
+ The algebraic connectivity of a connected undirected graph is the second
323
+ smallest eigenvalue of its Laplacian matrix.
324
+
325
+ Parameters
326
+ ----------
327
+ G : NetworkX graph
328
+ An undirected graph.
329
+
330
+ weight : object, optional (default: None)
331
+ The data key used to determine the weight of each edge. If None, then
332
+ each edge has unit weight.
333
+
334
+ normalized : bool, optional (default: False)
335
+ Whether the normalized Laplacian matrix is used.
336
+
337
+ tol : float, optional (default: 1e-8)
338
+ Tolerance of relative residual in eigenvalue computation.
339
+
340
+ method : string, optional (default: 'tracemin_pcg')
341
+ Method of eigenvalue computation. It must be one of the tracemin
342
+ options shown below (TraceMIN), 'lanczos' (Lanczos iteration)
343
+ or 'lobpcg' (LOBPCG).
344
+
345
+ The TraceMIN algorithm uses a linear system solver. The following
346
+ values allow specifying the solver to be used.
347
+
348
+ =============== ========================================
349
+ Value Solver
350
+ =============== ========================================
351
+ 'tracemin_pcg' Preconditioned conjugate gradient method
352
+ 'tracemin_lu' LU factorization
353
+ =============== ========================================
354
+
355
+ seed : integer, random_state, or None (default)
356
+ Indicator of random number generation state.
357
+ See :ref:`Randomness<randomness>`.
358
+
359
+ Returns
360
+ -------
361
+ algebraic_connectivity : float
362
+ Algebraic connectivity.
363
+
364
+ Raises
365
+ ------
366
+ NetworkXNotImplemented
367
+ If G is directed.
368
+
369
+ NetworkXError
370
+ If G has less than two nodes.
371
+
372
+ Notes
373
+ -----
374
+ Edge weights are interpreted by their absolute values. For MultiGraph's,
375
+ weights of parallel edges are summed. Zero-weighted edges are ignored.
376
+
377
+ See Also
378
+ --------
379
+ laplacian_matrix
380
+
381
+ Examples
382
+ --------
383
+ For undirected graphs algebraic connectivity can tell us if a graph is connected or not
384
+ `G` is connected iff ``algebraic_connectivity(G) > 0``:
385
+
386
+ >>> G = nx.complete_graph(5)
387
+ >>> nx.algebraic_connectivity(G) > 0
388
+ True
389
+ >>> G.add_node(10) # G is no longer connected
390
+ >>> nx.algebraic_connectivity(G) > 0
391
+ False
392
+
393
+ """
394
+ if len(G) < 2:
395
+ raise nx.NetworkXError("graph has less than two nodes.")
396
+ G = _preprocess_graph(G, weight)
397
+ if not nx.is_connected(G):
398
+ return 0.0
399
+
400
+ L = nx.laplacian_matrix(G)
401
+ if L.shape[0] == 2:
402
+ return 2.0 * float(L[0, 0]) if not normalized else 2.0
403
+
404
+ find_fiedler = _get_fiedler_func(method)
405
+ x = None if method != "lobpcg" else _rcm_estimate(G, G)
406
+ sigma, fiedler = find_fiedler(L, x, normalized, tol, seed)
407
+ return float(sigma)
408
+
409
+
410
+ @not_implemented_for("directed")
411
+ @np_random_state(5)
412
+ @nx._dispatchable(edge_attrs="weight")
413
+ def fiedler_vector(
414
+ G, weight="weight", normalized=False, tol=1e-8, method="tracemin_pcg", seed=None
415
+ ):
416
+ """Returns the Fiedler vector of a connected undirected graph.
417
+
418
+ The Fiedler vector of a connected undirected graph is the eigenvector
419
+ corresponding to the second smallest eigenvalue of the Laplacian matrix
420
+ of the graph.
421
+
422
+ Parameters
423
+ ----------
424
+ G : NetworkX graph
425
+ An undirected graph.
426
+
427
+ weight : object, optional (default: None)
428
+ The data key used to determine the weight of each edge. If None, then
429
+ each edge has unit weight.
430
+
431
+ normalized : bool, optional (default: False)
432
+ Whether the normalized Laplacian matrix is used.
433
+
434
+ tol : float, optional (default: 1e-8)
435
+ Tolerance of relative residual in eigenvalue computation.
436
+
437
+ method : string, optional (default: 'tracemin_pcg')
438
+ Method of eigenvalue computation. It must be one of the tracemin
439
+ options shown below (TraceMIN), 'lanczos' (Lanczos iteration)
440
+ or 'lobpcg' (LOBPCG).
441
+
442
+ The TraceMIN algorithm uses a linear system solver. The following
443
+ values allow specifying the solver to be used.
444
+
445
+ =============== ========================================
446
+ Value Solver
447
+ =============== ========================================
448
+ 'tracemin_pcg' Preconditioned conjugate gradient method
449
+ 'tracemin_lu' LU factorization
450
+ =============== ========================================
451
+
452
+ seed : integer, random_state, or None (default)
453
+ Indicator of random number generation state.
454
+ See :ref:`Randomness<randomness>`.
455
+
456
+ Returns
457
+ -------
458
+ fiedler_vector : NumPy array of floats.
459
+ Fiedler vector.
460
+
461
+ Raises
462
+ ------
463
+ NetworkXNotImplemented
464
+ If G is directed.
465
+
466
+ NetworkXError
467
+ If G has less than two nodes or is not connected.
468
+
469
+ Notes
470
+ -----
471
+ Edge weights are interpreted by their absolute values. For MultiGraph's,
472
+ weights of parallel edges are summed. Zero-weighted edges are ignored.
473
+
474
+ See Also
475
+ --------
476
+ laplacian_matrix
477
+
478
+ Examples
479
+ --------
480
+ Given a connected graph the signs of the values in the Fiedler vector can be
481
+ used to partition the graph into two components.
482
+
483
+ >>> G = nx.barbell_graph(5, 0)
484
+ >>> nx.fiedler_vector(G, normalized=True, seed=1)
485
+ array([-0.32864129, -0.32864129, -0.32864129, -0.32864129, -0.26072899,
486
+ 0.26072899, 0.32864129, 0.32864129, 0.32864129, 0.32864129])
487
+
488
+ The connected components are the two 5-node cliques of the barbell graph.
489
+ """
490
+ import numpy as np
491
+
492
+ if len(G) < 2:
493
+ raise nx.NetworkXError("graph has less than two nodes.")
494
+ G = _preprocess_graph(G, weight)
495
+ if not nx.is_connected(G):
496
+ raise nx.NetworkXError("graph is not connected.")
497
+
498
+ if len(G) == 2:
499
+ return np.array([1.0, -1.0])
500
+
501
+ find_fiedler = _get_fiedler_func(method)
502
+ L = nx.laplacian_matrix(G)
503
+ x = None if method != "lobpcg" else _rcm_estimate(G, G)
504
+ sigma, fiedler = find_fiedler(L, x, normalized, tol, seed)
505
+ return fiedler
506
+
507
+
508
+ @np_random_state(5)
509
+ @nx._dispatchable(edge_attrs="weight")
510
+ def spectral_ordering(
511
+ G, weight="weight", normalized=False, tol=1e-8, method="tracemin_pcg", seed=None
512
+ ):
513
+ """Compute the spectral_ordering of a graph.
514
+
515
+ The spectral ordering of a graph is an ordering of its nodes where nodes
516
+ in the same weakly connected components appear contiguous and ordered by
517
+ their corresponding elements in the Fiedler vector of the component.
518
+
519
+ Parameters
520
+ ----------
521
+ G : NetworkX graph
522
+ A graph.
523
+
524
+ weight : object, optional (default: None)
525
+ The data key used to determine the weight of each edge. If None, then
526
+ each edge has unit weight.
527
+
528
+ normalized : bool, optional (default: False)
529
+ Whether the normalized Laplacian matrix is used.
530
+
531
+ tol : float, optional (default: 1e-8)
532
+ Tolerance of relative residual in eigenvalue computation.
533
+
534
+ method : string, optional (default: 'tracemin_pcg')
535
+ Method of eigenvalue computation. It must be one of the tracemin
536
+ options shown below (TraceMIN), 'lanczos' (Lanczos iteration)
537
+ or 'lobpcg' (LOBPCG).
538
+
539
+ The TraceMIN algorithm uses a linear system solver. The following
540
+ values allow specifying the solver to be used.
541
+
542
+ =============== ========================================
543
+ Value Solver
544
+ =============== ========================================
545
+ 'tracemin_pcg' Preconditioned conjugate gradient method
546
+ 'tracemin_lu' LU factorization
547
+ =============== ========================================
548
+
549
+ seed : integer, random_state, or None (default)
550
+ Indicator of random number generation state.
551
+ See :ref:`Randomness<randomness>`.
552
+
553
+ Returns
554
+ -------
555
+ spectral_ordering : NumPy array of floats.
556
+ Spectral ordering of nodes.
557
+
558
+ Raises
559
+ ------
560
+ NetworkXError
561
+ If G is empty.
562
+
563
+ Notes
564
+ -----
565
+ Edge weights are interpreted by their absolute values. For MultiGraph's,
566
+ weights of parallel edges are summed. Zero-weighted edges are ignored.
567
+
568
+ See Also
569
+ --------
570
+ laplacian_matrix
571
+ """
572
+ if len(G) == 0:
573
+ raise nx.NetworkXError("graph is empty.")
574
+ G = _preprocess_graph(G, weight)
575
+
576
+ find_fiedler = _get_fiedler_func(method)
577
+ order = []
578
+ for component in nx.connected_components(G):
579
+ size = len(component)
580
+ if size > 2:
581
+ L = nx.laplacian_matrix(G, component)
582
+ x = None if method != "lobpcg" else _rcm_estimate(G, component)
583
+ sigma, fiedler = find_fiedler(L, x, normalized, tol, seed)
584
+ sort_info = zip(fiedler, range(size), component)
585
+ order.extend(u for x, c, u in sorted(sort_info))
586
+ else:
587
+ order.extend(component)
588
+
589
+ return order
590
+
591
+
592
+ @nx._dispatchable(edge_attrs="weight")
593
+ def spectral_bisection(
594
+ G, weight="weight", normalized=False, tol=1e-8, method="tracemin_pcg", seed=None
595
+ ):
596
+ """Bisect the graph using the Fiedler vector.
597
+
598
+ This method uses the Fiedler vector to bisect a graph.
599
+ The partition is defined by the nodes which are associated with
600
+ either positive or negative values in the vector.
601
+
602
+ Parameters
603
+ ----------
604
+ G : NetworkX Graph
605
+
606
+ weight : str, optional (default: weight)
607
+ The data key used to determine the weight of each edge. If None, then
608
+ each edge has unit weight.
609
+
610
+ normalized : bool, optional (default: False)
611
+ Whether the normalized Laplacian matrix is used.
612
+
613
+ tol : float, optional (default: 1e-8)
614
+ Tolerance of relative residual in eigenvalue computation.
615
+
616
+ method : string, optional (default: 'tracemin_pcg')
617
+ Method of eigenvalue computation. It must be one of the tracemin
618
+ options shown below (TraceMIN), 'lanczos' (Lanczos iteration)
619
+ or 'lobpcg' (LOBPCG).
620
+
621
+ The TraceMIN algorithm uses a linear system solver. The following
622
+ values allow specifying the solver to be used.
623
+
624
+ =============== ========================================
625
+ Value Solver
626
+ =============== ========================================
627
+ 'tracemin_pcg' Preconditioned conjugate gradient method
628
+ 'tracemin_lu' LU factorization
629
+ =============== ========================================
630
+
631
+ seed : integer, random_state, or None (default)
632
+ Indicator of random number generation state.
633
+ See :ref:`Randomness<randomness>`.
634
+
635
+ Returns
636
+ -------
637
+ bisection : tuple of sets
638
+ Sets with the bisection of nodes
639
+
640
+ Examples
641
+ --------
642
+ >>> G = nx.barbell_graph(3, 0)
643
+ >>> nx.spectral_bisection(G)
644
+ ({0, 1, 2}, {3, 4, 5})
645
+
646
+ References
647
+ ----------
648
+ .. [1] M. E. J Newman 'Networks: An Introduction', pages 364-370
649
+ Oxford University Press 2011.
650
+ """
651
+ import numpy as np
652
+
653
+ v = nx.fiedler_vector(G, weight, normalized, tol, method, seed)
654
+ nodes = np.array(list(G))
655
+ pos_vals = v >= 0
656
+
657
+ return set(nodes[~pos_vals].tolist()), set(nodes[pos_vals].tolist())
.venv/lib/python3.11/site-packages/networkx/linalg/attrmatrix.py ADDED
@@ -0,0 +1,465 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Functions for constructing matrix-like objects from graph attributes.
3
+ """
4
+
5
+ import networkx as nx
6
+
7
+ __all__ = ["attr_matrix", "attr_sparse_matrix"]
8
+
9
+
10
+ def _node_value(G, node_attr):
11
+ """Returns a function that returns a value from G.nodes[u].
12
+
13
+ We return a function expecting a node as its sole argument. Then, in the
14
+ simplest scenario, the returned function will return G.nodes[u][node_attr].
15
+ However, we also handle the case when `node_attr` is None or when it is a
16
+ function itself.
17
+
18
+ Parameters
19
+ ----------
20
+ G : graph
21
+ A NetworkX graph
22
+
23
+ node_attr : {None, str, callable}
24
+ Specification of how the value of the node attribute should be obtained
25
+ from the node attribute dictionary.
26
+
27
+ Returns
28
+ -------
29
+ value : function
30
+ A function expecting a node as its sole argument. The function will
31
+ returns a value from G.nodes[u] that depends on `edge_attr`.
32
+
33
+ """
34
+ if node_attr is None:
35
+
36
+ def value(u):
37
+ return u
38
+
39
+ elif not callable(node_attr):
40
+ # assume it is a key for the node attribute dictionary
41
+ def value(u):
42
+ return G.nodes[u][node_attr]
43
+
44
+ else:
45
+ # Advanced: Allow users to specify something else.
46
+ #
47
+ # For example,
48
+ # node_attr = lambda u: G.nodes[u].get('size', .5) * 3
49
+ #
50
+ value = node_attr
51
+
52
+ return value
53
+
54
+
55
+ def _edge_value(G, edge_attr):
56
+ """Returns a function that returns a value from G[u][v].
57
+
58
+ Suppose there exists an edge between u and v. Then we return a function
59
+ expecting u and v as arguments. For Graph and DiGraph, G[u][v] is
60
+ the edge attribute dictionary, and the function (essentially) returns
61
+ G[u][v][edge_attr]. However, we also handle cases when `edge_attr` is None
62
+ and when it is a function itself. For MultiGraph and MultiDiGraph, G[u][v]
63
+ is a dictionary of all edges between u and v. In this case, the returned
64
+ function sums the value of `edge_attr` for every edge between u and v.
65
+
66
+ Parameters
67
+ ----------
68
+ G : graph
69
+ A NetworkX graph
70
+
71
+ edge_attr : {None, str, callable}
72
+ Specification of how the value of the edge attribute should be obtained
73
+ from the edge attribute dictionary, G[u][v]. For multigraphs, G[u][v]
74
+ is a dictionary of all the edges between u and v. This allows for
75
+ special treatment of multiedges.
76
+
77
+ Returns
78
+ -------
79
+ value : function
80
+ A function expecting two nodes as parameters. The nodes should
81
+ represent the from- and to- node of an edge. The function will
82
+ return a value from G[u][v] that depends on `edge_attr`.
83
+
84
+ """
85
+
86
+ if edge_attr is None:
87
+ # topological count of edges
88
+
89
+ if G.is_multigraph():
90
+
91
+ def value(u, v):
92
+ return len(G[u][v])
93
+
94
+ else:
95
+
96
+ def value(u, v):
97
+ return 1
98
+
99
+ elif not callable(edge_attr):
100
+ # assume it is a key for the edge attribute dictionary
101
+
102
+ if edge_attr == "weight":
103
+ # provide a default value
104
+ if G.is_multigraph():
105
+
106
+ def value(u, v):
107
+ return sum(d.get(edge_attr, 1) for d in G[u][v].values())
108
+
109
+ else:
110
+
111
+ def value(u, v):
112
+ return G[u][v].get(edge_attr, 1)
113
+
114
+ else:
115
+ # otherwise, the edge attribute MUST exist for each edge
116
+ if G.is_multigraph():
117
+
118
+ def value(u, v):
119
+ return sum(d[edge_attr] for d in G[u][v].values())
120
+
121
+ else:
122
+
123
+ def value(u, v):
124
+ return G[u][v][edge_attr]
125
+
126
+ else:
127
+ # Advanced: Allow users to specify something else.
128
+ #
129
+ # Alternative default value:
130
+ # edge_attr = lambda u,v: G[u][v].get('thickness', .5)
131
+ #
132
+ # Function on an attribute:
133
+ # edge_attr = lambda u,v: abs(G[u][v]['weight'])
134
+ #
135
+ # Handle Multi(Di)Graphs differently:
136
+ # edge_attr = lambda u,v: numpy.prod([d['size'] for d in G[u][v].values()])
137
+ #
138
+ # Ignore multiple edges
139
+ # edge_attr = lambda u,v: 1 if len(G[u][v]) else 0
140
+ #
141
+ value = edge_attr
142
+
143
+ return value
144
+
145
+
146
+ @nx._dispatchable(edge_attrs={"edge_attr": None}, node_attrs="node_attr")
147
+ def attr_matrix(
148
+ G,
149
+ edge_attr=None,
150
+ node_attr=None,
151
+ normalized=False,
152
+ rc_order=None,
153
+ dtype=None,
154
+ order=None,
155
+ ):
156
+ """Returns the attribute matrix using attributes from `G` as a numpy array.
157
+
158
+ If only `G` is passed in, then the adjacency matrix is constructed.
159
+
160
+ Let A be a discrete set of values for the node attribute `node_attr`. Then
161
+ the elements of A represent the rows and columns of the constructed matrix.
162
+ Now, iterate through every edge e=(u,v) in `G` and consider the value
163
+ of the edge attribute `edge_attr`. If ua and va are the values of the
164
+ node attribute `node_attr` for u and v, respectively, then the value of
165
+ the edge attribute is added to the matrix element at (ua, va).
166
+
167
+ Parameters
168
+ ----------
169
+ G : graph
170
+ The NetworkX graph used to construct the attribute matrix.
171
+
172
+ edge_attr : str, optional
173
+ Each element of the matrix represents a running total of the
174
+ specified edge attribute for edges whose node attributes correspond
175
+ to the rows/cols of the matrix. The attribute must be present for
176
+ all edges in the graph. If no attribute is specified, then we
177
+ just count the number of edges whose node attributes correspond
178
+ to the matrix element.
179
+
180
+ node_attr : str, optional
181
+ Each row and column in the matrix represents a particular value
182
+ of the node attribute. The attribute must be present for all nodes
183
+ in the graph. Note, the values of this attribute should be reliably
184
+ hashable. So, float values are not recommended. If no attribute is
185
+ specified, then the rows and columns will be the nodes of the graph.
186
+
187
+ normalized : bool, optional
188
+ If True, then each row is normalized by the summation of its values.
189
+
190
+ rc_order : list, optional
191
+ A list of the node attribute values. This list specifies the ordering
192
+ of rows and columns of the array. If no ordering is provided, then
193
+ the ordering will be random (and also, a return value).
194
+
195
+ Other Parameters
196
+ ----------------
197
+ dtype : NumPy data-type, optional
198
+ A valid NumPy dtype used to initialize the array. Keep in mind certain
199
+ dtypes can yield unexpected results if the array is to be normalized.
200
+ The parameter is passed to numpy.zeros(). If unspecified, the NumPy
201
+ default is used.
202
+
203
+ order : {'C', 'F'}, optional
204
+ Whether to store multidimensional data in C- or Fortran-contiguous
205
+ (row- or column-wise) order in memory. This parameter is passed to
206
+ numpy.zeros(). If unspecified, the NumPy default is used.
207
+
208
+ Returns
209
+ -------
210
+ M : 2D NumPy ndarray
211
+ The attribute matrix.
212
+
213
+ ordering : list
214
+ If `rc_order` was specified, then only the attribute matrix is returned.
215
+ However, if `rc_order` was None, then the ordering used to construct
216
+ the matrix is returned as well.
217
+
218
+ Examples
219
+ --------
220
+ Construct an adjacency matrix:
221
+
222
+ >>> G = nx.Graph()
223
+ >>> G.add_edge(0, 1, thickness=1, weight=3)
224
+ >>> G.add_edge(0, 2, thickness=2)
225
+ >>> G.add_edge(1, 2, thickness=3)
226
+ >>> nx.attr_matrix(G, rc_order=[0, 1, 2])
227
+ array([[0., 1., 1.],
228
+ [1., 0., 1.],
229
+ [1., 1., 0.]])
230
+
231
+ Alternatively, we can obtain the matrix describing edge thickness.
232
+
233
+ >>> nx.attr_matrix(G, edge_attr="thickness", rc_order=[0, 1, 2])
234
+ array([[0., 1., 2.],
235
+ [1., 0., 3.],
236
+ [2., 3., 0.]])
237
+
238
+ We can also color the nodes and ask for the probability distribution over
239
+ all edges (u,v) describing:
240
+
241
+ Pr(v has color Y | u has color X)
242
+
243
+ >>> G.nodes[0]["color"] = "red"
244
+ >>> G.nodes[1]["color"] = "red"
245
+ >>> G.nodes[2]["color"] = "blue"
246
+ >>> rc = ["red", "blue"]
247
+ >>> nx.attr_matrix(G, node_attr="color", normalized=True, rc_order=rc)
248
+ array([[0.33333333, 0.66666667],
249
+ [1. , 0. ]])
250
+
251
+ For example, the above tells us that for all edges (u,v):
252
+
253
+ Pr( v is red | u is red) = 1/3
254
+ Pr( v is blue | u is red) = 2/3
255
+
256
+ Pr( v is red | u is blue) = 1
257
+ Pr( v is blue | u is blue) = 0
258
+
259
+ Finally, we can obtain the total weights listed by the node colors.
260
+
261
+ >>> nx.attr_matrix(G, edge_attr="weight", node_attr="color", rc_order=rc)
262
+ array([[3., 2.],
263
+ [2., 0.]])
264
+
265
+ Thus, the total weight over all edges (u,v) with u and v having colors:
266
+
267
+ (red, red) is 3 # the sole contribution is from edge (0,1)
268
+ (red, blue) is 2 # contributions from edges (0,2) and (1,2)
269
+ (blue, red) is 2 # same as (red, blue) since graph is undirected
270
+ (blue, blue) is 0 # there are no edges with blue endpoints
271
+
272
+ """
273
+ import numpy as np
274
+
275
+ edge_value = _edge_value(G, edge_attr)
276
+ node_value = _node_value(G, node_attr)
277
+
278
+ if rc_order is None:
279
+ ordering = list({node_value(n) for n in G})
280
+ else:
281
+ ordering = rc_order
282
+
283
+ N = len(ordering)
284
+ undirected = not G.is_directed()
285
+ index = dict(zip(ordering, range(N)))
286
+ M = np.zeros((N, N), dtype=dtype, order=order)
287
+
288
+ seen = set()
289
+ for u, nbrdict in G.adjacency():
290
+ for v in nbrdict:
291
+ # Obtain the node attribute values.
292
+ i, j = index[node_value(u)], index[node_value(v)]
293
+ if v not in seen:
294
+ M[i, j] += edge_value(u, v)
295
+ if undirected:
296
+ M[j, i] = M[i, j]
297
+
298
+ if undirected:
299
+ seen.add(u)
300
+
301
+ if normalized:
302
+ M /= M.sum(axis=1).reshape((N, 1))
303
+
304
+ if rc_order is None:
305
+ return M, ordering
306
+ else:
307
+ return M
308
+
309
+
310
+ @nx._dispatchable(edge_attrs={"edge_attr": None}, node_attrs="node_attr")
311
+ def attr_sparse_matrix(
312
+ G, edge_attr=None, node_attr=None, normalized=False, rc_order=None, dtype=None
313
+ ):
314
+ """Returns a SciPy sparse array using attributes from G.
315
+
316
+ If only `G` is passed in, then the adjacency matrix is constructed.
317
+
318
+ Let A be a discrete set of values for the node attribute `node_attr`. Then
319
+ the elements of A represent the rows and columns of the constructed matrix.
320
+ Now, iterate through every edge e=(u,v) in `G` and consider the value
321
+ of the edge attribute `edge_attr`. If ua and va are the values of the
322
+ node attribute `node_attr` for u and v, respectively, then the value of
323
+ the edge attribute is added to the matrix element at (ua, va).
324
+
325
+ Parameters
326
+ ----------
327
+ G : graph
328
+ The NetworkX graph used to construct the NumPy matrix.
329
+
330
+ edge_attr : str, optional
331
+ Each element of the matrix represents a running total of the
332
+ specified edge attribute for edges whose node attributes correspond
333
+ to the rows/cols of the matrix. The attribute must be present for
334
+ all edges in the graph. If no attribute is specified, then we
335
+ just count the number of edges whose node attributes correspond
336
+ to the matrix element.
337
+
338
+ node_attr : str, optional
339
+ Each row and column in the matrix represents a particular value
340
+ of the node attribute. The attribute must be present for all nodes
341
+ in the graph. Note, the values of this attribute should be reliably
342
+ hashable. So, float values are not recommended. If no attribute is
343
+ specified, then the rows and columns will be the nodes of the graph.
344
+
345
+ normalized : bool, optional
346
+ If True, then each row is normalized by the summation of its values.
347
+
348
+ rc_order : list, optional
349
+ A list of the node attribute values. This list specifies the ordering
350
+ of rows and columns of the array. If no ordering is provided, then
351
+ the ordering will be random (and also, a return value).
352
+
353
+ Other Parameters
354
+ ----------------
355
+ dtype : NumPy data-type, optional
356
+ A valid NumPy dtype used to initialize the array. Keep in mind certain
357
+ dtypes can yield unexpected results if the array is to be normalized.
358
+ The parameter is passed to numpy.zeros(). If unspecified, the NumPy
359
+ default is used.
360
+
361
+ Returns
362
+ -------
363
+ M : SciPy sparse array
364
+ The attribute matrix.
365
+
366
+ ordering : list
367
+ If `rc_order` was specified, then only the matrix is returned.
368
+ However, if `rc_order` was None, then the ordering used to construct
369
+ the matrix is returned as well.
370
+
371
+ Examples
372
+ --------
373
+ Construct an adjacency matrix:
374
+
375
+ >>> G = nx.Graph()
376
+ >>> G.add_edge(0, 1, thickness=1, weight=3)
377
+ >>> G.add_edge(0, 2, thickness=2)
378
+ >>> G.add_edge(1, 2, thickness=3)
379
+ >>> M = nx.attr_sparse_matrix(G, rc_order=[0, 1, 2])
380
+ >>> M.toarray()
381
+ array([[0., 1., 1.],
382
+ [1., 0., 1.],
383
+ [1., 1., 0.]])
384
+
385
+ Alternatively, we can obtain the matrix describing edge thickness.
386
+
387
+ >>> M = nx.attr_sparse_matrix(G, edge_attr="thickness", rc_order=[0, 1, 2])
388
+ >>> M.toarray()
389
+ array([[0., 1., 2.],
390
+ [1., 0., 3.],
391
+ [2., 3., 0.]])
392
+
393
+ We can also color the nodes and ask for the probability distribution over
394
+ all edges (u,v) describing:
395
+
396
+ Pr(v has color Y | u has color X)
397
+
398
+ >>> G.nodes[0]["color"] = "red"
399
+ >>> G.nodes[1]["color"] = "red"
400
+ >>> G.nodes[2]["color"] = "blue"
401
+ >>> rc = ["red", "blue"]
402
+ >>> M = nx.attr_sparse_matrix(G, node_attr="color", normalized=True, rc_order=rc)
403
+ >>> M.toarray()
404
+ array([[0.33333333, 0.66666667],
405
+ [1. , 0. ]])
406
+
407
+ For example, the above tells us that for all edges (u,v):
408
+
409
+ Pr( v is red | u is red) = 1/3
410
+ Pr( v is blue | u is red) = 2/3
411
+
412
+ Pr( v is red | u is blue) = 1
413
+ Pr( v is blue | u is blue) = 0
414
+
415
+ Finally, we can obtain the total weights listed by the node colors.
416
+
417
+ >>> M = nx.attr_sparse_matrix(G, edge_attr="weight", node_attr="color", rc_order=rc)
418
+ >>> M.toarray()
419
+ array([[3., 2.],
420
+ [2., 0.]])
421
+
422
+ Thus, the total weight over all edges (u,v) with u and v having colors:
423
+
424
+ (red, red) is 3 # the sole contribution is from edge (0,1)
425
+ (red, blue) is 2 # contributions from edges (0,2) and (1,2)
426
+ (blue, red) is 2 # same as (red, blue) since graph is undirected
427
+ (blue, blue) is 0 # there are no edges with blue endpoints
428
+
429
+ """
430
+ import numpy as np
431
+ import scipy as sp
432
+
433
+ edge_value = _edge_value(G, edge_attr)
434
+ node_value = _node_value(G, node_attr)
435
+
436
+ if rc_order is None:
437
+ ordering = list({node_value(n) for n in G})
438
+ else:
439
+ ordering = rc_order
440
+
441
+ N = len(ordering)
442
+ undirected = not G.is_directed()
443
+ index = dict(zip(ordering, range(N)))
444
+ M = sp.sparse.lil_array((N, N), dtype=dtype)
445
+
446
+ seen = set()
447
+ for u, nbrdict in G.adjacency():
448
+ for v in nbrdict:
449
+ # Obtain the node attribute values.
450
+ i, j = index[node_value(u)], index[node_value(v)]
451
+ if v not in seen:
452
+ M[i, j] += edge_value(u, v)
453
+ if undirected:
454
+ M[j, i] = M[i, j]
455
+
456
+ if undirected:
457
+ seen.add(u)
458
+
459
+ if normalized:
460
+ M *= 1 / M.sum(axis=1)[:, np.newaxis] # in-place mult preserves sparse
461
+
462
+ if rc_order is None:
463
+ return M, ordering
464
+ else:
465
+ return M
.venv/lib/python3.11/site-packages/networkx/linalg/bethehessianmatrix.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Bethe Hessian or deformed Laplacian matrix of graphs."""
2
+
3
+ import networkx as nx
4
+ from networkx.utils import not_implemented_for
5
+
6
+ __all__ = ["bethe_hessian_matrix"]
7
+
8
+
9
+ @not_implemented_for("directed")
10
+ @not_implemented_for("multigraph")
11
+ @nx._dispatchable
12
+ def bethe_hessian_matrix(G, r=None, nodelist=None):
13
+ r"""Returns the Bethe Hessian matrix of G.
14
+
15
+ The Bethe Hessian is a family of matrices parametrized by r, defined as
16
+ H(r) = (r^2 - 1) I - r A + D where A is the adjacency matrix, D is the
17
+ diagonal matrix of node degrees, and I is the identify matrix. It is equal
18
+ to the graph laplacian when the regularizer r = 1.
19
+
20
+ The default choice of regularizer should be the ratio [2]_
21
+
22
+ .. math::
23
+ r_m = \left(\sum k_i \right)^{-1}\left(\sum k_i^2 \right) - 1
24
+
25
+ Parameters
26
+ ----------
27
+ G : Graph
28
+ A NetworkX graph
29
+ r : float
30
+ Regularizer parameter
31
+ nodelist : list, optional
32
+ The rows and columns are ordered according to the nodes in nodelist.
33
+ If nodelist is None, then the ordering is produced by ``G.nodes()``.
34
+
35
+ Returns
36
+ -------
37
+ H : scipy.sparse.csr_array
38
+ The Bethe Hessian matrix of `G`, with parameter `r`.
39
+
40
+ Examples
41
+ --------
42
+ >>> k = [3, 2, 2, 1, 0]
43
+ >>> G = nx.havel_hakimi_graph(k)
44
+ >>> H = nx.bethe_hessian_matrix(G)
45
+ >>> H.toarray()
46
+ array([[ 3.5625, -1.25 , -1.25 , -1.25 , 0. ],
47
+ [-1.25 , 2.5625, -1.25 , 0. , 0. ],
48
+ [-1.25 , -1.25 , 2.5625, 0. , 0. ],
49
+ [-1.25 , 0. , 0. , 1.5625, 0. ],
50
+ [ 0. , 0. , 0. , 0. , 0.5625]])
51
+
52
+ See Also
53
+ --------
54
+ bethe_hessian_spectrum
55
+ adjacency_matrix
56
+ laplacian_matrix
57
+
58
+ References
59
+ ----------
60
+ .. [1] A. Saade, F. Krzakala and L. Zdeborová
61
+ "Spectral Clustering of Graphs with the Bethe Hessian",
62
+ Advances in Neural Information Processing Systems, 2014.
63
+ .. [2] C. M. Le, E. Levina
64
+ "Estimating the number of communities in networks by spectral methods"
65
+ arXiv:1507.00827, 2015.
66
+ """
67
+ import scipy as sp
68
+
69
+ if nodelist is None:
70
+ nodelist = list(G)
71
+ if r is None:
72
+ r = sum(d**2 for v, d in nx.degree(G)) / sum(d for v, d in nx.degree(G)) - 1
73
+ A = nx.to_scipy_sparse_array(G, nodelist=nodelist, format="csr")
74
+ n, m = A.shape
75
+ # TODO: Rm csr_array wrapper when spdiags array creation becomes available
76
+ D = sp.sparse.csr_array(sp.sparse.spdiags(A.sum(axis=1), 0, m, n, format="csr"))
77
+ # TODO: Rm csr_array wrapper when eye array creation becomes available
78
+ I = sp.sparse.csr_array(sp.sparse.eye(m, n, format="csr"))
79
+ return (r**2 - 1) * I - r * A + D
.venv/lib/python3.11/site-packages/networkx/linalg/graphmatrix.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Adjacency matrix and incidence matrix of graphs.
3
+ """
4
+
5
+ import networkx as nx
6
+
7
+ __all__ = ["incidence_matrix", "adjacency_matrix"]
8
+
9
+
10
+ @nx._dispatchable(edge_attrs="weight")
11
+ def incidence_matrix(
12
+ G, nodelist=None, edgelist=None, oriented=False, weight=None, *, dtype=None
13
+ ):
14
+ """Returns incidence matrix of G.
15
+
16
+ The incidence matrix assigns each row to a node and each column to an edge.
17
+ For a standard incidence matrix a 1 appears wherever a row's node is
18
+ incident on the column's edge. For an oriented incidence matrix each
19
+ edge is assigned an orientation (arbitrarily for undirected and aligning to
20
+ direction for directed). A -1 appears for the source (tail) of an edge and
21
+ 1 for the destination (head) of the edge. The elements are zero otherwise.
22
+
23
+ Parameters
24
+ ----------
25
+ G : graph
26
+ A NetworkX graph
27
+
28
+ nodelist : list, optional (default= all nodes in G)
29
+ The rows are ordered according to the nodes in nodelist.
30
+ If nodelist is None, then the ordering is produced by G.nodes().
31
+
32
+ edgelist : list, optional (default= all edges in G)
33
+ The columns are ordered according to the edges in edgelist.
34
+ If edgelist is None, then the ordering is produced by G.edges().
35
+
36
+ oriented: bool, optional (default=False)
37
+ If True, matrix elements are +1 or -1 for the head or tail node
38
+ respectively of each edge. If False, +1 occurs at both nodes.
39
+
40
+ weight : string or None, optional (default=None)
41
+ The edge data key used to provide each value in the matrix.
42
+ If None, then each edge has weight 1. Edge weights, if used,
43
+ should be positive so that the orientation can provide the sign.
44
+
45
+ dtype : a NumPy dtype or None (default=None)
46
+ The dtype of the output sparse array. This type should be a compatible
47
+ type of the weight argument, eg. if weight would return a float this
48
+ argument should also be a float.
49
+ If None, then the default for SciPy is used.
50
+
51
+ Returns
52
+ -------
53
+ A : SciPy sparse array
54
+ The incidence matrix of G.
55
+
56
+ Notes
57
+ -----
58
+ For MultiGraph/MultiDiGraph, the edges in edgelist should be
59
+ (u,v,key) 3-tuples.
60
+
61
+ "Networks are the best discrete model for so many problems in
62
+ applied mathematics" [1]_.
63
+
64
+ References
65
+ ----------
66
+ .. [1] Gil Strang, Network applications: A = incidence matrix,
67
+ http://videolectures.net/mit18085f07_strang_lec03/
68
+ """
69
+ import scipy as sp
70
+
71
+ if nodelist is None:
72
+ nodelist = list(G)
73
+ if edgelist is None:
74
+ if G.is_multigraph():
75
+ edgelist = list(G.edges(keys=True))
76
+ else:
77
+ edgelist = list(G.edges())
78
+ A = sp.sparse.lil_array((len(nodelist), len(edgelist)), dtype=dtype)
79
+ node_index = {node: i for i, node in enumerate(nodelist)}
80
+ for ei, e in enumerate(edgelist):
81
+ (u, v) = e[:2]
82
+ if u == v:
83
+ continue # self loops give zero column
84
+ try:
85
+ ui = node_index[u]
86
+ vi = node_index[v]
87
+ except KeyError as err:
88
+ raise nx.NetworkXError(
89
+ f"node {u} or {v} in edgelist but not in nodelist"
90
+ ) from err
91
+ if weight is None:
92
+ wt = 1
93
+ else:
94
+ if G.is_multigraph():
95
+ ekey = e[2]
96
+ wt = G[u][v][ekey].get(weight, 1)
97
+ else:
98
+ wt = G[u][v].get(weight, 1)
99
+ if oriented:
100
+ A[ui, ei] = -wt
101
+ A[vi, ei] = wt
102
+ else:
103
+ A[ui, ei] = wt
104
+ A[vi, ei] = wt
105
+ return A.asformat("csc")
106
+
107
+
108
+ @nx._dispatchable(edge_attrs="weight")
109
+ def adjacency_matrix(G, nodelist=None, dtype=None, weight="weight"):
110
+ """Returns adjacency matrix of `G`.
111
+
112
+ Parameters
113
+ ----------
114
+ G : graph
115
+ A NetworkX graph
116
+
117
+ nodelist : list, optional
118
+ The rows and columns are ordered according to the nodes in `nodelist`.
119
+ If ``nodelist=None`` (the default), then the ordering is produced by
120
+ ``G.nodes()``.
121
+
122
+ dtype : NumPy data-type, optional
123
+ The desired data-type for the array.
124
+ If `None`, then the NumPy default is used.
125
+
126
+ weight : string or None, optional (default='weight')
127
+ The edge data key used to provide each value in the matrix.
128
+ If None, then each edge has weight 1.
129
+
130
+ Returns
131
+ -------
132
+ A : SciPy sparse array
133
+ Adjacency matrix representation of G.
134
+
135
+ Notes
136
+ -----
137
+ For directed graphs, entry ``i, j`` corresponds to an edge from ``i`` to ``j``.
138
+
139
+ If you want a pure Python adjacency matrix representation try
140
+ :func:`~networkx.convert.to_dict_of_dicts` which will return a
141
+ dictionary-of-dictionaries format that can be addressed as a
142
+ sparse matrix.
143
+
144
+ For multigraphs with parallel edges the weights are summed.
145
+ See :func:`networkx.convert_matrix.to_numpy_array` for other options.
146
+
147
+ The convention used for self-loop edges in graphs is to assign the
148
+ diagonal matrix entry value to the edge weight attribute
149
+ (or the number 1 if the edge has no weight attribute). If the
150
+ alternate convention of doubling the edge weight is desired the
151
+ resulting SciPy sparse array can be modified as follows::
152
+
153
+ >>> G = nx.Graph([(1, 1)])
154
+ >>> A = nx.adjacency_matrix(G)
155
+ >>> A.toarray()
156
+ array([[1]])
157
+ >>> A.setdiag(A.diagonal() * 2)
158
+ >>> A.toarray()
159
+ array([[2]])
160
+
161
+ See Also
162
+ --------
163
+ to_numpy_array
164
+ to_scipy_sparse_array
165
+ to_dict_of_dicts
166
+ adjacency_spectrum
167
+ """
168
+ return nx.to_scipy_sparse_array(G, nodelist=nodelist, dtype=dtype, weight=weight)
.venv/lib/python3.11/site-packages/networkx/linalg/laplacianmatrix.py ADDED
@@ -0,0 +1,617 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Laplacian matrix of graphs.
2
+
3
+ All calculations here are done using the out-degree. For Laplacians using
4
+ in-degree, use `G.reverse(copy=False)` instead of `G` and take the transpose.
5
+
6
+ The `laplacian_matrix` function provides an unnormalized matrix,
7
+ while `normalized_laplacian_matrix`, `directed_laplacian_matrix`,
8
+ and `directed_combinatorial_laplacian_matrix` are all normalized.
9
+ """
10
+
11
+ import networkx as nx
12
+ from networkx.utils import not_implemented_for
13
+
14
+ __all__ = [
15
+ "laplacian_matrix",
16
+ "normalized_laplacian_matrix",
17
+ "total_spanning_tree_weight",
18
+ "directed_laplacian_matrix",
19
+ "directed_combinatorial_laplacian_matrix",
20
+ ]
21
+
22
+
23
+ @nx._dispatchable(edge_attrs="weight")
24
+ def laplacian_matrix(G, nodelist=None, weight="weight"):
25
+ """Returns the Laplacian matrix of G.
26
+
27
+ The graph Laplacian is the matrix L = D - A, where
28
+ A is the adjacency matrix and D is the diagonal matrix of node degrees.
29
+
30
+ Parameters
31
+ ----------
32
+ G : graph
33
+ A NetworkX graph
34
+
35
+ nodelist : list, optional
36
+ The rows and columns are ordered according to the nodes in nodelist.
37
+ If nodelist is None, then the ordering is produced by G.nodes().
38
+
39
+ weight : string or None, optional (default='weight')
40
+ The edge data key used to compute each value in the matrix.
41
+ If None, then each edge has weight 1.
42
+
43
+ Returns
44
+ -------
45
+ L : SciPy sparse array
46
+ The Laplacian matrix of G.
47
+
48
+ Notes
49
+ -----
50
+ For MultiGraph, the edges weights are summed.
51
+
52
+ This returns an unnormalized matrix. For a normalized output,
53
+ use `normalized_laplacian_matrix`, `directed_laplacian_matrix`,
54
+ or `directed_combinatorial_laplacian_matrix`.
55
+
56
+ This calculation uses the out-degree of the graph `G`. To use the
57
+ in-degree for calculations instead, use `G.reverse(copy=False)` and
58
+ take the transpose.
59
+
60
+ See Also
61
+ --------
62
+ :func:`~networkx.convert_matrix.to_numpy_array`
63
+ normalized_laplacian_matrix
64
+ directed_laplacian_matrix
65
+ directed_combinatorial_laplacian_matrix
66
+ :func:`~networkx.linalg.spectrum.laplacian_spectrum`
67
+
68
+ Examples
69
+ --------
70
+ For graphs with multiple connected components, L is permutation-similar
71
+ to a block diagonal matrix where each block is the respective Laplacian
72
+ matrix for each component.
73
+
74
+ >>> G = nx.Graph([(1, 2), (2, 3), (4, 5)])
75
+ >>> print(nx.laplacian_matrix(G).toarray())
76
+ [[ 1 -1 0 0 0]
77
+ [-1 2 -1 0 0]
78
+ [ 0 -1 1 0 0]
79
+ [ 0 0 0 1 -1]
80
+ [ 0 0 0 -1 1]]
81
+
82
+ >>> edges = [
83
+ ... (1, 2),
84
+ ... (2, 1),
85
+ ... (2, 4),
86
+ ... (4, 3),
87
+ ... (3, 4),
88
+ ... ]
89
+ >>> DiG = nx.DiGraph(edges)
90
+ >>> print(nx.laplacian_matrix(DiG).toarray())
91
+ [[ 1 -1 0 0]
92
+ [-1 2 -1 0]
93
+ [ 0 0 1 -1]
94
+ [ 0 0 -1 1]]
95
+
96
+ Notice that node 4 is represented by the third column and row. This is because
97
+ by default the row/column order is the order of `G.nodes` (i.e. the node added
98
+ order -- in the edgelist, 4 first appears in (2, 4), before node 3 in edge (4, 3).)
99
+ To control the node order of the matrix, use the `nodelist` argument.
100
+
101
+ >>> print(nx.laplacian_matrix(DiG, nodelist=[1, 2, 3, 4]).toarray())
102
+ [[ 1 -1 0 0]
103
+ [-1 2 0 -1]
104
+ [ 0 0 1 -1]
105
+ [ 0 0 -1 1]]
106
+
107
+ This calculation uses the out-degree of the graph `G`. To use the
108
+ in-degree for calculations instead, use `G.reverse(copy=False)` and
109
+ take the transpose.
110
+
111
+ >>> print(nx.laplacian_matrix(DiG.reverse(copy=False)).toarray().T)
112
+ [[ 1 -1 0 0]
113
+ [-1 1 -1 0]
114
+ [ 0 0 2 -1]
115
+ [ 0 0 -1 1]]
116
+
117
+ References
118
+ ----------
119
+ .. [1] Langville, Amy N., and Carl D. Meyer. Google’s PageRank and Beyond:
120
+ The Science of Search Engine Rankings. Princeton University Press, 2006.
121
+
122
+ """
123
+ import scipy as sp
124
+
125
+ if nodelist is None:
126
+ nodelist = list(G)
127
+ A = nx.to_scipy_sparse_array(G, nodelist=nodelist, weight=weight, format="csr")
128
+ n, m = A.shape
129
+ # TODO: rm csr_array wrapper when spdiags can produce arrays
130
+ D = sp.sparse.csr_array(sp.sparse.spdiags(A.sum(axis=1), 0, m, n, format="csr"))
131
+ return D - A
132
+
133
+
134
+ @nx._dispatchable(edge_attrs="weight")
135
+ def normalized_laplacian_matrix(G, nodelist=None, weight="weight"):
136
+ r"""Returns the normalized Laplacian matrix of G.
137
+
138
+ The normalized graph Laplacian is the matrix
139
+
140
+ .. math::
141
+
142
+ N = D^{-1/2} L D^{-1/2}
143
+
144
+ where `L` is the graph Laplacian and `D` is the diagonal matrix of
145
+ node degrees [1]_.
146
+
147
+ Parameters
148
+ ----------
149
+ G : graph
150
+ A NetworkX graph
151
+
152
+ nodelist : list, optional
153
+ The rows and columns are ordered according to the nodes in nodelist.
154
+ If nodelist is None, then the ordering is produced by G.nodes().
155
+
156
+ weight : string or None, optional (default='weight')
157
+ The edge data key used to compute each value in the matrix.
158
+ If None, then each edge has weight 1.
159
+
160
+ Returns
161
+ -------
162
+ N : SciPy sparse array
163
+ The normalized Laplacian matrix of G.
164
+
165
+ Notes
166
+ -----
167
+ For MultiGraph, the edges weights are summed.
168
+ See :func:`to_numpy_array` for other options.
169
+
170
+ If the Graph contains selfloops, D is defined as ``diag(sum(A, 1))``, where A is
171
+ the adjacency matrix [2]_.
172
+
173
+ This calculation uses the out-degree of the graph `G`. To use the
174
+ in-degree for calculations instead, use `G.reverse(copy=False)` and
175
+ take the transpose.
176
+
177
+ For an unnormalized output, use `laplacian_matrix`.
178
+
179
+ Examples
180
+ --------
181
+
182
+ >>> import numpy as np
183
+ >>> edges = [
184
+ ... (1, 2),
185
+ ... (2, 1),
186
+ ... (2, 4),
187
+ ... (4, 3),
188
+ ... (3, 4),
189
+ ... ]
190
+ >>> DiG = nx.DiGraph(edges)
191
+ >>> print(nx.normalized_laplacian_matrix(DiG).toarray())
192
+ [[ 1. -0.70710678 0. 0. ]
193
+ [-0.70710678 1. -0.70710678 0. ]
194
+ [ 0. 0. 1. -1. ]
195
+ [ 0. 0. -1. 1. ]]
196
+
197
+ Notice that node 4 is represented by the third column and row. This is because
198
+ by default the row/column order is the order of `G.nodes` (i.e. the node added
199
+ order -- in the edgelist, 4 first appears in (2, 4), before node 3 in edge (4, 3).)
200
+ To control the node order of the matrix, use the `nodelist` argument.
201
+
202
+ >>> print(nx.normalized_laplacian_matrix(DiG, nodelist=[1, 2, 3, 4]).toarray())
203
+ [[ 1. -0.70710678 0. 0. ]
204
+ [-0.70710678 1. 0. -0.70710678]
205
+ [ 0. 0. 1. -1. ]
206
+ [ 0. 0. -1. 1. ]]
207
+ >>> G = nx.Graph(edges)
208
+ >>> print(nx.normalized_laplacian_matrix(G).toarray())
209
+ [[ 1. -0.70710678 0. 0. ]
210
+ [-0.70710678 1. -0.5 0. ]
211
+ [ 0. -0.5 1. -0.70710678]
212
+ [ 0. 0. -0.70710678 1. ]]
213
+
214
+ See Also
215
+ --------
216
+ laplacian_matrix
217
+ normalized_laplacian_spectrum
218
+ directed_laplacian_matrix
219
+ directed_combinatorial_laplacian_matrix
220
+
221
+ References
222
+ ----------
223
+ .. [1] Fan Chung-Graham, Spectral Graph Theory,
224
+ CBMS Regional Conference Series in Mathematics, Number 92, 1997.
225
+ .. [2] Steve Butler, Interlacing For Weighted Graphs Using The Normalized
226
+ Laplacian, Electronic Journal of Linear Algebra, Volume 16, pp. 90-98,
227
+ March 2007.
228
+ .. [3] Langville, Amy N., and Carl D. Meyer. Google’s PageRank and Beyond:
229
+ The Science of Search Engine Rankings. Princeton University Press, 2006.
230
+ """
231
+ import numpy as np
232
+ import scipy as sp
233
+
234
+ if nodelist is None:
235
+ nodelist = list(G)
236
+ A = nx.to_scipy_sparse_array(G, nodelist=nodelist, weight=weight, format="csr")
237
+ n, _ = A.shape
238
+ diags = A.sum(axis=1)
239
+ # TODO: rm csr_array wrapper when spdiags can produce arrays
240
+ D = sp.sparse.csr_array(sp.sparse.spdiags(diags, 0, n, n, format="csr"))
241
+ L = D - A
242
+ with np.errstate(divide="ignore"):
243
+ diags_sqrt = 1.0 / np.sqrt(diags)
244
+ diags_sqrt[np.isinf(diags_sqrt)] = 0
245
+ # TODO: rm csr_array wrapper when spdiags can produce arrays
246
+ DH = sp.sparse.csr_array(sp.sparse.spdiags(diags_sqrt, 0, n, n, format="csr"))
247
+ return DH @ (L @ DH)
248
+
249
+
250
+ @nx._dispatchable(edge_attrs="weight")
251
+ def total_spanning_tree_weight(G, weight=None, root=None):
252
+ """
253
+ Returns the total weight of all spanning trees of `G`.
254
+
255
+ Kirchoff's Tree Matrix Theorem [1]_, [2]_ states that the determinant of any
256
+ cofactor of the Laplacian matrix of a graph is the number of spanning trees
257
+ in the graph. For a weighted Laplacian matrix, it is the sum across all
258
+ spanning trees of the multiplicative weight of each tree. That is, the
259
+ weight of each tree is the product of its edge weights.
260
+
261
+ For unweighted graphs, the total weight equals the number of spanning trees in `G`.
262
+
263
+ For directed graphs, the total weight follows by summing over all directed
264
+ spanning trees in `G` that start in the `root` node [3]_.
265
+
266
+ .. deprecated:: 3.3
267
+
268
+ ``total_spanning_tree_weight`` is deprecated and will be removed in v3.5.
269
+ Use ``nx.number_of_spanning_trees(G)`` instead.
270
+
271
+ Parameters
272
+ ----------
273
+ G : NetworkX Graph
274
+
275
+ weight : string or None, optional (default=None)
276
+ The key for the edge attribute holding the edge weight.
277
+ If None, then each edge has weight 1.
278
+
279
+ root : node (only required for directed graphs)
280
+ A node in the directed graph `G`.
281
+
282
+ Returns
283
+ -------
284
+ total_weight : float
285
+ Undirected graphs:
286
+ The sum of the total multiplicative weights for all spanning trees in `G`.
287
+ Directed graphs:
288
+ The sum of the total multiplicative weights for all spanning trees of `G`,
289
+ rooted at node `root`.
290
+
291
+ Raises
292
+ ------
293
+ NetworkXPointlessConcept
294
+ If `G` does not contain any nodes.
295
+
296
+ NetworkXError
297
+ If the graph `G` is not (weakly) connected,
298
+ or if `G` is directed and the root node is not specified or not in G.
299
+
300
+ Examples
301
+ --------
302
+ >>> G = nx.complete_graph(5)
303
+ >>> round(nx.total_spanning_tree_weight(G))
304
+ 125
305
+
306
+ >>> G = nx.Graph()
307
+ >>> G.add_edge(1, 2, weight=2)
308
+ >>> G.add_edge(1, 3, weight=1)
309
+ >>> G.add_edge(2, 3, weight=1)
310
+ >>> round(nx.total_spanning_tree_weight(G, "weight"))
311
+ 5
312
+
313
+ Notes
314
+ -----
315
+ Self-loops are excluded. Multi-edges are contracted in one edge
316
+ equal to the sum of the weights.
317
+
318
+ References
319
+ ----------
320
+ .. [1] Wikipedia
321
+ "Kirchhoff's theorem."
322
+ https://en.wikipedia.org/wiki/Kirchhoff%27s_theorem
323
+ .. [2] Kirchhoff, G. R.
324
+ Über die Auflösung der Gleichungen, auf welche man
325
+ bei der Untersuchung der linearen Vertheilung
326
+ Galvanischer Ströme geführt wird
327
+ Annalen der Physik und Chemie, vol. 72, pp. 497-508, 1847.
328
+ .. [3] Margoliash, J.
329
+ "Matrix-Tree Theorem for Directed Graphs"
330
+ https://www.math.uchicago.edu/~may/VIGRE/VIGRE2010/REUPapers/Margoliash.pdf
331
+ """
332
+ import warnings
333
+
334
+ warnings.warn(
335
+ (
336
+ "\n\ntotal_spanning_tree_weight is deprecated and will be removed in v3.5.\n"
337
+ "Use `nx.number_of_spanning_trees(G)` instead."
338
+ ),
339
+ category=DeprecationWarning,
340
+ stacklevel=3,
341
+ )
342
+
343
+ return nx.number_of_spanning_trees(G, weight=weight, root=root)
344
+
345
+
346
+ ###############################################################################
347
+ # Code based on work from https://github.com/bjedwards
348
+
349
+
350
+ @not_implemented_for("undirected")
351
+ @not_implemented_for("multigraph")
352
+ @nx._dispatchable(edge_attrs="weight")
353
+ def directed_laplacian_matrix(
354
+ G, nodelist=None, weight="weight", walk_type=None, alpha=0.95
355
+ ):
356
+ r"""Returns the directed Laplacian matrix of G.
357
+
358
+ The graph directed Laplacian is the matrix
359
+
360
+ .. math::
361
+
362
+ L = I - \frac{1}{2} \left (\Phi^{1/2} P \Phi^{-1/2} + \Phi^{-1/2} P^T \Phi^{1/2} \right )
363
+
364
+ where `I` is the identity matrix, `P` is the transition matrix of the
365
+ graph, and `\Phi` a matrix with the Perron vector of `P` in the diagonal and
366
+ zeros elsewhere [1]_.
367
+
368
+ Depending on the value of walk_type, `P` can be the transition matrix
369
+ induced by a random walk, a lazy random walk, or a random walk with
370
+ teleportation (PageRank).
371
+
372
+ Parameters
373
+ ----------
374
+ G : DiGraph
375
+ A NetworkX graph
376
+
377
+ nodelist : list, optional
378
+ The rows and columns are ordered according to the nodes in nodelist.
379
+ If nodelist is None, then the ordering is produced by G.nodes().
380
+
381
+ weight : string or None, optional (default='weight')
382
+ The edge data key used to compute each value in the matrix.
383
+ If None, then each edge has weight 1.
384
+
385
+ walk_type : string or None, optional (default=None)
386
+ One of ``"random"``, ``"lazy"``, or ``"pagerank"``. If ``walk_type=None``
387
+ (the default), then a value is selected according to the properties of `G`:
388
+ - ``walk_type="random"`` if `G` is strongly connected and aperiodic
389
+ - ``walk_type="lazy"`` if `G` is strongly connected but not aperiodic
390
+ - ``walk_type="pagerank"`` for all other cases.
391
+
392
+ alpha : real
393
+ (1 - alpha) is the teleportation probability used with pagerank
394
+
395
+ Returns
396
+ -------
397
+ L : NumPy matrix
398
+ Normalized Laplacian of G.
399
+
400
+ Notes
401
+ -----
402
+ Only implemented for DiGraphs
403
+
404
+ The result is always a symmetric matrix.
405
+
406
+ This calculation uses the out-degree of the graph `G`. To use the
407
+ in-degree for calculations instead, use `G.reverse(copy=False)` and
408
+ take the transpose.
409
+
410
+ See Also
411
+ --------
412
+ laplacian_matrix
413
+ normalized_laplacian_matrix
414
+ directed_combinatorial_laplacian_matrix
415
+
416
+ References
417
+ ----------
418
+ .. [1] Fan Chung (2005).
419
+ Laplacians and the Cheeger inequality for directed graphs.
420
+ Annals of Combinatorics, 9(1), 2005
421
+ """
422
+ import numpy as np
423
+ import scipy as sp
424
+
425
+ # NOTE: P has type ndarray if walk_type=="pagerank", else csr_array
426
+ P = _transition_matrix(
427
+ G, nodelist=nodelist, weight=weight, walk_type=walk_type, alpha=alpha
428
+ )
429
+
430
+ n, m = P.shape
431
+
432
+ evals, evecs = sp.sparse.linalg.eigs(P.T, k=1)
433
+ v = evecs.flatten().real
434
+ p = v / v.sum()
435
+ # p>=0 by Perron-Frobenius Thm. Use abs() to fix roundoff across zero gh-6865
436
+ sqrtp = np.sqrt(np.abs(p))
437
+ Q = (
438
+ # TODO: rm csr_array wrapper when spdiags creates arrays
439
+ sp.sparse.csr_array(sp.sparse.spdiags(sqrtp, 0, n, n))
440
+ @ P
441
+ # TODO: rm csr_array wrapper when spdiags creates arrays
442
+ @ sp.sparse.csr_array(sp.sparse.spdiags(1.0 / sqrtp, 0, n, n))
443
+ )
444
+ # NOTE: This could be sparsified for the non-pagerank cases
445
+ I = np.identity(len(G))
446
+
447
+ return I - (Q + Q.T) / 2.0
448
+
449
+
450
+ @not_implemented_for("undirected")
451
+ @not_implemented_for("multigraph")
452
+ @nx._dispatchable(edge_attrs="weight")
453
+ def directed_combinatorial_laplacian_matrix(
454
+ G, nodelist=None, weight="weight", walk_type=None, alpha=0.95
455
+ ):
456
+ r"""Return the directed combinatorial Laplacian matrix of G.
457
+
458
+ The graph directed combinatorial Laplacian is the matrix
459
+
460
+ .. math::
461
+
462
+ L = \Phi - \frac{1}{2} \left (\Phi P + P^T \Phi \right)
463
+
464
+ where `P` is the transition matrix of the graph and `\Phi` a matrix
465
+ with the Perron vector of `P` in the diagonal and zeros elsewhere [1]_.
466
+
467
+ Depending on the value of walk_type, `P` can be the transition matrix
468
+ induced by a random walk, a lazy random walk, or a random walk with
469
+ teleportation (PageRank).
470
+
471
+ Parameters
472
+ ----------
473
+ G : DiGraph
474
+ A NetworkX graph
475
+
476
+ nodelist : list, optional
477
+ The rows and columns are ordered according to the nodes in nodelist.
478
+ If nodelist is None, then the ordering is produced by G.nodes().
479
+
480
+ weight : string or None, optional (default='weight')
481
+ The edge data key used to compute each value in the matrix.
482
+ If None, then each edge has weight 1.
483
+
484
+ walk_type : string or None, optional (default=None)
485
+ One of ``"random"``, ``"lazy"``, or ``"pagerank"``. If ``walk_type=None``
486
+ (the default), then a value is selected according to the properties of `G`:
487
+ - ``walk_type="random"`` if `G` is strongly connected and aperiodic
488
+ - ``walk_type="lazy"`` if `G` is strongly connected but not aperiodic
489
+ - ``walk_type="pagerank"`` for all other cases.
490
+
491
+ alpha : real
492
+ (1 - alpha) is the teleportation probability used with pagerank
493
+
494
+ Returns
495
+ -------
496
+ L : NumPy matrix
497
+ Combinatorial Laplacian of G.
498
+
499
+ Notes
500
+ -----
501
+ Only implemented for DiGraphs
502
+
503
+ The result is always a symmetric matrix.
504
+
505
+ This calculation uses the out-degree of the graph `G`. To use the
506
+ in-degree for calculations instead, use `G.reverse(copy=False)` and
507
+ take the transpose.
508
+
509
+ See Also
510
+ --------
511
+ laplacian_matrix
512
+ normalized_laplacian_matrix
513
+ directed_laplacian_matrix
514
+
515
+ References
516
+ ----------
517
+ .. [1] Fan Chung (2005).
518
+ Laplacians and the Cheeger inequality for directed graphs.
519
+ Annals of Combinatorics, 9(1), 2005
520
+ """
521
+ import scipy as sp
522
+
523
+ P = _transition_matrix(
524
+ G, nodelist=nodelist, weight=weight, walk_type=walk_type, alpha=alpha
525
+ )
526
+
527
+ n, m = P.shape
528
+
529
+ evals, evecs = sp.sparse.linalg.eigs(P.T, k=1)
530
+ v = evecs.flatten().real
531
+ p = v / v.sum()
532
+ # NOTE: could be improved by not densifying
533
+ # TODO: Rm csr_array wrapper when spdiags array creation becomes available
534
+ Phi = sp.sparse.csr_array(sp.sparse.spdiags(p, 0, n, n)).toarray()
535
+
536
+ return Phi - (Phi @ P + P.T @ Phi) / 2.0
537
+
538
+
539
+ def _transition_matrix(G, nodelist=None, weight="weight", walk_type=None, alpha=0.95):
540
+ """Returns the transition matrix of G.
541
+
542
+ This is a row stochastic giving the transition probabilities while
543
+ performing a random walk on the graph. Depending on the value of walk_type,
544
+ P can be the transition matrix induced by a random walk, a lazy random walk,
545
+ or a random walk with teleportation (PageRank).
546
+
547
+ Parameters
548
+ ----------
549
+ G : DiGraph
550
+ A NetworkX graph
551
+
552
+ nodelist : list, optional
553
+ The rows and columns are ordered according to the nodes in nodelist.
554
+ If nodelist is None, then the ordering is produced by G.nodes().
555
+
556
+ weight : string or None, optional (default='weight')
557
+ The edge data key used to compute each value in the matrix.
558
+ If None, then each edge has weight 1.
559
+
560
+ walk_type : string or None, optional (default=None)
561
+ One of ``"random"``, ``"lazy"``, or ``"pagerank"``. If ``walk_type=None``
562
+ (the default), then a value is selected according to the properties of `G`:
563
+ - ``walk_type="random"`` if `G` is strongly connected and aperiodic
564
+ - ``walk_type="lazy"`` if `G` is strongly connected but not aperiodic
565
+ - ``walk_type="pagerank"`` for all other cases.
566
+
567
+ alpha : real
568
+ (1 - alpha) is the teleportation probability used with pagerank
569
+
570
+ Returns
571
+ -------
572
+ P : numpy.ndarray
573
+ transition matrix of G.
574
+
575
+ Raises
576
+ ------
577
+ NetworkXError
578
+ If walk_type not specified or alpha not in valid range
579
+ """
580
+ import numpy as np
581
+ import scipy as sp
582
+
583
+ if walk_type is None:
584
+ if nx.is_strongly_connected(G):
585
+ if nx.is_aperiodic(G):
586
+ walk_type = "random"
587
+ else:
588
+ walk_type = "lazy"
589
+ else:
590
+ walk_type = "pagerank"
591
+
592
+ A = nx.to_scipy_sparse_array(G, nodelist=nodelist, weight=weight, dtype=float)
593
+ n, m = A.shape
594
+ if walk_type in ["random", "lazy"]:
595
+ # TODO: Rm csr_array wrapper when spdiags array creation becomes available
596
+ DI = sp.sparse.csr_array(sp.sparse.spdiags(1.0 / A.sum(axis=1), 0, n, n))
597
+ if walk_type == "random":
598
+ P = DI @ A
599
+ else:
600
+ # TODO: Rm csr_array wrapper when identity array creation becomes available
601
+ I = sp.sparse.csr_array(sp.sparse.identity(n))
602
+ P = (I + DI @ A) / 2.0
603
+
604
+ elif walk_type == "pagerank":
605
+ if not (0 < alpha < 1):
606
+ raise nx.NetworkXError("alpha must be between 0 and 1")
607
+ # this is using a dense representation. NOTE: This should be sparsified!
608
+ A = A.toarray()
609
+ # add constant to dangling nodes' row
610
+ A[A.sum(axis=1) == 0, :] = 1 / n
611
+ # normalize
612
+ A = A / A.sum(axis=1)[np.newaxis, :].T
613
+ P = alpha * A + (1 - alpha) / n
614
+ else:
615
+ raise nx.NetworkXError("walk_type must be random, lazy, or pagerank")
616
+
617
+ return P
.venv/lib/python3.11/site-packages/networkx/linalg/modularitymatrix.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Modularity matrix of graphs."""
2
+
3
+ import networkx as nx
4
+ from networkx.utils import not_implemented_for
5
+
6
+ __all__ = ["modularity_matrix", "directed_modularity_matrix"]
7
+
8
+
9
+ @not_implemented_for("directed")
10
+ @not_implemented_for("multigraph")
11
+ @nx._dispatchable(edge_attrs="weight")
12
+ def modularity_matrix(G, nodelist=None, weight=None):
13
+ r"""Returns the modularity matrix of G.
14
+
15
+ The modularity matrix is the matrix B = A - <A>, where A is the adjacency
16
+ matrix and <A> is the average adjacency matrix, assuming that the graph
17
+ is described by the configuration model.
18
+
19
+ More specifically, the element B_ij of B is defined as
20
+
21
+ .. math::
22
+ A_{ij} - {k_i k_j \over 2 m}
23
+
24
+ where k_i is the degree of node i, and where m is the number of edges
25
+ in the graph. When weight is set to a name of an attribute edge, Aij, k_i,
26
+ k_j and m are computed using its value.
27
+
28
+ Parameters
29
+ ----------
30
+ G : Graph
31
+ A NetworkX graph
32
+
33
+ nodelist : list, optional
34
+ The rows and columns are ordered according to the nodes in nodelist.
35
+ If nodelist is None, then the ordering is produced by G.nodes().
36
+
37
+ weight : string or None, optional (default=None)
38
+ The edge attribute that holds the numerical value used for
39
+ the edge weight. If None then all edge weights are 1.
40
+
41
+ Returns
42
+ -------
43
+ B : Numpy array
44
+ The modularity matrix of G.
45
+
46
+ Examples
47
+ --------
48
+ >>> k = [3, 2, 2, 1, 0]
49
+ >>> G = nx.havel_hakimi_graph(k)
50
+ >>> B = nx.modularity_matrix(G)
51
+
52
+
53
+ See Also
54
+ --------
55
+ to_numpy_array
56
+ modularity_spectrum
57
+ adjacency_matrix
58
+ directed_modularity_matrix
59
+
60
+ References
61
+ ----------
62
+ .. [1] M. E. J. Newman, "Modularity and community structure in networks",
63
+ Proc. Natl. Acad. Sci. USA, vol. 103, pp. 8577-8582, 2006.
64
+ """
65
+ import numpy as np
66
+
67
+ if nodelist is None:
68
+ nodelist = list(G)
69
+ A = nx.to_scipy_sparse_array(G, nodelist=nodelist, weight=weight, format="csr")
70
+ k = A.sum(axis=1)
71
+ m = k.sum() * 0.5
72
+ # Expected adjacency matrix
73
+ X = np.outer(k, k) / (2 * m)
74
+
75
+ return A - X
76
+
77
+
78
+ @not_implemented_for("undirected")
79
+ @not_implemented_for("multigraph")
80
+ @nx._dispatchable(edge_attrs="weight")
81
+ def directed_modularity_matrix(G, nodelist=None, weight=None):
82
+ """Returns the directed modularity matrix of G.
83
+
84
+ The modularity matrix is the matrix B = A - <A>, where A is the adjacency
85
+ matrix and <A> is the expected adjacency matrix, assuming that the graph
86
+ is described by the configuration model.
87
+
88
+ More specifically, the element B_ij of B is defined as
89
+
90
+ .. math::
91
+ B_{ij} = A_{ij} - k_i^{out} k_j^{in} / m
92
+
93
+ where :math:`k_i^{in}` is the in degree of node i, and :math:`k_j^{out}` is the out degree
94
+ of node j, with m the number of edges in the graph. When weight is set
95
+ to a name of an attribute edge, Aij, k_i, k_j and m are computed using
96
+ its value.
97
+
98
+ Parameters
99
+ ----------
100
+ G : DiGraph
101
+ A NetworkX DiGraph
102
+
103
+ nodelist : list, optional
104
+ The rows and columns are ordered according to the nodes in nodelist.
105
+ If nodelist is None, then the ordering is produced by G.nodes().
106
+
107
+ weight : string or None, optional (default=None)
108
+ The edge attribute that holds the numerical value used for
109
+ the edge weight. If None then all edge weights are 1.
110
+
111
+ Returns
112
+ -------
113
+ B : Numpy array
114
+ The modularity matrix of G.
115
+
116
+ Examples
117
+ --------
118
+ >>> G = nx.DiGraph()
119
+ >>> G.add_edges_from(
120
+ ... (
121
+ ... (1, 2),
122
+ ... (1, 3),
123
+ ... (3, 1),
124
+ ... (3, 2),
125
+ ... (3, 5),
126
+ ... (4, 5),
127
+ ... (4, 6),
128
+ ... (5, 4),
129
+ ... (5, 6),
130
+ ... (6, 4),
131
+ ... )
132
+ ... )
133
+ >>> B = nx.directed_modularity_matrix(G)
134
+
135
+
136
+ Notes
137
+ -----
138
+ NetworkX defines the element A_ij of the adjacency matrix as 1 if there
139
+ is a link going from node i to node j. Leicht and Newman use the opposite
140
+ definition. This explains the different expression for B_ij.
141
+
142
+ See Also
143
+ --------
144
+ to_numpy_array
145
+ modularity_spectrum
146
+ adjacency_matrix
147
+ modularity_matrix
148
+
149
+ References
150
+ ----------
151
+ .. [1] E. A. Leicht, M. E. J. Newman,
152
+ "Community structure in directed networks",
153
+ Phys. Rev Lett., vol. 100, no. 11, p. 118703, 2008.
154
+ """
155
+ import numpy as np
156
+
157
+ if nodelist is None:
158
+ nodelist = list(G)
159
+ A = nx.to_scipy_sparse_array(G, nodelist=nodelist, weight=weight, format="csr")
160
+ k_in = A.sum(axis=0)
161
+ k_out = A.sum(axis=1)
162
+ m = k_in.sum()
163
+ # Expected adjacency matrix
164
+ X = np.outer(k_out, k_in) / m
165
+
166
+ return A - X
.venv/lib/python3.11/site-packages/networkx/linalg/spectrum.py ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Eigenvalue spectrum of graphs.
3
+ """
4
+
5
+ import networkx as nx
6
+
7
+ __all__ = [
8
+ "laplacian_spectrum",
9
+ "adjacency_spectrum",
10
+ "modularity_spectrum",
11
+ "normalized_laplacian_spectrum",
12
+ "bethe_hessian_spectrum",
13
+ ]
14
+
15
+
16
+ @nx._dispatchable(edge_attrs="weight")
17
+ def laplacian_spectrum(G, weight="weight"):
18
+ """Returns eigenvalues of the Laplacian of G
19
+
20
+ Parameters
21
+ ----------
22
+ G : graph
23
+ A NetworkX graph
24
+
25
+ weight : string or None, optional (default='weight')
26
+ The edge data key used to compute each value in the matrix.
27
+ If None, then each edge has weight 1.
28
+
29
+ Returns
30
+ -------
31
+ evals : NumPy array
32
+ Eigenvalues
33
+
34
+ Notes
35
+ -----
36
+ For MultiGraph/MultiDiGraph, the edges weights are summed.
37
+ See :func:`~networkx.convert_matrix.to_numpy_array` for other options.
38
+
39
+ See Also
40
+ --------
41
+ laplacian_matrix
42
+
43
+ Examples
44
+ --------
45
+ The multiplicity of 0 as an eigenvalue of the laplacian matrix is equal
46
+ to the number of connected components of G.
47
+
48
+ >>> G = nx.Graph() # Create a graph with 5 nodes and 3 connected components
49
+ >>> G.add_nodes_from(range(5))
50
+ >>> G.add_edges_from([(0, 2), (3, 4)])
51
+ >>> nx.laplacian_spectrum(G)
52
+ array([0., 0., 0., 2., 2.])
53
+
54
+ """
55
+ import scipy as sp
56
+
57
+ return sp.linalg.eigvalsh(nx.laplacian_matrix(G, weight=weight).todense())
58
+
59
+
60
+ @nx._dispatchable(edge_attrs="weight")
61
+ def normalized_laplacian_spectrum(G, weight="weight"):
62
+ """Return eigenvalues of the normalized Laplacian of G
63
+
64
+ Parameters
65
+ ----------
66
+ G : graph
67
+ A NetworkX graph
68
+
69
+ weight : string or None, optional (default='weight')
70
+ The edge data key used to compute each value in the matrix.
71
+ If None, then each edge has weight 1.
72
+
73
+ Returns
74
+ -------
75
+ evals : NumPy array
76
+ Eigenvalues
77
+
78
+ Notes
79
+ -----
80
+ For MultiGraph/MultiDiGraph, the edges weights are summed.
81
+ See to_numpy_array for other options.
82
+
83
+ See Also
84
+ --------
85
+ normalized_laplacian_matrix
86
+ """
87
+ import scipy as sp
88
+
89
+ return sp.linalg.eigvalsh(
90
+ nx.normalized_laplacian_matrix(G, weight=weight).todense()
91
+ )
92
+
93
+
94
+ @nx._dispatchable(edge_attrs="weight")
95
+ def adjacency_spectrum(G, weight="weight"):
96
+ """Returns eigenvalues of the adjacency matrix of G.
97
+
98
+ Parameters
99
+ ----------
100
+ G : graph
101
+ A NetworkX graph
102
+
103
+ weight : string or None, optional (default='weight')
104
+ The edge data key used to compute each value in the matrix.
105
+ If None, then each edge has weight 1.
106
+
107
+ Returns
108
+ -------
109
+ evals : NumPy array
110
+ Eigenvalues
111
+
112
+ Notes
113
+ -----
114
+ For MultiGraph/MultiDiGraph, the edges weights are summed.
115
+ See to_numpy_array for other options.
116
+
117
+ See Also
118
+ --------
119
+ adjacency_matrix
120
+ """
121
+ import scipy as sp
122
+
123
+ return sp.linalg.eigvals(nx.adjacency_matrix(G, weight=weight).todense())
124
+
125
+
126
+ @nx._dispatchable
127
+ def modularity_spectrum(G):
128
+ """Returns eigenvalues of the modularity matrix of G.
129
+
130
+ Parameters
131
+ ----------
132
+ G : Graph
133
+ A NetworkX Graph or DiGraph
134
+
135
+ Returns
136
+ -------
137
+ evals : NumPy array
138
+ Eigenvalues
139
+
140
+ See Also
141
+ --------
142
+ modularity_matrix
143
+
144
+ References
145
+ ----------
146
+ .. [1] M. E. J. Newman, "Modularity and community structure in networks",
147
+ Proc. Natl. Acad. Sci. USA, vol. 103, pp. 8577-8582, 2006.
148
+ """
149
+ import scipy as sp
150
+
151
+ if G.is_directed():
152
+ return sp.linalg.eigvals(nx.directed_modularity_matrix(G))
153
+ else:
154
+ return sp.linalg.eigvals(nx.modularity_matrix(G))
155
+
156
+
157
+ @nx._dispatchable
158
+ def bethe_hessian_spectrum(G, r=None):
159
+ """Returns eigenvalues of the Bethe Hessian matrix of G.
160
+
161
+ Parameters
162
+ ----------
163
+ G : Graph
164
+ A NetworkX Graph or DiGraph
165
+
166
+ r : float
167
+ Regularizer parameter
168
+
169
+ Returns
170
+ -------
171
+ evals : NumPy array
172
+ Eigenvalues
173
+
174
+ See Also
175
+ --------
176
+ bethe_hessian_matrix
177
+
178
+ References
179
+ ----------
180
+ .. [1] A. Saade, F. Krzakala and L. Zdeborová
181
+ "Spectral clustering of graphs with the bethe hessian",
182
+ Advances in Neural Information Processing Systems. 2014.
183
+ """
184
+ import scipy as sp
185
+
186
+ return sp.linalg.eigvalsh(nx.bethe_hessian_matrix(G, r).todense())
.venv/lib/python3.11/site-packages/networkx/linalg/tests/__init__.py ADDED
File without changes
.venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (194 Bytes). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_algebraic_connectivity.cpython-311.pyc ADDED
Binary file (25.4 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_attrmatrix.cpython-311.pyc ADDED
Binary file (6.81 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_bethehessian.cpython-311.pyc ADDED
Binary file (2.81 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_graphmatrix.cpython-311.pyc ADDED
Binary file (14.6 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_laplacian.cpython-311.pyc ADDED
Binary file (18.2 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_modularity.cpython-311.pyc ADDED
Binary file (4.63 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/tests/__pycache__/test_spectrum.cpython-311.pyc ADDED
Binary file (6.81 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/linalg/tests/test_algebraic_connectivity.py ADDED
@@ -0,0 +1,402 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from math import sqrt
2
+
3
+ import pytest
4
+
5
+ np = pytest.importorskip("numpy")
6
+
7
+
8
+ import networkx as nx
9
+
10
+ methods = ("tracemin_pcg", "tracemin_lu", "lanczos", "lobpcg")
11
+
12
+
13
+ def test_algebraic_connectivity_tracemin_chol():
14
+ """Test that "tracemin_chol" raises an exception."""
15
+ pytest.importorskip("scipy")
16
+ G = nx.barbell_graph(5, 4)
17
+ with pytest.raises(nx.NetworkXError):
18
+ nx.algebraic_connectivity(G, method="tracemin_chol")
19
+
20
+
21
+ def test_fiedler_vector_tracemin_chol():
22
+ """Test that "tracemin_chol" raises an exception."""
23
+ pytest.importorskip("scipy")
24
+ G = nx.barbell_graph(5, 4)
25
+ with pytest.raises(nx.NetworkXError):
26
+ nx.fiedler_vector(G, method="tracemin_chol")
27
+
28
+
29
+ def test_spectral_ordering_tracemin_chol():
30
+ """Test that "tracemin_chol" raises an exception."""
31
+ pytest.importorskip("scipy")
32
+ G = nx.barbell_graph(5, 4)
33
+ with pytest.raises(nx.NetworkXError):
34
+ nx.spectral_ordering(G, method="tracemin_chol")
35
+
36
+
37
+ def test_fiedler_vector_tracemin_unknown():
38
+ """Test that "tracemin_unknown" raises an exception."""
39
+ pytest.importorskip("scipy")
40
+ G = nx.barbell_graph(5, 4)
41
+ L = nx.laplacian_matrix(G)
42
+ X = np.asarray(np.random.normal(size=(1, L.shape[0]))).T
43
+ with pytest.raises(nx.NetworkXError, match="Unknown linear system solver"):
44
+ nx.linalg.algebraicconnectivity._tracemin_fiedler(
45
+ L, X, normalized=False, tol=1e-8, method="tracemin_unknown"
46
+ )
47
+
48
+
49
+ def test_spectral_bisection():
50
+ pytest.importorskip("scipy")
51
+ G = nx.barbell_graph(3, 0)
52
+ C = nx.spectral_bisection(G)
53
+ assert C == ({0, 1, 2}, {3, 4, 5})
54
+
55
+ mapping = dict(enumerate("badfec"))
56
+ G = nx.relabel_nodes(G, mapping)
57
+ C = nx.spectral_bisection(G)
58
+ assert C == (
59
+ {mapping[0], mapping[1], mapping[2]},
60
+ {mapping[3], mapping[4], mapping[5]},
61
+ )
62
+
63
+
64
+ def check_eigenvector(A, l, x):
65
+ nx = np.linalg.norm(x)
66
+ # Check zeroness.
67
+ assert nx != pytest.approx(0, abs=1e-07)
68
+ y = A @ x
69
+ ny = np.linalg.norm(y)
70
+ # Check collinearity.
71
+ assert x @ y == pytest.approx(nx * ny, abs=1e-7)
72
+ # Check eigenvalue.
73
+ assert ny == pytest.approx(l * nx, abs=1e-7)
74
+
75
+
76
+ class TestAlgebraicConnectivity:
77
+ @pytest.mark.parametrize("method", methods)
78
+ def test_directed(self, method):
79
+ G = nx.DiGraph()
80
+ pytest.raises(
81
+ nx.NetworkXNotImplemented, nx.algebraic_connectivity, G, method=method
82
+ )
83
+ pytest.raises(nx.NetworkXNotImplemented, nx.fiedler_vector, G, method=method)
84
+
85
+ @pytest.mark.parametrize("method", methods)
86
+ def test_null_and_singleton(self, method):
87
+ G = nx.Graph()
88
+ pytest.raises(nx.NetworkXError, nx.algebraic_connectivity, G, method=method)
89
+ pytest.raises(nx.NetworkXError, nx.fiedler_vector, G, method=method)
90
+ G.add_edge(0, 0)
91
+ pytest.raises(nx.NetworkXError, nx.algebraic_connectivity, G, method=method)
92
+ pytest.raises(nx.NetworkXError, nx.fiedler_vector, G, method=method)
93
+
94
+ @pytest.mark.parametrize("method", methods)
95
+ def test_disconnected(self, method):
96
+ G = nx.Graph()
97
+ G.add_nodes_from(range(2))
98
+ assert nx.algebraic_connectivity(G) == 0
99
+ pytest.raises(nx.NetworkXError, nx.fiedler_vector, G, method=method)
100
+ G.add_edge(0, 1, weight=0)
101
+ assert nx.algebraic_connectivity(G) == 0
102
+ pytest.raises(nx.NetworkXError, nx.fiedler_vector, G, method=method)
103
+
104
+ def test_unrecognized_method(self):
105
+ pytest.importorskip("scipy")
106
+ G = nx.path_graph(4)
107
+ pytest.raises(nx.NetworkXError, nx.algebraic_connectivity, G, method="unknown")
108
+ pytest.raises(nx.NetworkXError, nx.fiedler_vector, G, method="unknown")
109
+
110
+ @pytest.mark.parametrize("method", methods)
111
+ def test_two_nodes(self, method):
112
+ pytest.importorskip("scipy")
113
+ G = nx.Graph()
114
+ G.add_edge(0, 1, weight=1)
115
+ A = nx.laplacian_matrix(G)
116
+ assert nx.algebraic_connectivity(G, tol=1e-12, method=method) == pytest.approx(
117
+ 2, abs=1e-7
118
+ )
119
+ x = nx.fiedler_vector(G, tol=1e-12, method=method)
120
+ check_eigenvector(A, 2, x)
121
+
122
+ @pytest.mark.parametrize("method", methods)
123
+ def test_two_nodes_multigraph(self, method):
124
+ pytest.importorskip("scipy")
125
+ G = nx.MultiGraph()
126
+ G.add_edge(0, 0, spam=1e8)
127
+ G.add_edge(0, 1, spam=1)
128
+ G.add_edge(0, 1, spam=-2)
129
+ A = -3 * nx.laplacian_matrix(G, weight="spam")
130
+ assert nx.algebraic_connectivity(
131
+ G, weight="spam", tol=1e-12, method=method
132
+ ) == pytest.approx(6, abs=1e-7)
133
+ x = nx.fiedler_vector(G, weight="spam", tol=1e-12, method=method)
134
+ check_eigenvector(A, 6, x)
135
+
136
+ def test_abbreviation_of_method(self):
137
+ pytest.importorskip("scipy")
138
+ G = nx.path_graph(8)
139
+ A = nx.laplacian_matrix(G)
140
+ sigma = 2 - sqrt(2 + sqrt(2))
141
+ ac = nx.algebraic_connectivity(G, tol=1e-12, method="tracemin")
142
+ assert ac == pytest.approx(sigma, abs=1e-7)
143
+ x = nx.fiedler_vector(G, tol=1e-12, method="tracemin")
144
+ check_eigenvector(A, sigma, x)
145
+
146
+ @pytest.mark.parametrize("method", methods)
147
+ def test_path(self, method):
148
+ pytest.importorskip("scipy")
149
+ G = nx.path_graph(8)
150
+ A = nx.laplacian_matrix(G)
151
+ sigma = 2 - sqrt(2 + sqrt(2))
152
+ ac = nx.algebraic_connectivity(G, tol=1e-12, method=method)
153
+ assert ac == pytest.approx(sigma, abs=1e-7)
154
+ x = nx.fiedler_vector(G, tol=1e-12, method=method)
155
+ check_eigenvector(A, sigma, x)
156
+
157
+ @pytest.mark.parametrize("method", methods)
158
+ def test_problematic_graph_issue_2381(self, method):
159
+ pytest.importorskip("scipy")
160
+ G = nx.path_graph(4)
161
+ G.add_edges_from([(4, 2), (5, 1)])
162
+ A = nx.laplacian_matrix(G)
163
+ sigma = 0.438447187191
164
+ ac = nx.algebraic_connectivity(G, tol=1e-12, method=method)
165
+ assert ac == pytest.approx(sigma, abs=1e-7)
166
+ x = nx.fiedler_vector(G, tol=1e-12, method=method)
167
+ check_eigenvector(A, sigma, x)
168
+
169
+ @pytest.mark.parametrize("method", methods)
170
+ def test_cycle(self, method):
171
+ pytest.importorskip("scipy")
172
+ G = nx.cycle_graph(8)
173
+ A = nx.laplacian_matrix(G)
174
+ sigma = 2 - sqrt(2)
175
+ ac = nx.algebraic_connectivity(G, tol=1e-12, method=method)
176
+ assert ac == pytest.approx(sigma, abs=1e-7)
177
+ x = nx.fiedler_vector(G, tol=1e-12, method=method)
178
+ check_eigenvector(A, sigma, x)
179
+
180
+ @pytest.mark.parametrize("method", methods)
181
+ def test_seed_argument(self, method):
182
+ pytest.importorskip("scipy")
183
+ G = nx.cycle_graph(8)
184
+ A = nx.laplacian_matrix(G)
185
+ sigma = 2 - sqrt(2)
186
+ ac = nx.algebraic_connectivity(G, tol=1e-12, method=method, seed=1)
187
+ assert ac == pytest.approx(sigma, abs=1e-7)
188
+ x = nx.fiedler_vector(G, tol=1e-12, method=method, seed=1)
189
+ check_eigenvector(A, sigma, x)
190
+
191
+ @pytest.mark.parametrize(
192
+ ("normalized", "sigma", "laplacian_fn"),
193
+ (
194
+ (False, 0.2434017461399311, nx.laplacian_matrix),
195
+ (True, 0.08113391537997749, nx.normalized_laplacian_matrix),
196
+ ),
197
+ )
198
+ @pytest.mark.parametrize("method", methods)
199
+ def test_buckminsterfullerene(self, normalized, sigma, laplacian_fn, method):
200
+ pytest.importorskip("scipy")
201
+ G = nx.Graph(
202
+ [
203
+ (1, 10),
204
+ (1, 41),
205
+ (1, 59),
206
+ (2, 12),
207
+ (2, 42),
208
+ (2, 60),
209
+ (3, 6),
210
+ (3, 43),
211
+ (3, 57),
212
+ (4, 8),
213
+ (4, 44),
214
+ (4, 58),
215
+ (5, 13),
216
+ (5, 56),
217
+ (5, 57),
218
+ (6, 10),
219
+ (6, 31),
220
+ (7, 14),
221
+ (7, 56),
222
+ (7, 58),
223
+ (8, 12),
224
+ (8, 32),
225
+ (9, 23),
226
+ (9, 53),
227
+ (9, 59),
228
+ (10, 15),
229
+ (11, 24),
230
+ (11, 53),
231
+ (11, 60),
232
+ (12, 16),
233
+ (13, 14),
234
+ (13, 25),
235
+ (14, 26),
236
+ (15, 27),
237
+ (15, 49),
238
+ (16, 28),
239
+ (16, 50),
240
+ (17, 18),
241
+ (17, 19),
242
+ (17, 54),
243
+ (18, 20),
244
+ (18, 55),
245
+ (19, 23),
246
+ (19, 41),
247
+ (20, 24),
248
+ (20, 42),
249
+ (21, 31),
250
+ (21, 33),
251
+ (21, 57),
252
+ (22, 32),
253
+ (22, 34),
254
+ (22, 58),
255
+ (23, 24),
256
+ (25, 35),
257
+ (25, 43),
258
+ (26, 36),
259
+ (26, 44),
260
+ (27, 51),
261
+ (27, 59),
262
+ (28, 52),
263
+ (28, 60),
264
+ (29, 33),
265
+ (29, 34),
266
+ (29, 56),
267
+ (30, 51),
268
+ (30, 52),
269
+ (30, 53),
270
+ (31, 47),
271
+ (32, 48),
272
+ (33, 45),
273
+ (34, 46),
274
+ (35, 36),
275
+ (35, 37),
276
+ (36, 38),
277
+ (37, 39),
278
+ (37, 49),
279
+ (38, 40),
280
+ (38, 50),
281
+ (39, 40),
282
+ (39, 51),
283
+ (40, 52),
284
+ (41, 47),
285
+ (42, 48),
286
+ (43, 49),
287
+ (44, 50),
288
+ (45, 46),
289
+ (45, 54),
290
+ (46, 55),
291
+ (47, 54),
292
+ (48, 55),
293
+ ]
294
+ )
295
+ A = laplacian_fn(G)
296
+ try:
297
+ assert nx.algebraic_connectivity(
298
+ G, normalized=normalized, tol=1e-12, method=method
299
+ ) == pytest.approx(sigma, abs=1e-7)
300
+ x = nx.fiedler_vector(G, normalized=normalized, tol=1e-12, method=method)
301
+ check_eigenvector(A, sigma, x)
302
+ except nx.NetworkXError as err:
303
+ if err.args not in (
304
+ ("Cholesky solver unavailable.",),
305
+ ("LU solver unavailable.",),
306
+ ):
307
+ raise
308
+
309
+
310
+ class TestSpectralOrdering:
311
+ _graphs = (nx.Graph, nx.DiGraph, nx.MultiGraph, nx.MultiDiGraph)
312
+
313
+ @pytest.mark.parametrize("graph", _graphs)
314
+ def test_nullgraph(self, graph):
315
+ G = graph()
316
+ pytest.raises(nx.NetworkXError, nx.spectral_ordering, G)
317
+
318
+ @pytest.mark.parametrize("graph", _graphs)
319
+ def test_singleton(self, graph):
320
+ G = graph()
321
+ G.add_node("x")
322
+ assert nx.spectral_ordering(G) == ["x"]
323
+ G.add_edge("x", "x", weight=33)
324
+ G.add_edge("x", "x", weight=33)
325
+ assert nx.spectral_ordering(G) == ["x"]
326
+
327
+ def test_unrecognized_method(self):
328
+ G = nx.path_graph(4)
329
+ pytest.raises(nx.NetworkXError, nx.spectral_ordering, G, method="unknown")
330
+
331
+ @pytest.mark.parametrize("method", methods)
332
+ def test_three_nodes(self, method):
333
+ pytest.importorskip("scipy")
334
+ G = nx.Graph()
335
+ G.add_weighted_edges_from([(1, 2, 1), (1, 3, 2), (2, 3, 1)], weight="spam")
336
+ order = nx.spectral_ordering(G, weight="spam", method=method)
337
+ assert set(order) == set(G)
338
+ assert {1, 3} in (set(order[:-1]), set(order[1:]))
339
+
340
+ @pytest.mark.parametrize("method", methods)
341
+ def test_three_nodes_multigraph(self, method):
342
+ pytest.importorskip("scipy")
343
+ G = nx.MultiDiGraph()
344
+ G.add_weighted_edges_from([(1, 2, 1), (1, 3, 2), (2, 3, 1), (2, 3, 2)])
345
+ order = nx.spectral_ordering(G, method=method)
346
+ assert set(order) == set(G)
347
+ assert {2, 3} in (set(order[:-1]), set(order[1:]))
348
+
349
+ @pytest.mark.parametrize("method", methods)
350
+ def test_path(self, method):
351
+ pytest.importorskip("scipy")
352
+ path = list(range(10))
353
+ np.random.shuffle(path)
354
+ G = nx.Graph()
355
+ nx.add_path(G, path)
356
+ order = nx.spectral_ordering(G, method=method)
357
+ assert order in [path, list(reversed(path))]
358
+
359
+ @pytest.mark.parametrize("method", methods)
360
+ def test_seed_argument(self, method):
361
+ pytest.importorskip("scipy")
362
+ path = list(range(10))
363
+ np.random.shuffle(path)
364
+ G = nx.Graph()
365
+ nx.add_path(G, path)
366
+ order = nx.spectral_ordering(G, method=method, seed=1)
367
+ assert order in [path, list(reversed(path))]
368
+
369
+ @pytest.mark.parametrize("method", methods)
370
+ def test_disconnected(self, method):
371
+ pytest.importorskip("scipy")
372
+ G = nx.Graph()
373
+ nx.add_path(G, range(0, 10, 2))
374
+ nx.add_path(G, range(1, 10, 2))
375
+ order = nx.spectral_ordering(G, method=method)
376
+ assert set(order) == set(G)
377
+ seqs = [
378
+ list(range(0, 10, 2)),
379
+ list(range(8, -1, -2)),
380
+ list(range(1, 10, 2)),
381
+ list(range(9, -1, -2)),
382
+ ]
383
+ assert order[:5] in seqs
384
+ assert order[5:] in seqs
385
+
386
+ @pytest.mark.parametrize(
387
+ ("normalized", "expected_order"),
388
+ (
389
+ (False, [[1, 2, 0, 3, 4, 5, 6, 9, 7, 8], [8, 7, 9, 6, 5, 4, 3, 0, 2, 1]]),
390
+ (True, [[1, 2, 3, 0, 4, 5, 9, 6, 7, 8], [8, 7, 6, 9, 5, 4, 0, 3, 2, 1]]),
391
+ ),
392
+ )
393
+ @pytest.mark.parametrize("method", methods)
394
+ def test_cycle(self, normalized, expected_order, method):
395
+ pytest.importorskip("scipy")
396
+ path = list(range(10))
397
+ G = nx.Graph()
398
+ nx.add_path(G, path, weight=5)
399
+ G.add_edge(path[-1], path[0], weight=1)
400
+ A = nx.laplacian_matrix(G).todense()
401
+ order = nx.spectral_ordering(G, normalized=normalized, method=method)
402
+ assert order in expected_order
.venv/lib/python3.11/site-packages/networkx/linalg/tests/test_attrmatrix.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ np = pytest.importorskip("numpy")
4
+
5
+ import networkx as nx
6
+
7
+
8
+ def test_attr_matrix():
9
+ G = nx.Graph()
10
+ G.add_edge(0, 1, thickness=1, weight=3)
11
+ G.add_edge(0, 1, thickness=1, weight=3)
12
+ G.add_edge(0, 2, thickness=2)
13
+ G.add_edge(1, 2, thickness=3)
14
+
15
+ def node_attr(u):
16
+ return G.nodes[u].get("size", 0.5) * 3
17
+
18
+ def edge_attr(u, v):
19
+ return G[u][v].get("thickness", 0.5)
20
+
21
+ M = nx.attr_matrix(G, edge_attr=edge_attr, node_attr=node_attr)
22
+ np.testing.assert_equal(M[0], np.array([[6.0]]))
23
+ assert M[1] == [1.5]
24
+
25
+
26
+ def test_attr_matrix_directed():
27
+ G = nx.DiGraph()
28
+ G.add_edge(0, 1, thickness=1, weight=3)
29
+ G.add_edge(0, 1, thickness=1, weight=3)
30
+ G.add_edge(0, 2, thickness=2)
31
+ G.add_edge(1, 2, thickness=3)
32
+ M = nx.attr_matrix(G, rc_order=[0, 1, 2])
33
+ # fmt: off
34
+ data = np.array(
35
+ [[0., 1., 1.],
36
+ [0., 0., 1.],
37
+ [0., 0., 0.]]
38
+ )
39
+ # fmt: on
40
+ np.testing.assert_equal(M, np.array(data))
41
+
42
+
43
+ def test_attr_matrix_multigraph():
44
+ G = nx.MultiGraph()
45
+ G.add_edge(0, 1, thickness=1, weight=3)
46
+ G.add_edge(0, 1, thickness=1, weight=3)
47
+ G.add_edge(0, 1, thickness=1, weight=3)
48
+ G.add_edge(0, 2, thickness=2)
49
+ G.add_edge(1, 2, thickness=3)
50
+ M = nx.attr_matrix(G, rc_order=[0, 1, 2])
51
+ # fmt: off
52
+ data = np.array(
53
+ [[0., 3., 1.],
54
+ [3., 0., 1.],
55
+ [1., 1., 0.]]
56
+ )
57
+ # fmt: on
58
+ np.testing.assert_equal(M, np.array(data))
59
+ M = nx.attr_matrix(G, edge_attr="weight", rc_order=[0, 1, 2])
60
+ # fmt: off
61
+ data = np.array(
62
+ [[0., 9., 1.],
63
+ [9., 0., 1.],
64
+ [1., 1., 0.]]
65
+ )
66
+ # fmt: on
67
+ np.testing.assert_equal(M, np.array(data))
68
+ M = nx.attr_matrix(G, edge_attr="thickness", rc_order=[0, 1, 2])
69
+ # fmt: off
70
+ data = np.array(
71
+ [[0., 3., 2.],
72
+ [3., 0., 3.],
73
+ [2., 3., 0.]]
74
+ )
75
+ # fmt: on
76
+ np.testing.assert_equal(M, np.array(data))
77
+
78
+
79
+ def test_attr_sparse_matrix():
80
+ pytest.importorskip("scipy")
81
+ G = nx.Graph()
82
+ G.add_edge(0, 1, thickness=1, weight=3)
83
+ G.add_edge(0, 2, thickness=2)
84
+ G.add_edge(1, 2, thickness=3)
85
+ M = nx.attr_sparse_matrix(G)
86
+ mtx = M[0]
87
+ data = np.ones((3, 3), float)
88
+ np.fill_diagonal(data, 0)
89
+ np.testing.assert_equal(mtx.todense(), np.array(data))
90
+ assert M[1] == [0, 1, 2]
91
+
92
+
93
+ def test_attr_sparse_matrix_directed():
94
+ pytest.importorskip("scipy")
95
+ G = nx.DiGraph()
96
+ G.add_edge(0, 1, thickness=1, weight=3)
97
+ G.add_edge(0, 1, thickness=1, weight=3)
98
+ G.add_edge(0, 2, thickness=2)
99
+ G.add_edge(1, 2, thickness=3)
100
+ M = nx.attr_sparse_matrix(G, rc_order=[0, 1, 2])
101
+ # fmt: off
102
+ data = np.array(
103
+ [[0., 1., 1.],
104
+ [0., 0., 1.],
105
+ [0., 0., 0.]]
106
+ )
107
+ # fmt: on
108
+ np.testing.assert_equal(M.todense(), np.array(data))
.venv/lib/python3.11/site-packages/networkx/linalg/tests/test_bethehessian.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ np = pytest.importorskip("numpy")
4
+ pytest.importorskip("scipy")
5
+
6
+ import networkx as nx
7
+ from networkx.generators.degree_seq import havel_hakimi_graph
8
+
9
+
10
+ class TestBetheHessian:
11
+ @classmethod
12
+ def setup_class(cls):
13
+ deg = [3, 2, 2, 1, 0]
14
+ cls.G = havel_hakimi_graph(deg)
15
+ cls.P = nx.path_graph(3)
16
+
17
+ def test_bethe_hessian(self):
18
+ "Bethe Hessian matrix"
19
+ # fmt: off
20
+ H = np.array([[4, -2, 0],
21
+ [-2, 5, -2],
22
+ [0, -2, 4]])
23
+ # fmt: on
24
+ permutation = [2, 0, 1]
25
+ # Bethe Hessian gives expected form
26
+ np.testing.assert_equal(nx.bethe_hessian_matrix(self.P, r=2).todense(), H)
27
+ # nodelist is correctly implemented
28
+ np.testing.assert_equal(
29
+ nx.bethe_hessian_matrix(self.P, r=2, nodelist=permutation).todense(),
30
+ H[np.ix_(permutation, permutation)],
31
+ )
32
+ # Equal to Laplacian matrix when r=1
33
+ np.testing.assert_equal(
34
+ nx.bethe_hessian_matrix(self.G, r=1).todense(),
35
+ nx.laplacian_matrix(self.G).todense(),
36
+ )
37
+ # Correct default for the regularizer r
38
+ np.testing.assert_equal(
39
+ nx.bethe_hessian_matrix(self.G).todense(),
40
+ nx.bethe_hessian_matrix(self.G, r=1.25).todense(),
41
+ )
.venv/lib/python3.11/site-packages/networkx/linalg/tests/test_graphmatrix.py ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ np = pytest.importorskip("numpy")
4
+ pytest.importorskip("scipy")
5
+
6
+ import networkx as nx
7
+ from networkx.exception import NetworkXError
8
+ from networkx.generators.degree_seq import havel_hakimi_graph
9
+
10
+
11
+ def test_incidence_matrix_simple():
12
+ deg = [3, 2, 2, 1, 0]
13
+ G = havel_hakimi_graph(deg)
14
+ deg = [(1, 0), (1, 0), (1, 0), (2, 0), (1, 0), (2, 1), (0, 1), (0, 1)]
15
+ MG = nx.random_clustered_graph(deg, seed=42)
16
+
17
+ I = nx.incidence_matrix(G, dtype=int).todense()
18
+ # fmt: off
19
+ expected = np.array(
20
+ [[1, 1, 1, 0],
21
+ [0, 1, 0, 1],
22
+ [1, 0, 0, 1],
23
+ [0, 0, 1, 0],
24
+ [0, 0, 0, 0]]
25
+ )
26
+ # fmt: on
27
+ np.testing.assert_equal(I, expected)
28
+
29
+ I = nx.incidence_matrix(MG, dtype=int).todense()
30
+ # fmt: off
31
+ expected = np.array(
32
+ [[1, 0, 0, 0, 0, 0, 0],
33
+ [1, 0, 0, 0, 0, 0, 0],
34
+ [0, 1, 0, 0, 0, 0, 0],
35
+ [0, 0, 0, 0, 0, 0, 0],
36
+ [0, 1, 0, 0, 0, 0, 0],
37
+ [0, 0, 0, 0, 1, 1, 0],
38
+ [0, 0, 0, 0, 0, 1, 1],
39
+ [0, 0, 0, 0, 1, 0, 1]]
40
+ )
41
+ # fmt: on
42
+ np.testing.assert_equal(I, expected)
43
+
44
+ with pytest.raises(NetworkXError):
45
+ nx.incidence_matrix(G, nodelist=[0, 1])
46
+
47
+
48
+ class TestGraphMatrix:
49
+ @classmethod
50
+ def setup_class(cls):
51
+ deg = [3, 2, 2, 1, 0]
52
+ cls.G = havel_hakimi_graph(deg)
53
+ # fmt: off
54
+ cls.OI = np.array(
55
+ [[-1, -1, -1, 0],
56
+ [1, 0, 0, -1],
57
+ [0, 1, 0, 1],
58
+ [0, 0, 1, 0],
59
+ [0, 0, 0, 0]]
60
+ )
61
+ cls.A = np.array(
62
+ [[0, 1, 1, 1, 0],
63
+ [1, 0, 1, 0, 0],
64
+ [1, 1, 0, 0, 0],
65
+ [1, 0, 0, 0, 0],
66
+ [0, 0, 0, 0, 0]]
67
+ )
68
+ # fmt: on
69
+ cls.WG = havel_hakimi_graph(deg)
70
+ cls.WG.add_edges_from(
71
+ (u, v, {"weight": 0.5, "other": 0.3}) for (u, v) in cls.G.edges()
72
+ )
73
+ # fmt: off
74
+ cls.WA = np.array(
75
+ [[0, 0.5, 0.5, 0.5, 0],
76
+ [0.5, 0, 0.5, 0, 0],
77
+ [0.5, 0.5, 0, 0, 0],
78
+ [0.5, 0, 0, 0, 0],
79
+ [0, 0, 0, 0, 0]]
80
+ )
81
+ # fmt: on
82
+ cls.MG = nx.MultiGraph(cls.G)
83
+ cls.MG2 = cls.MG.copy()
84
+ cls.MG2.add_edge(0, 1)
85
+ # fmt: off
86
+ cls.MG2A = np.array(
87
+ [[0, 2, 1, 1, 0],
88
+ [2, 0, 1, 0, 0],
89
+ [1, 1, 0, 0, 0],
90
+ [1, 0, 0, 0, 0],
91
+ [0, 0, 0, 0, 0]]
92
+ )
93
+ cls.MGOI = np.array(
94
+ [[-1, -1, -1, -1, 0],
95
+ [1, 1, 0, 0, -1],
96
+ [0, 0, 1, 0, 1],
97
+ [0, 0, 0, 1, 0],
98
+ [0, 0, 0, 0, 0]]
99
+ )
100
+ # fmt: on
101
+ cls.no_edges_G = nx.Graph([(1, 2), (3, 2, {"weight": 8})])
102
+ cls.no_edges_A = np.array([[0, 0], [0, 0]])
103
+
104
+ def test_incidence_matrix(self):
105
+ "Conversion to incidence matrix"
106
+ I = nx.incidence_matrix(
107
+ self.G,
108
+ nodelist=sorted(self.G),
109
+ edgelist=sorted(self.G.edges()),
110
+ oriented=True,
111
+ dtype=int,
112
+ ).todense()
113
+ np.testing.assert_equal(I, self.OI)
114
+
115
+ I = nx.incidence_matrix(
116
+ self.G,
117
+ nodelist=sorted(self.G),
118
+ edgelist=sorted(self.G.edges()),
119
+ oriented=False,
120
+ dtype=int,
121
+ ).todense()
122
+ np.testing.assert_equal(I, np.abs(self.OI))
123
+
124
+ I = nx.incidence_matrix(
125
+ self.MG,
126
+ nodelist=sorted(self.MG),
127
+ edgelist=sorted(self.MG.edges()),
128
+ oriented=True,
129
+ dtype=int,
130
+ ).todense()
131
+ np.testing.assert_equal(I, self.OI)
132
+
133
+ I = nx.incidence_matrix(
134
+ self.MG,
135
+ nodelist=sorted(self.MG),
136
+ edgelist=sorted(self.MG.edges()),
137
+ oriented=False,
138
+ dtype=int,
139
+ ).todense()
140
+ np.testing.assert_equal(I, np.abs(self.OI))
141
+
142
+ I = nx.incidence_matrix(
143
+ self.MG2,
144
+ nodelist=sorted(self.MG2),
145
+ edgelist=sorted(self.MG2.edges()),
146
+ oriented=True,
147
+ dtype=int,
148
+ ).todense()
149
+ np.testing.assert_equal(I, self.MGOI)
150
+
151
+ I = nx.incidence_matrix(
152
+ self.MG2,
153
+ nodelist=sorted(self.MG),
154
+ edgelist=sorted(self.MG2.edges()),
155
+ oriented=False,
156
+ dtype=int,
157
+ ).todense()
158
+ np.testing.assert_equal(I, np.abs(self.MGOI))
159
+
160
+ I = nx.incidence_matrix(self.G, dtype=np.uint8)
161
+ assert I.dtype == np.uint8
162
+
163
+ def test_weighted_incidence_matrix(self):
164
+ I = nx.incidence_matrix(
165
+ self.WG,
166
+ nodelist=sorted(self.WG),
167
+ edgelist=sorted(self.WG.edges()),
168
+ oriented=True,
169
+ dtype=int,
170
+ ).todense()
171
+ np.testing.assert_equal(I, self.OI)
172
+
173
+ I = nx.incidence_matrix(
174
+ self.WG,
175
+ nodelist=sorted(self.WG),
176
+ edgelist=sorted(self.WG.edges()),
177
+ oriented=False,
178
+ dtype=int,
179
+ ).todense()
180
+ np.testing.assert_equal(I, np.abs(self.OI))
181
+
182
+ # np.testing.assert_equal(nx.incidence_matrix(self.WG,oriented=True,
183
+ # weight='weight').todense(),0.5*self.OI)
184
+ # np.testing.assert_equal(nx.incidence_matrix(self.WG,weight='weight').todense(),
185
+ # np.abs(0.5*self.OI))
186
+ # np.testing.assert_equal(nx.incidence_matrix(self.WG,oriented=True,weight='other').todense(),
187
+ # 0.3*self.OI)
188
+
189
+ I = nx.incidence_matrix(
190
+ self.WG,
191
+ nodelist=sorted(self.WG),
192
+ edgelist=sorted(self.WG.edges()),
193
+ oriented=True,
194
+ weight="weight",
195
+ ).todense()
196
+ np.testing.assert_equal(I, 0.5 * self.OI)
197
+
198
+ I = nx.incidence_matrix(
199
+ self.WG,
200
+ nodelist=sorted(self.WG),
201
+ edgelist=sorted(self.WG.edges()),
202
+ oriented=False,
203
+ weight="weight",
204
+ ).todense()
205
+ np.testing.assert_equal(I, np.abs(0.5 * self.OI))
206
+
207
+ I = nx.incidence_matrix(
208
+ self.WG,
209
+ nodelist=sorted(self.WG),
210
+ edgelist=sorted(self.WG.edges()),
211
+ oriented=True,
212
+ weight="other",
213
+ ).todense()
214
+ np.testing.assert_equal(I, 0.3 * self.OI)
215
+
216
+ # WMG=nx.MultiGraph(self.WG)
217
+ # WMG.add_edge(0,1,weight=0.5,other=0.3)
218
+ # np.testing.assert_equal(nx.incidence_matrix(WMG,weight='weight').todense(),
219
+ # np.abs(0.5*self.MGOI))
220
+ # np.testing.assert_equal(nx.incidence_matrix(WMG,weight='weight',oriented=True).todense(),
221
+ # 0.5*self.MGOI)
222
+ # np.testing.assert_equal(nx.incidence_matrix(WMG,weight='other',oriented=True).todense(),
223
+ # 0.3*self.MGOI)
224
+
225
+ WMG = nx.MultiGraph(self.WG)
226
+ WMG.add_edge(0, 1, weight=0.5, other=0.3)
227
+
228
+ I = nx.incidence_matrix(
229
+ WMG,
230
+ nodelist=sorted(WMG),
231
+ edgelist=sorted(WMG.edges(keys=True)),
232
+ oriented=True,
233
+ weight="weight",
234
+ ).todense()
235
+ np.testing.assert_equal(I, 0.5 * self.MGOI)
236
+
237
+ I = nx.incidence_matrix(
238
+ WMG,
239
+ nodelist=sorted(WMG),
240
+ edgelist=sorted(WMG.edges(keys=True)),
241
+ oriented=False,
242
+ weight="weight",
243
+ ).todense()
244
+ np.testing.assert_equal(I, np.abs(0.5 * self.MGOI))
245
+
246
+ I = nx.incidence_matrix(
247
+ WMG,
248
+ nodelist=sorted(WMG),
249
+ edgelist=sorted(WMG.edges(keys=True)),
250
+ oriented=True,
251
+ weight="other",
252
+ ).todense()
253
+ np.testing.assert_equal(I, 0.3 * self.MGOI)
254
+
255
+ def test_adjacency_matrix(self):
256
+ "Conversion to adjacency matrix"
257
+ np.testing.assert_equal(nx.adjacency_matrix(self.G).todense(), self.A)
258
+ np.testing.assert_equal(nx.adjacency_matrix(self.MG).todense(), self.A)
259
+ np.testing.assert_equal(nx.adjacency_matrix(self.MG2).todense(), self.MG2A)
260
+ np.testing.assert_equal(
261
+ nx.adjacency_matrix(self.G, nodelist=[0, 1]).todense(), self.A[:2, :2]
262
+ )
263
+ np.testing.assert_equal(nx.adjacency_matrix(self.WG).todense(), self.WA)
264
+ np.testing.assert_equal(
265
+ nx.adjacency_matrix(self.WG, weight=None).todense(), self.A
266
+ )
267
+ np.testing.assert_equal(
268
+ nx.adjacency_matrix(self.MG2, weight=None).todense(), self.MG2A
269
+ )
270
+ np.testing.assert_equal(
271
+ nx.adjacency_matrix(self.WG, weight="other").todense(), 0.6 * self.WA
272
+ )
273
+ np.testing.assert_equal(
274
+ nx.adjacency_matrix(self.no_edges_G, nodelist=[1, 3]).todense(),
275
+ self.no_edges_A,
276
+ )
.venv/lib/python3.11/site-packages/networkx/linalg/tests/test_laplacian.py ADDED
@@ -0,0 +1,336 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ np = pytest.importorskip("numpy")
4
+ pytest.importorskip("scipy")
5
+
6
+ import networkx as nx
7
+ from networkx.generators.degree_seq import havel_hakimi_graph
8
+ from networkx.generators.expanders import margulis_gabber_galil_graph
9
+
10
+
11
+ class TestLaplacian:
12
+ @classmethod
13
+ def setup_class(cls):
14
+ deg = [3, 2, 2, 1, 0]
15
+ cls.G = havel_hakimi_graph(deg)
16
+ cls.WG = nx.Graph(
17
+ (u, v, {"weight": 0.5, "other": 0.3}) for (u, v) in cls.G.edges()
18
+ )
19
+ cls.WG.add_node(4)
20
+ cls.MG = nx.MultiGraph(cls.G)
21
+
22
+ # Graph with clsloops
23
+ cls.Gsl = cls.G.copy()
24
+ for node in cls.Gsl.nodes():
25
+ cls.Gsl.add_edge(node, node)
26
+
27
+ # Graph used as an example in Sec. 4.1 of Langville and Meyer,
28
+ # "Google's PageRank and Beyond".
29
+ cls.DiG = nx.DiGraph()
30
+ cls.DiG.add_edges_from(
31
+ (
32
+ (1, 2),
33
+ (1, 3),
34
+ (3, 1),
35
+ (3, 2),
36
+ (3, 5),
37
+ (4, 5),
38
+ (4, 6),
39
+ (5, 4),
40
+ (5, 6),
41
+ (6, 4),
42
+ )
43
+ )
44
+ cls.DiMG = nx.MultiDiGraph(cls.DiG)
45
+ cls.DiWG = nx.DiGraph(
46
+ (u, v, {"weight": 0.5, "other": 0.3}) for (u, v) in cls.DiG.edges()
47
+ )
48
+ cls.DiGsl = cls.DiG.copy()
49
+ for node in cls.DiGsl.nodes():
50
+ cls.DiGsl.add_edge(node, node)
51
+
52
+ def test_laplacian(self):
53
+ "Graph Laplacian"
54
+ # fmt: off
55
+ NL = np.array([[ 3, -1, -1, -1, 0],
56
+ [-1, 2, -1, 0, 0],
57
+ [-1, -1, 2, 0, 0],
58
+ [-1, 0, 0, 1, 0],
59
+ [ 0, 0, 0, 0, 0]])
60
+ # fmt: on
61
+ WL = 0.5 * NL
62
+ OL = 0.3 * NL
63
+ # fmt: off
64
+ DiNL = np.array([[ 2, -1, -1, 0, 0, 0],
65
+ [ 0, 0, 0, 0, 0, 0],
66
+ [-1, -1, 3, -1, 0, 0],
67
+ [ 0, 0, 0, 2, -1, -1],
68
+ [ 0, 0, 0, -1, 2, -1],
69
+ [ 0, 0, 0, 0, -1, 1]])
70
+ # fmt: on
71
+ DiWL = 0.5 * DiNL
72
+ DiOL = 0.3 * DiNL
73
+ np.testing.assert_equal(nx.laplacian_matrix(self.G).todense(), NL)
74
+ np.testing.assert_equal(nx.laplacian_matrix(self.MG).todense(), NL)
75
+ np.testing.assert_equal(
76
+ nx.laplacian_matrix(self.G, nodelist=[0, 1]).todense(),
77
+ np.array([[1, -1], [-1, 1]]),
78
+ )
79
+ np.testing.assert_equal(nx.laplacian_matrix(self.WG).todense(), WL)
80
+ np.testing.assert_equal(nx.laplacian_matrix(self.WG, weight=None).todense(), NL)
81
+ np.testing.assert_equal(
82
+ nx.laplacian_matrix(self.WG, weight="other").todense(), OL
83
+ )
84
+
85
+ np.testing.assert_equal(nx.laplacian_matrix(self.DiG).todense(), DiNL)
86
+ np.testing.assert_equal(nx.laplacian_matrix(self.DiMG).todense(), DiNL)
87
+ np.testing.assert_equal(
88
+ nx.laplacian_matrix(self.DiG, nodelist=[1, 2]).todense(),
89
+ np.array([[1, -1], [0, 0]]),
90
+ )
91
+ np.testing.assert_equal(nx.laplacian_matrix(self.DiWG).todense(), DiWL)
92
+ np.testing.assert_equal(
93
+ nx.laplacian_matrix(self.DiWG, weight=None).todense(), DiNL
94
+ )
95
+ np.testing.assert_equal(
96
+ nx.laplacian_matrix(self.DiWG, weight="other").todense(), DiOL
97
+ )
98
+
99
+ def test_normalized_laplacian(self):
100
+ "Generalized Graph Laplacian"
101
+ # fmt: off
102
+ G = np.array([[ 1. , -0.408, -0.408, -0.577, 0.],
103
+ [-0.408, 1. , -0.5 , 0. , 0.],
104
+ [-0.408, -0.5 , 1. , 0. , 0.],
105
+ [-0.577, 0. , 0. , 1. , 0.],
106
+ [ 0. , 0. , 0. , 0. , 0.]])
107
+ GL = np.array([[ 1. , -0.408, -0.408, -0.577, 0. ],
108
+ [-0.408, 1. , -0.5 , 0. , 0. ],
109
+ [-0.408, -0.5 , 1. , 0. , 0. ],
110
+ [-0.577, 0. , 0. , 1. , 0. ],
111
+ [ 0. , 0. , 0. , 0. , 0. ]])
112
+ Lsl = np.array([[ 0.75 , -0.2887, -0.2887, -0.3536, 0. ],
113
+ [-0.2887, 0.6667, -0.3333, 0. , 0. ],
114
+ [-0.2887, -0.3333, 0.6667, 0. , 0. ],
115
+ [-0.3536, 0. , 0. , 0.5 , 0. ],
116
+ [ 0. , 0. , 0. , 0. , 0. ]])
117
+
118
+ DiG = np.array([[ 1. , 0. , -0.4082, 0. , 0. , 0. ],
119
+ [ 0. , 0. , 0. , 0. , 0. , 0. ],
120
+ [-0.4082, 0. , 1. , 0. , -0.4082, 0. ],
121
+ [ 0. , 0. , 0. , 1. , -0.5 , -0.7071],
122
+ [ 0. , 0. , 0. , -0.5 , 1. , -0.7071],
123
+ [ 0. , 0. , 0. , -0.7071, 0. , 1. ]])
124
+ DiGL = np.array([[ 1. , 0. , -0.4082, 0. , 0. , 0. ],
125
+ [ 0. , 0. , 0. , 0. , 0. , 0. ],
126
+ [-0.4082, 0. , 1. , -0.4082, 0. , 0. ],
127
+ [ 0. , 0. , 0. , 1. , -0.5 , -0.7071],
128
+ [ 0. , 0. , 0. , -0.5 , 1. , -0.7071],
129
+ [ 0. , 0. , 0. , 0. , -0.7071, 1. ]])
130
+ DiLsl = np.array([[ 0.6667, -0.5774, -0.2887, 0. , 0. , 0. ],
131
+ [ 0. , 0. , 0. , 0. , 0. , 0. ],
132
+ [-0.2887, -0.5 , 0.75 , -0.2887, 0. , 0. ],
133
+ [ 0. , 0. , 0. , 0.6667, -0.3333, -0.4082],
134
+ [ 0. , 0. , 0. , -0.3333, 0.6667, -0.4082],
135
+ [ 0. , 0. , 0. , 0. , -0.4082, 0.5 ]])
136
+ # fmt: on
137
+
138
+ np.testing.assert_almost_equal(
139
+ nx.normalized_laplacian_matrix(self.G, nodelist=range(5)).todense(),
140
+ G,
141
+ decimal=3,
142
+ )
143
+ np.testing.assert_almost_equal(
144
+ nx.normalized_laplacian_matrix(self.G).todense(), GL, decimal=3
145
+ )
146
+ np.testing.assert_almost_equal(
147
+ nx.normalized_laplacian_matrix(self.MG).todense(), GL, decimal=3
148
+ )
149
+ np.testing.assert_almost_equal(
150
+ nx.normalized_laplacian_matrix(self.WG).todense(), GL, decimal=3
151
+ )
152
+ np.testing.assert_almost_equal(
153
+ nx.normalized_laplacian_matrix(self.WG, weight="other").todense(),
154
+ GL,
155
+ decimal=3,
156
+ )
157
+ np.testing.assert_almost_equal(
158
+ nx.normalized_laplacian_matrix(self.Gsl).todense(), Lsl, decimal=3
159
+ )
160
+
161
+ np.testing.assert_almost_equal(
162
+ nx.normalized_laplacian_matrix(
163
+ self.DiG,
164
+ nodelist=range(1, 1 + 6),
165
+ ).todense(),
166
+ DiG,
167
+ decimal=3,
168
+ )
169
+ np.testing.assert_almost_equal(
170
+ nx.normalized_laplacian_matrix(self.DiG).todense(), DiGL, decimal=3
171
+ )
172
+ np.testing.assert_almost_equal(
173
+ nx.normalized_laplacian_matrix(self.DiMG).todense(), DiGL, decimal=3
174
+ )
175
+ np.testing.assert_almost_equal(
176
+ nx.normalized_laplacian_matrix(self.DiWG).todense(), DiGL, decimal=3
177
+ )
178
+ np.testing.assert_almost_equal(
179
+ nx.normalized_laplacian_matrix(self.DiWG, weight="other").todense(),
180
+ DiGL,
181
+ decimal=3,
182
+ )
183
+ np.testing.assert_almost_equal(
184
+ nx.normalized_laplacian_matrix(self.DiGsl).todense(), DiLsl, decimal=3
185
+ )
186
+
187
+
188
+ def test_directed_laplacian():
189
+ "Directed Laplacian"
190
+ # Graph used as an example in Sec. 4.1 of Langville and Meyer,
191
+ # "Google's PageRank and Beyond". The graph contains dangling nodes, so
192
+ # the pagerank random walk is selected by directed_laplacian
193
+ G = nx.DiGraph()
194
+ G.add_edges_from(
195
+ (
196
+ (1, 2),
197
+ (1, 3),
198
+ (3, 1),
199
+ (3, 2),
200
+ (3, 5),
201
+ (4, 5),
202
+ (4, 6),
203
+ (5, 4),
204
+ (5, 6),
205
+ (6, 4),
206
+ )
207
+ )
208
+ # fmt: off
209
+ GL = np.array([[ 0.9833, -0.2941, -0.3882, -0.0291, -0.0231, -0.0261],
210
+ [-0.2941, 0.8333, -0.2339, -0.0536, -0.0589, -0.0554],
211
+ [-0.3882, -0.2339, 0.9833, -0.0278, -0.0896, -0.0251],
212
+ [-0.0291, -0.0536, -0.0278, 0.9833, -0.4878, -0.6675],
213
+ [-0.0231, -0.0589, -0.0896, -0.4878, 0.9833, -0.2078],
214
+ [-0.0261, -0.0554, -0.0251, -0.6675, -0.2078, 0.9833]])
215
+ # fmt: on
216
+ L = nx.directed_laplacian_matrix(G, alpha=0.9, nodelist=sorted(G))
217
+ np.testing.assert_almost_equal(L, GL, decimal=3)
218
+
219
+ # Make the graph strongly connected, so we can use a random and lazy walk
220
+ G.add_edges_from(((2, 5), (6, 1)))
221
+ # fmt: off
222
+ GL = np.array([[ 1. , -0.3062, -0.4714, 0. , 0. , -0.3227],
223
+ [-0.3062, 1. , -0.1443, 0. , -0.3162, 0. ],
224
+ [-0.4714, -0.1443, 1. , 0. , -0.0913, 0. ],
225
+ [ 0. , 0. , 0. , 1. , -0.5 , -0.5 ],
226
+ [ 0. , -0.3162, -0.0913, -0.5 , 1. , -0.25 ],
227
+ [-0.3227, 0. , 0. , -0.5 , -0.25 , 1. ]])
228
+ # fmt: on
229
+ L = nx.directed_laplacian_matrix(
230
+ G, alpha=0.9, nodelist=sorted(G), walk_type="random"
231
+ )
232
+ np.testing.assert_almost_equal(L, GL, decimal=3)
233
+
234
+ # fmt: off
235
+ GL = np.array([[ 0.5 , -0.1531, -0.2357, 0. , 0. , -0.1614],
236
+ [-0.1531, 0.5 , -0.0722, 0. , -0.1581, 0. ],
237
+ [-0.2357, -0.0722, 0.5 , 0. , -0.0456, 0. ],
238
+ [ 0. , 0. , 0. , 0.5 , -0.25 , -0.25 ],
239
+ [ 0. , -0.1581, -0.0456, -0.25 , 0.5 , -0.125 ],
240
+ [-0.1614, 0. , 0. , -0.25 , -0.125 , 0.5 ]])
241
+ # fmt: on
242
+ L = nx.directed_laplacian_matrix(G, alpha=0.9, nodelist=sorted(G), walk_type="lazy")
243
+ np.testing.assert_almost_equal(L, GL, decimal=3)
244
+
245
+ # Make a strongly connected periodic graph
246
+ G = nx.DiGraph()
247
+ G.add_edges_from(((1, 2), (2, 4), (4, 1), (1, 3), (3, 4)))
248
+ # fmt: off
249
+ GL = np.array([[ 0.5 , -0.176, -0.176, -0.25 ],
250
+ [-0.176, 0.5 , 0. , -0.176],
251
+ [-0.176, 0. , 0.5 , -0.176],
252
+ [-0.25 , -0.176, -0.176, 0.5 ]])
253
+ # fmt: on
254
+ L = nx.directed_laplacian_matrix(G, alpha=0.9, nodelist=sorted(G))
255
+ np.testing.assert_almost_equal(L, GL, decimal=3)
256
+
257
+
258
+ def test_directed_combinatorial_laplacian():
259
+ "Directed combinatorial Laplacian"
260
+ # Graph used as an example in Sec. 4.1 of Langville and Meyer,
261
+ # "Google's PageRank and Beyond". The graph contains dangling nodes, so
262
+ # the pagerank random walk is selected by directed_laplacian
263
+ G = nx.DiGraph()
264
+ G.add_edges_from(
265
+ (
266
+ (1, 2),
267
+ (1, 3),
268
+ (3, 1),
269
+ (3, 2),
270
+ (3, 5),
271
+ (4, 5),
272
+ (4, 6),
273
+ (5, 4),
274
+ (5, 6),
275
+ (6, 4),
276
+ )
277
+ )
278
+ # fmt: off
279
+ GL = np.array([[ 0.0366, -0.0132, -0.0153, -0.0034, -0.0020, -0.0027],
280
+ [-0.0132, 0.0450, -0.0111, -0.0076, -0.0062, -0.0069],
281
+ [-0.0153, -0.0111, 0.0408, -0.0035, -0.0083, -0.0027],
282
+ [-0.0034, -0.0076, -0.0035, 0.3688, -0.1356, -0.2187],
283
+ [-0.0020, -0.0062, -0.0083, -0.1356, 0.2026, -0.0505],
284
+ [-0.0027, -0.0069, -0.0027, -0.2187, -0.0505, 0.2815]])
285
+ # fmt: on
286
+
287
+ L = nx.directed_combinatorial_laplacian_matrix(G, alpha=0.9, nodelist=sorted(G))
288
+ np.testing.assert_almost_equal(L, GL, decimal=3)
289
+
290
+ # Make the graph strongly connected, so we can use a random and lazy walk
291
+ G.add_edges_from(((2, 5), (6, 1)))
292
+
293
+ # fmt: off
294
+ GL = np.array([[ 0.1395, -0.0349, -0.0465, 0. , 0. , -0.0581],
295
+ [-0.0349, 0.093 , -0.0116, 0. , -0.0465, 0. ],
296
+ [-0.0465, -0.0116, 0.0698, 0. , -0.0116, 0. ],
297
+ [ 0. , 0. , 0. , 0.2326, -0.1163, -0.1163],
298
+ [ 0. , -0.0465, -0.0116, -0.1163, 0.2326, -0.0581],
299
+ [-0.0581, 0. , 0. , -0.1163, -0.0581, 0.2326]])
300
+ # fmt: on
301
+
302
+ L = nx.directed_combinatorial_laplacian_matrix(
303
+ G, alpha=0.9, nodelist=sorted(G), walk_type="random"
304
+ )
305
+ np.testing.assert_almost_equal(L, GL, decimal=3)
306
+
307
+ # fmt: off
308
+ GL = np.array([[ 0.0698, -0.0174, -0.0233, 0. , 0. , -0.0291],
309
+ [-0.0174, 0.0465, -0.0058, 0. , -0.0233, 0. ],
310
+ [-0.0233, -0.0058, 0.0349, 0. , -0.0058, 0. ],
311
+ [ 0. , 0. , 0. , 0.1163, -0.0581, -0.0581],
312
+ [ 0. , -0.0233, -0.0058, -0.0581, 0.1163, -0.0291],
313
+ [-0.0291, 0. , 0. , -0.0581, -0.0291, 0.1163]])
314
+ # fmt: on
315
+
316
+ L = nx.directed_combinatorial_laplacian_matrix(
317
+ G, alpha=0.9, nodelist=sorted(G), walk_type="lazy"
318
+ )
319
+ np.testing.assert_almost_equal(L, GL, decimal=3)
320
+
321
+ E = nx.DiGraph(margulis_gabber_galil_graph(2))
322
+ L = nx.directed_combinatorial_laplacian_matrix(E)
323
+ # fmt: off
324
+ expected = np.array(
325
+ [[ 0.16666667, -0.08333333, -0.08333333, 0. ],
326
+ [-0.08333333, 0.16666667, 0. , -0.08333333],
327
+ [-0.08333333, 0. , 0.16666667, -0.08333333],
328
+ [ 0. , -0.08333333, -0.08333333, 0.16666667]]
329
+ )
330
+ # fmt: on
331
+ np.testing.assert_almost_equal(L, expected, decimal=6)
332
+
333
+ with pytest.raises(nx.NetworkXError):
334
+ nx.directed_combinatorial_laplacian_matrix(G, walk_type="pagerank", alpha=100)
335
+ with pytest.raises(nx.NetworkXError):
336
+ nx.directed_combinatorial_laplacian_matrix(G, walk_type="silly")
.venv/lib/python3.11/site-packages/networkx/linalg/tests/test_modularity.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ np = pytest.importorskip("numpy")
4
+ pytest.importorskip("scipy")
5
+
6
+ import networkx as nx
7
+ from networkx.generators.degree_seq import havel_hakimi_graph
8
+
9
+
10
+ class TestModularity:
11
+ @classmethod
12
+ def setup_class(cls):
13
+ deg = [3, 2, 2, 1, 0]
14
+ cls.G = havel_hakimi_graph(deg)
15
+ # Graph used as an example in Sec. 4.1 of Langville and Meyer,
16
+ # "Google's PageRank and Beyond". (Used for test_directed_laplacian)
17
+ cls.DG = nx.DiGraph()
18
+ cls.DG.add_edges_from(
19
+ (
20
+ (1, 2),
21
+ (1, 3),
22
+ (3, 1),
23
+ (3, 2),
24
+ (3, 5),
25
+ (4, 5),
26
+ (4, 6),
27
+ (5, 4),
28
+ (5, 6),
29
+ (6, 4),
30
+ )
31
+ )
32
+
33
+ def test_modularity(self):
34
+ "Modularity matrix"
35
+ # fmt: off
36
+ B = np.array([[-1.125, 0.25, 0.25, 0.625, 0.],
37
+ [0.25, -0.5, 0.5, -0.25, 0.],
38
+ [0.25, 0.5, -0.5, -0.25, 0.],
39
+ [0.625, -0.25, -0.25, -0.125, 0.],
40
+ [0., 0., 0., 0., 0.]])
41
+ # fmt: on
42
+
43
+ permutation = [4, 0, 1, 2, 3]
44
+ np.testing.assert_equal(nx.modularity_matrix(self.G), B)
45
+ np.testing.assert_equal(
46
+ nx.modularity_matrix(self.G, nodelist=permutation),
47
+ B[np.ix_(permutation, permutation)],
48
+ )
49
+
50
+ def test_modularity_weight(self):
51
+ "Modularity matrix with weights"
52
+ # fmt: off
53
+ B = np.array([[-1.125, 0.25, 0.25, 0.625, 0.],
54
+ [0.25, -0.5, 0.5, -0.25, 0.],
55
+ [0.25, 0.5, -0.5, -0.25, 0.],
56
+ [0.625, -0.25, -0.25, -0.125, 0.],
57
+ [0., 0., 0., 0., 0.]])
58
+ # fmt: on
59
+
60
+ G_weighted = self.G.copy()
61
+ for n1, n2 in G_weighted.edges():
62
+ G_weighted.edges[n1, n2]["weight"] = 0.5
63
+ # The following test would fail in networkx 1.1
64
+ np.testing.assert_equal(nx.modularity_matrix(G_weighted), B)
65
+ # The following test that the modularity matrix get rescaled accordingly
66
+ np.testing.assert_equal(
67
+ nx.modularity_matrix(G_weighted, weight="weight"), 0.5 * B
68
+ )
69
+
70
+ def test_directed_modularity(self):
71
+ "Directed Modularity matrix"
72
+ # fmt: off
73
+ B = np.array([[-0.2, 0.6, 0.8, -0.4, -0.4, -0.4],
74
+ [0., 0., 0., 0., 0., 0.],
75
+ [0.7, 0.4, -0.3, -0.6, 0.4, -0.6],
76
+ [-0.2, -0.4, -0.2, -0.4, 0.6, 0.6],
77
+ [-0.2, -0.4, -0.2, 0.6, -0.4, 0.6],
78
+ [-0.1, -0.2, -0.1, 0.8, -0.2, -0.2]])
79
+ # fmt: on
80
+ node_permutation = [5, 1, 2, 3, 4, 6]
81
+ idx_permutation = [4, 0, 1, 2, 3, 5]
82
+ mm = nx.directed_modularity_matrix(self.DG, nodelist=sorted(self.DG))
83
+ np.testing.assert_equal(mm, B)
84
+ np.testing.assert_equal(
85
+ nx.directed_modularity_matrix(self.DG, nodelist=node_permutation),
86
+ B[np.ix_(idx_permutation, idx_permutation)],
87
+ )
.venv/lib/python3.11/site-packages/networkx/linalg/tests/test_spectrum.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ np = pytest.importorskip("numpy")
4
+ pytest.importorskip("scipy")
5
+
6
+ import networkx as nx
7
+ from networkx.generators.degree_seq import havel_hakimi_graph
8
+
9
+
10
+ class TestSpectrum:
11
+ @classmethod
12
+ def setup_class(cls):
13
+ deg = [3, 2, 2, 1, 0]
14
+ cls.G = havel_hakimi_graph(deg)
15
+ cls.P = nx.path_graph(3)
16
+ cls.WG = nx.Graph(
17
+ (u, v, {"weight": 0.5, "other": 0.3}) for (u, v) in cls.G.edges()
18
+ )
19
+ cls.WG.add_node(4)
20
+ cls.DG = nx.DiGraph()
21
+ nx.add_path(cls.DG, [0, 1, 2])
22
+
23
+ def test_laplacian_spectrum(self):
24
+ "Laplacian eigenvalues"
25
+ evals = np.array([0, 0, 1, 3, 4])
26
+ e = sorted(nx.laplacian_spectrum(self.G))
27
+ np.testing.assert_almost_equal(e, evals)
28
+ e = sorted(nx.laplacian_spectrum(self.WG, weight=None))
29
+ np.testing.assert_almost_equal(e, evals)
30
+ e = sorted(nx.laplacian_spectrum(self.WG))
31
+ np.testing.assert_almost_equal(e, 0.5 * evals)
32
+ e = sorted(nx.laplacian_spectrum(self.WG, weight="other"))
33
+ np.testing.assert_almost_equal(e, 0.3 * evals)
34
+
35
+ def test_normalized_laplacian_spectrum(self):
36
+ "Normalized Laplacian eigenvalues"
37
+ evals = np.array([0, 0, 0.7712864461218, 1.5, 1.7287135538781])
38
+ e = sorted(nx.normalized_laplacian_spectrum(self.G))
39
+ np.testing.assert_almost_equal(e, evals)
40
+ e = sorted(nx.normalized_laplacian_spectrum(self.WG, weight=None))
41
+ np.testing.assert_almost_equal(e, evals)
42
+ e = sorted(nx.normalized_laplacian_spectrum(self.WG))
43
+ np.testing.assert_almost_equal(e, evals)
44
+ e = sorted(nx.normalized_laplacian_spectrum(self.WG, weight="other"))
45
+ np.testing.assert_almost_equal(e, evals)
46
+
47
+ def test_adjacency_spectrum(self):
48
+ "Adjacency eigenvalues"
49
+ evals = np.array([-np.sqrt(2), 0, np.sqrt(2)])
50
+ e = sorted(nx.adjacency_spectrum(self.P))
51
+ np.testing.assert_almost_equal(e, evals)
52
+
53
+ def test_modularity_spectrum(self):
54
+ "Modularity eigenvalues"
55
+ evals = np.array([-1.5, 0.0, 0.0])
56
+ e = sorted(nx.modularity_spectrum(self.P))
57
+ np.testing.assert_almost_equal(e, evals)
58
+ # Directed modularity eigenvalues
59
+ evals = np.array([-0.5, 0.0, 0.0])
60
+ e = sorted(nx.modularity_spectrum(self.DG))
61
+ np.testing.assert_almost_equal(e, evals)
62
+
63
+ def test_bethe_hessian_spectrum(self):
64
+ "Bethe Hessian eigenvalues"
65
+ evals = np.array([0.5 * (9 - np.sqrt(33)), 4, 0.5 * (9 + np.sqrt(33))])
66
+ e = sorted(nx.bethe_hessian_spectrum(self.P, r=2))
67
+ np.testing.assert_almost_equal(e, evals)
68
+ # Collapses back to Laplacian:
69
+ e1 = sorted(nx.bethe_hessian_spectrum(self.P, r=1))
70
+ e2 = sorted(nx.laplacian_spectrum(self.P))
71
+ np.testing.assert_almost_equal(e1, e2)
.venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/adjlist.cpython-311.pyc ADDED
Binary file (10.8 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/edgelist.cpython-311.pyc ADDED
Binary file (16.4 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/graphml.cpython-311.pyc ADDED
Binary file (47.5 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/leda.cpython-311.pyc ADDED
Binary file (4.84 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/p2g.cpython-311.pyc ADDED
Binary file (5.09 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/pajek.cpython-311.pyc ADDED
Binary file (13.3 kB). View file
 
.venv/lib/python3.11/site-packages/networkx/readwrite/__pycache__/sparse6.cpython-311.pyc ADDED
Binary file (14.1 kB). View file