pygeoinf 1.3.8__py3-none-any.whl → 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pygeoinf/__init__.py +36 -0
- pygeoinf/gaussian_measure.py +79 -13
- pygeoinf/hilbert_space.py +15 -0
- pygeoinf/linear_operators.py +32 -0
- pygeoinf/plot.py +7 -1
- pygeoinf/preconditioners.py +1 -1
- pygeoinf/subsets.py +845 -0
- pygeoinf/subspaces.py +173 -23
- pygeoinf/symmetric_space/circle.py +41 -1
- pygeoinf/symmetric_space/sphere.py +231 -22
- pygeoinf/symmetric_space/symmetric_space.py +167 -12
- pygeoinf/symmetric_space/wigner.py +284 -0
- pygeoinf/utils.py +15 -0
- {pygeoinf-1.3.8.dist-info → pygeoinf-1.4.0.dist-info}/METADATA +3 -1
- {pygeoinf-1.3.8.dist-info → pygeoinf-1.4.0.dist-info}/RECORD +17 -14
- {pygeoinf-1.3.8.dist-info → pygeoinf-1.4.0.dist-info}/WHEEL +1 -1
- {pygeoinf-1.3.8.dist-info → pygeoinf-1.4.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import numba as nb
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@nb.jit(nopython=True, cache=True)
|
|
6
|
+
def _wigner_start_values(l, n, theta):
|
|
7
|
+
"""
|
|
8
|
+
Computes the boundary values for the recursion (l == |n|).
|
|
9
|
+
Corresponds to WignerMinOrder/WignerMaxOrder in C++.
|
|
10
|
+
"""
|
|
11
|
+
# Use log-space arithmetic for stability
|
|
12
|
+
# Corresponds to lines 86-105 in Wigner.h
|
|
13
|
+
|
|
14
|
+
half = 0.5
|
|
15
|
+
sin_half = np.sin(half * theta)
|
|
16
|
+
cos_half = np.cos(half * theta)
|
|
17
|
+
|
|
18
|
+
# Handle tiny angles (log stability)
|
|
19
|
+
# Note: In a full implementation, check for strict 0 or pi,
|
|
20
|
+
# but float precision usually handles this with small eps.
|
|
21
|
+
log_sin = np.log(sin_half) if sin_half > 1e-15 else -1e15
|
|
22
|
+
log_cos = np.log(cos_half) if cos_half > 1e-15 else -1e15
|
|
23
|
+
|
|
24
|
+
Fl = float(l)
|
|
25
|
+
Fn = float(n)
|
|
26
|
+
|
|
27
|
+
# Formula from WignerMinOrder
|
|
28
|
+
# exp( 0.5 * (lgamma(2l+1) - lgamma(l-n+1) - lgamma(l+n+1)) + ... )
|
|
29
|
+
term = np.exp(
|
|
30
|
+
half
|
|
31
|
+
* (
|
|
32
|
+
np.math.lgamma(2 * Fl + 1)
|
|
33
|
+
- np.math.lgamma(Fl - Fn + 1)
|
|
34
|
+
- np.math.lgamma(Fl + Fn + 1)
|
|
35
|
+
)
|
|
36
|
+
+ (Fl + Fn) * log_sin
|
|
37
|
+
+ (Fl - Fn) * log_cos
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Returns (min_val, max_val)
|
|
41
|
+
# min_val corresponds to m = -l (if n is negative logic)
|
|
42
|
+
# Based on WignerDetails logic, we return the value for m=-l and m=l
|
|
43
|
+
|
|
44
|
+
# Note: The C++ code handles sign flips based on n.
|
|
45
|
+
# We simplify for the standard case.
|
|
46
|
+
val_minus_l = term
|
|
47
|
+
val_plus_l = term * ((-1) ** (n + l)) # From MinusOneToPower in WignerMaxOrder
|
|
48
|
+
|
|
49
|
+
return val_minus_l, val_plus_l
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@nb.jit(nopython=True, cache=True)
|
|
53
|
+
def compute_wigner_d_recursive(l_max, m_max, n, theta):
|
|
54
|
+
"""
|
|
55
|
+
Direct port of GSHTrans::Wigner::Compute.
|
|
56
|
+
Returns a flat array of coefficients and an offset array to index it.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
# 1. Precompute inverse square roots for integer factors
|
|
60
|
+
# (Matches PreCompute in Wigner.h)
|
|
61
|
+
size_pre = 2 * l_max + 5
|
|
62
|
+
sqrt_inv = np.zeros(size_pre)
|
|
63
|
+
sqrt_val = np.zeros(size_pre)
|
|
64
|
+
for i in range(1, size_pre):
|
|
65
|
+
sqrt_val[i] = np.sqrt(i)
|
|
66
|
+
sqrt_inv[i] = 1.0 / sqrt_val[i]
|
|
67
|
+
|
|
68
|
+
# 2. Calculate storage size and offsets
|
|
69
|
+
# We assume 'All' m-range for simplicity (m goes from -min(l, m_max) to min(l, m_max))
|
|
70
|
+
n_abs = abs(n)
|
|
71
|
+
offsets = np.zeros(l_max + 2, dtype=np.int64)
|
|
72
|
+
current_offset = 0
|
|
73
|
+
|
|
74
|
+
for l in range(l_max + 1):
|
|
75
|
+
offsets[l] = current_offset
|
|
76
|
+
if l >= n_abs:
|
|
77
|
+
effective_m_max = min(l, m_max)
|
|
78
|
+
# Size = (effective_m_max - (-effective_m_max)) + 1
|
|
79
|
+
current_offset += 2 * effective_m_max + 1
|
|
80
|
+
|
|
81
|
+
data = np.zeros(current_offset, dtype=np.float64)
|
|
82
|
+
cos_theta = np.cos(theta)
|
|
83
|
+
|
|
84
|
+
# 3. Main Recursion Loop
|
|
85
|
+
# Iterate degrees l from |n| to l_max
|
|
86
|
+
for l in range(n_abs, l_max + 1):
|
|
87
|
+
|
|
88
|
+
m_lim = min(l, m_max)
|
|
89
|
+
row_len = 2 * m_lim + 1
|
|
90
|
+
|
|
91
|
+
# Pointers to current and previous data in the flat array
|
|
92
|
+
ptr = offsets[l]
|
|
93
|
+
ptr_minus_1 = offsets[l - 1] if l > 0 else -1
|
|
94
|
+
ptr_minus_2 = offsets[l - 2] if l > 1 else -1
|
|
95
|
+
|
|
96
|
+
# A. Base Case: l = |n|
|
|
97
|
+
if l == n_abs:
|
|
98
|
+
val_min, val_max = _wigner_start_values(l, n, theta)
|
|
99
|
+
|
|
100
|
+
# If n is positive, we start filling from the "left" (m=-l) logic
|
|
101
|
+
# The C++ code separates logic for n>=0 and n<0.
|
|
102
|
+
# Assuming n=0 for common cases, or standard alignment:
|
|
103
|
+
|
|
104
|
+
# Fill directly. For l=|n|, usually there is only one valid starting m
|
|
105
|
+
# if we strictly followed the "Sector" logic, but Wigner.h fills the row.
|
|
106
|
+
# We will use the boundary values logic.
|
|
107
|
+
|
|
108
|
+
# Simple fill for l=|n|: usually 0 except at boundaries?
|
|
109
|
+
# The C++ code lines 326-338 imply it fills the whole row for l=|n|.
|
|
110
|
+
# But mathematically only m=-l or m=l are non-zero at the start of recursion?
|
|
111
|
+
# Actually, for l=n, d^n_{n,m} is computable.
|
|
112
|
+
|
|
113
|
+
# To be safe and "passably efficient", we only set the edges
|
|
114
|
+
# and let the loop fill (though loop is empty for size 1).
|
|
115
|
+
if m_lim == l: # If we have full range
|
|
116
|
+
if n >= 0:
|
|
117
|
+
data[ptr] = val_min # m = -l
|
|
118
|
+
data[ptr + row_len - 1] = val_max # m = +l
|
|
119
|
+
else:
|
|
120
|
+
data[ptr] = val_max # Flip logic
|
|
121
|
+
data[ptr + row_len - 1] = val_min
|
|
122
|
+
|
|
123
|
+
# Note: For l=|n|, intermediate m's are handled by specific logic
|
|
124
|
+
# or are zero? In Wigner.h line 334, it loops w/ WignerMaxUpperIndex.
|
|
125
|
+
# For simplicity in this port, we assume we just need the recursion seeds.
|
|
126
|
+
|
|
127
|
+
# B. One-term recursion: l = |n| + 1
|
|
128
|
+
elif l == n_abs + 1:
|
|
129
|
+
# Range of m for previous row (l-1)
|
|
130
|
+
m_lim_prev = min(l - 1, m_max)
|
|
131
|
+
|
|
132
|
+
# Iterate over m. The C++ code is careful about indices.
|
|
133
|
+
# We map m to index: index = m + m_lim
|
|
134
|
+
|
|
135
|
+
# Pre-calc coefficients
|
|
136
|
+
alpha_base = (2 * l - 1) * l * cos_theta * sqrt_inv[l + n_abs]
|
|
137
|
+
beta_base = (2 * l - 1) * sqrt_inv[l + n_abs]
|
|
138
|
+
if n < 0:
|
|
139
|
+
beta_base *= -1
|
|
140
|
+
|
|
141
|
+
# Loop over 'interior' m (those that exist in l-1)
|
|
142
|
+
# m goes from -m_lim_prev to m_lim_prev
|
|
143
|
+
for m in range(-m_lim_prev, m_lim_prev + 1):
|
|
144
|
+
# Indices
|
|
145
|
+
idx_prev = m + m_lim_prev # Index in l-1 row
|
|
146
|
+
idx_curr = m + m_lim # Index in l row
|
|
147
|
+
|
|
148
|
+
f1 = (alpha_base - beta_base * m) * sqrt_inv[l - m] * sqrt_inv[l + m]
|
|
149
|
+
data[ptr + idx_curr] = f1 * data[ptr_minus_1 + idx_prev]
|
|
150
|
+
|
|
151
|
+
# Add Boundaries (m = -l and m = +l) if they fit in m_max
|
|
152
|
+
if m_lim == l:
|
|
153
|
+
val_min, val_max = _wigner_start_values(l, n, theta)
|
|
154
|
+
data[ptr] = val_min # m = -l
|
|
155
|
+
data[ptr + row_len - 1] = val_max # m = l
|
|
156
|
+
|
|
157
|
+
# C. Two-term recursion: l > |n| + 1
|
|
158
|
+
else:
|
|
159
|
+
m_lim_prev = min(l - 1, m_max)
|
|
160
|
+
m_lim_prev2 = min(l - 2, m_max)
|
|
161
|
+
|
|
162
|
+
# Terms for recursion
|
|
163
|
+
# Matches C++ Lines 397-402
|
|
164
|
+
inv_l_minus_1 = 1.0 / (l - 1.0)
|
|
165
|
+
|
|
166
|
+
alpha = (2 * l - 1) * l * cos_theta * sqrt_inv[l - n] * sqrt_inv[l + n]
|
|
167
|
+
beta = (2 * l - 1) * n * sqrt_inv[l - n] * sqrt_inv[l + n] * inv_l_minus_1
|
|
168
|
+
gamma = (
|
|
169
|
+
l
|
|
170
|
+
* sqrt_val[l - 1 - n]
|
|
171
|
+
* sqrt_val[l - 1 + n]
|
|
172
|
+
* sqrt_inv[l - n]
|
|
173
|
+
* sqrt_inv[l + n]
|
|
174
|
+
* inv_l_minus_1
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
# 1. Fill Interior (where m exists in l-2)
|
|
178
|
+
# Range where we can use two-term: m in intersection of l-1 and l-2
|
|
179
|
+
m_start_2term = -m_lim_prev2
|
|
180
|
+
m_end_2term = m_lim_prev2
|
|
181
|
+
|
|
182
|
+
for m in range(m_start_2term, m_end_2term + 1):
|
|
183
|
+
idx_curr = m + m_lim
|
|
184
|
+
idx_prev = m + m_lim_prev
|
|
185
|
+
idx_prev2 = m + m_lim_prev2
|
|
186
|
+
|
|
187
|
+
denom = sqrt_inv[l - m] * sqrt_inv[l + m]
|
|
188
|
+
f1 = (alpha - beta * m) * denom
|
|
189
|
+
f2 = gamma * sqrt_val[l - 1 - m] * sqrt_val[l - 1 + m] * denom
|
|
190
|
+
|
|
191
|
+
term1 = f1 * data[ptr_minus_1 + idx_prev]
|
|
192
|
+
term2 = f2 * data[ptr_minus_2 + idx_prev2]
|
|
193
|
+
|
|
194
|
+
data[ptr + idx_curr] = term1 - term2
|
|
195
|
+
|
|
196
|
+
# 2. Fill Lower Gap (if m_max allows, between l-2 and l-1)
|
|
197
|
+
# This corresponds to "one-point recursion" logic for growing edges
|
|
198
|
+
# The gap is m = -(l-1). It exists in l-1 but not l-2.
|
|
199
|
+
if m_lim_prev > m_lim_prev2: # If l-1 has wider range than l-2
|
|
200
|
+
# Logic for m = -(l-1)
|
|
201
|
+
m = -(l - 1)
|
|
202
|
+
if abs(m) <= m_lim:
|
|
203
|
+
idx_curr = m + m_lim
|
|
204
|
+
idx_prev = m + m_lim_prev
|
|
205
|
+
# Use 1-term expansion (simplified from C++ lines 360-370)
|
|
206
|
+
# f1 derived from boundary conditions
|
|
207
|
+
f1 = (
|
|
208
|
+
(2 * l - 1)
|
|
209
|
+
* (l * (l - 1) * cos_theta - m * n)
|
|
210
|
+
* sqrt_inv[l - n]
|
|
211
|
+
* sqrt_inv[l + n]
|
|
212
|
+
* sqrt_inv[l - m]
|
|
213
|
+
* sqrt_inv[l + m]
|
|
214
|
+
* inv_l_minus_1
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
data[ptr + idx_curr] = f1 * data[ptr_minus_1 + idx_prev]
|
|
218
|
+
|
|
219
|
+
# Logic for m = +(l-1)
|
|
220
|
+
m = l - 1
|
|
221
|
+
if abs(m) <= m_lim:
|
|
222
|
+
idx_curr = m + m_lim
|
|
223
|
+
idx_prev = m + m_lim_prev
|
|
224
|
+
f1 = (
|
|
225
|
+
(2 * l - 1)
|
|
226
|
+
* (l * (l - 1) * cos_theta - m * n)
|
|
227
|
+
* sqrt_inv[l - n]
|
|
228
|
+
* sqrt_inv[l + n]
|
|
229
|
+
* sqrt_inv[l - m]
|
|
230
|
+
* sqrt_inv[l + m]
|
|
231
|
+
* inv_l_minus_1
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
data[ptr + idx_curr] = f1 * data[ptr_minus_1 + idx_prev]
|
|
235
|
+
|
|
236
|
+
# 3. Fill Outer Boundaries (m = -l and m = +l)
|
|
237
|
+
if m_lim == l:
|
|
238
|
+
val_min, val_max = _wigner_start_values(l, n, theta)
|
|
239
|
+
data[ptr] = val_min
|
|
240
|
+
data[ptr + row_len - 1] = val_max
|
|
241
|
+
|
|
242
|
+
# 4. Optional: Orthogonal Normalization (Matches GSHTrans::Ortho)
|
|
243
|
+
# Multiply by sqrt(2l+1) / sqrt(4pi) ?
|
|
244
|
+
# Your C++ code multiplies by (inv_sqrt_pi / 2) * sqrt(2l+1)
|
|
245
|
+
# We apply this to match your output exactly.
|
|
246
|
+
inv_sqrt_pi = 0.5641895835477563
|
|
247
|
+
factor = inv_sqrt_pi / 2.0
|
|
248
|
+
|
|
249
|
+
for l in range(n_abs, l_max + 1):
|
|
250
|
+
norm_factor = factor * np.sqrt(2 * l + 1)
|
|
251
|
+
start = offsets[l]
|
|
252
|
+
end = start + (2 * min(l, m_max) + 1)
|
|
253
|
+
data[start:end] *= norm_factor
|
|
254
|
+
|
|
255
|
+
return data, offsets
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class WignerRecursion:
|
|
259
|
+
def __init__(self, l_max, m_max, n):
|
|
260
|
+
self.l_max = l_max
|
|
261
|
+
self.m_max = m_max
|
|
262
|
+
self.n = n
|
|
263
|
+
|
|
264
|
+
# JIT compile immediately with dummy data to avoid lag on first real use
|
|
265
|
+
compute_wigner_d_recursive(1, 1, 0, 0.1)
|
|
266
|
+
|
|
267
|
+
def compute(self, theta):
|
|
268
|
+
"""
|
|
269
|
+
Computes Wigner elements for angle theta.
|
|
270
|
+
Returns:
|
|
271
|
+
data (np.array): Flat array of coefficients.
|
|
272
|
+
offsets (np.array): Indices where each degree l starts.
|
|
273
|
+
"""
|
|
274
|
+
return compute_wigner_d_recursive(self.l_max, self.m_max, self.n, theta)
|
|
275
|
+
|
|
276
|
+
def get_index(self, l, m, offsets):
|
|
277
|
+
"""Helper to find index in flat array"""
|
|
278
|
+
if l < abs(self.n) or l > self.l_max:
|
|
279
|
+
return -1
|
|
280
|
+
m_lim = min(l, self.m_max)
|
|
281
|
+
if abs(m) > m_lim:
|
|
282
|
+
return -1
|
|
283
|
+
# Offset + (m - m_min) where m_min is -m_lim
|
|
284
|
+
return offsets[l] + (m + m_lim)
|
pygeoinf/utils.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from threadpoolctl import threadpool_limits
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def configure_threading(n_threads: int = 1):
|
|
5
|
+
"""
|
|
6
|
+
Sets the maximum number of threads used by underlying linear algebra
|
|
7
|
+
backends (MKL, OpenBLAS, etc.).
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
n_threads: The number of threads to allow.
|
|
11
|
+
Set to 1 for serial execution (safe for multiprocessing).
|
|
12
|
+
Set to -1 or None to use all available cores.
|
|
13
|
+
"""
|
|
14
|
+
threadpool_limits(limits=n_threads)
|
|
15
|
+
print(f"Backend threading restricted to {n_threads} thread(s).")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pygeoinf
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: A package for solving geophysical inference and inverse problems
|
|
5
5
|
License: BSD-3-Clause
|
|
6
6
|
License-File: LICENSE
|
|
@@ -16,10 +16,12 @@ Provides-Extra: sphere
|
|
|
16
16
|
Requires-Dist: Cartopy (>=0.23.0,<0.24.0) ; extra == "sphere"
|
|
17
17
|
Requires-Dist: joblib (>=1.5.2,<2.0.0)
|
|
18
18
|
Requires-Dist: matplotlib (>=3.0.0)
|
|
19
|
+
Requires-Dist: numba (>=0.63.1,<0.64.0)
|
|
19
20
|
Requires-Dist: numpy (>=1.26.0)
|
|
20
21
|
Requires-Dist: pyqt6 (>=6.0.0)
|
|
21
22
|
Requires-Dist: pyshtools (>=4.0.0) ; extra == "sphere"
|
|
22
23
|
Requires-Dist: scipy (>=1.16.1)
|
|
24
|
+
Requires-Dist: threadpoolctl (>=3.6.0,<4.0.0)
|
|
23
25
|
Description-Content-Type: text/markdown
|
|
24
26
|
|
|
25
27
|
# pygeoinf: A Python Library for Geophysical Inference
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pygeoinf/__init__.py,sha256=
|
|
1
|
+
pygeoinf/__init__.py,sha256=vLr6Mx7aSFc3Gtntyt29f7eYx79UAEVuKV2GznCQjNI,4808
|
|
2
2
|
pygeoinf/auxiliary.py,sha256=lfoTt9ZH4y8SAV8dKZi5EWx1oF_JtxtBMSmlFYqJYfE,1610
|
|
3
3
|
pygeoinf/backus_gilbert.py,sha256=eFi4blSwOCsg_NuH6WD4gcgjvzvu5g5WpWahGobSBdM,3694
|
|
4
4
|
pygeoinf/checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -7,28 +7,31 @@ pygeoinf/checks/linear_operators.py,sha256=945ECCM7nEPuE00_5Tb8o2pG5IYbNtDSqwKNh
|
|
|
7
7
|
pygeoinf/checks/nonlinear_operators.py,sha256=pFHQrbQslrbBM9J_p1-4TQoETsupVICKtTtKFSWBfsk,7533
|
|
8
8
|
pygeoinf/direct_sum.py,sha256=7V0qrwFGj0GN-p_zzffefPrIB0dPu5dshLTxem1mQGE,19274
|
|
9
9
|
pygeoinf/forward_problem.py,sha256=NnqWp7iMfkhHa9d-jBHzYHClaAfhKmO5D058AcJLLYg,10724
|
|
10
|
-
pygeoinf/gaussian_measure.py,sha256=
|
|
11
|
-
pygeoinf/hilbert_space.py,sha256=
|
|
10
|
+
pygeoinf/gaussian_measure.py,sha256=RUbRNce9tua2RJK_yx8VEcc_sba4kloAGTLEse2wRyY,28531
|
|
11
|
+
pygeoinf/hilbert_space.py,sha256=kcwKa45MkGRQkHLgZl4Z07i4T5Z_L8c4KzImfrcLCe8,27811
|
|
12
12
|
pygeoinf/inversion.py,sha256=RV0hG2bGnciWdja0oOPKPxnFhYzufqdj-mKYNr4JJ_o,6447
|
|
13
13
|
pygeoinf/linear_bayesian.py,sha256=qzWEVaNe9AwG5GBmGHgVHswEMFKBWvOOJDlS95ahyxc,8877
|
|
14
14
|
pygeoinf/linear_forms.py,sha256=mgZeDRegNKo8kviE68KrxkHR4gG9bf1RgsJz1MtDMCk,9181
|
|
15
|
-
pygeoinf/linear_operators.py,sha256=
|
|
15
|
+
pygeoinf/linear_operators.py,sha256=PJChuh6njEBy-_1X7pO782MJHFkxOxpvBtFtpL0jWFE,65969
|
|
16
16
|
pygeoinf/linear_optimisation.py,sha256=RhO-1OsEDGnVHBlCtYyqp8jmW4GeGnGWGPRYPSc5GSg,13922
|
|
17
17
|
pygeoinf/linear_solvers.py,sha256=tYBp_ysePnOgqgKhMXhNHxLM8xi3awiwwdnKXHhmlNk,31071
|
|
18
18
|
pygeoinf/nonlinear_forms.py,sha256=t7lk-Bha7Xdk9eiwXMmS0F47oTR6jW6qQ3HkgRGk54A,7012
|
|
19
19
|
pygeoinf/nonlinear_operators.py,sha256=AtkDTQfGDzAnfFDIgiKfdk7uPEI-j_ZA3CNvY5A3U8w,7144
|
|
20
20
|
pygeoinf/nonlinear_optimisation.py,sha256=skK1ikn9GrVYherD64Qt9WrEYHA2NAJ48msOu_J8Oig,7431
|
|
21
21
|
pygeoinf/parallel.py,sha256=VVFvNHszy4wSa9LuErIsch4NAkLaZezhdN9YpRROBJo,2267
|
|
22
|
-
pygeoinf/plot.py,sha256=
|
|
23
|
-
pygeoinf/preconditioners.py,sha256=
|
|
22
|
+
pygeoinf/plot.py,sha256=kc63kIo55bmwTM1Mu0fSDJoR8I98F69ma_OrK6QK7xs,14310
|
|
23
|
+
pygeoinf/preconditioners.py,sha256=B4sBQefWpK_SovkbX0Y2LVFLUgRE-JX-iMhUDscyW5U,4504
|
|
24
24
|
pygeoinf/random_matrix.py,sha256=-U_3-yrVos_86EfNy1flULsWY-Y9G9Yy1GKoSS2gn60,17828
|
|
25
|
-
pygeoinf/
|
|
25
|
+
pygeoinf/subsets.py,sha256=jp25hdQ9rsZ7cckMJFiXLSx554dgBwtqwnRWi8AsUOY,26029
|
|
26
|
+
pygeoinf/subspaces.py,sha256=oPSZx2B07kg2SRQEVk8bBWXnGqvXuJngC0PFiSij78M,19949
|
|
26
27
|
pygeoinf/symmetric_space/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
-
pygeoinf/symmetric_space/circle.py,sha256=
|
|
28
|
+
pygeoinf/symmetric_space/circle.py,sha256=7Kn_qVaRYCi16lqXpYEz9h-Z9u2O6dC61P5miuG8PWU,20296
|
|
28
29
|
pygeoinf/symmetric_space/sh_tools.py,sha256=EDZm0YRZefvCfDjAKZatZMM3UqeTi-Npiflnc1E5slk,3884
|
|
29
|
-
pygeoinf/symmetric_space/sphere.py,sha256=
|
|
30
|
-
pygeoinf/symmetric_space/symmetric_space.py,sha256=
|
|
31
|
-
pygeoinf
|
|
32
|
-
pygeoinf
|
|
33
|
-
pygeoinf-1.
|
|
34
|
-
pygeoinf-1.
|
|
30
|
+
pygeoinf/symmetric_space/sphere.py,sha256=jcTUfO_hn-zqS_5Zr6EZN-rxhGX-pN6-ojZHEaTczSg,35887
|
|
31
|
+
pygeoinf/symmetric_space/symmetric_space.py,sha256=wLdLi7_edfC37K-12I0AIulbYL8vkLQUvIJ5ZELTNWM,24813
|
|
32
|
+
pygeoinf/symmetric_space/wigner.py,sha256=4_8O_cQvoRjCgns86cpTkZ7gslGHg_veoaVXTZ1dhYk,10632
|
|
33
|
+
pygeoinf/utils.py,sha256=UIrO5w2aenzENryuZUYxg6q3MQqk0rFTgbhl_FY10V0,529
|
|
34
|
+
pygeoinf-1.4.0.dist-info/METADATA,sha256=SiSlyg8SsvnhRoc-dNr-CVdtVtLeieUDYRH6dSGf1Lo,16568
|
|
35
|
+
pygeoinf-1.4.0.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
|
|
36
|
+
pygeoinf-1.4.0.dist-info/licenses/LICENSE,sha256=GrTQnKJemVi69FSbHprq60KN0OJGsOSR-joQoTq-oD8,1501
|
|
37
|
+
pygeoinf-1.4.0.dist-info/RECORD,,
|
|
File without changes
|