foscat 3.8.0__py3-none-any.whl → 3.9.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.
- foscat/BkBase.py +39 -29
- foscat/BkNumpy.py +56 -47
- foscat/BkTensorflow.py +89 -81
- foscat/BkTorch.py +95 -59
- foscat/FoCUS.py +72 -56
- foscat/Synthesis.py +3 -3
- foscat/alm.py +194 -177
- foscat/backend.py +84 -70
- foscat/scat_cov.py +1876 -2100
- foscat/scat_cov2D.py +146 -53
- {foscat-3.8.0.dist-info → foscat-3.9.0.dist-info}/METADATA +1 -1
- {foscat-3.8.0.dist-info → foscat-3.9.0.dist-info}/RECORD +15 -15
- {foscat-3.8.0.dist-info → foscat-3.9.0.dist-info}/WHEEL +1 -1
- {foscat-3.8.0.dist-info → foscat-3.9.0.dist-info}/LICENSE +0 -0
- {foscat-3.8.0.dist-info → foscat-3.9.0.dist-info}/top_level.txt +0 -0
foscat/backend.py
CHANGED
|
@@ -44,7 +44,12 @@ class foscat_backend:
|
|
|
44
44
|
|
|
45
45
|
if self.BACKEND == "torch":
|
|
46
46
|
import torch
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
self.torch_device = (
|
|
49
|
+
torch.device("cuda")
|
|
50
|
+
if torch.cuda.is_available()
|
|
51
|
+
else torch.device("cpu")
|
|
52
|
+
)
|
|
48
53
|
|
|
49
54
|
self.BACKEND = self.TORCH
|
|
50
55
|
self.backend = torch
|
|
@@ -383,7 +388,11 @@ class foscat_backend:
|
|
|
383
388
|
if self.BACKEND == self.TENSORFLOW:
|
|
384
389
|
return self.backend.SparseTensor(indice, w, dense_shape=dense_shape)
|
|
385
390
|
if self.BACKEND == self.TORCH:
|
|
386
|
-
return
|
|
391
|
+
return (
|
|
392
|
+
self.backend.sparse_coo_tensor(indice.T, w, dense_shape)
|
|
393
|
+
.to_sparse_csr()
|
|
394
|
+
.to(self.torch_device)
|
|
395
|
+
)
|
|
387
396
|
if self.BACKEND == self.NUMPY:
|
|
388
397
|
return self.scipy.sparse.coo_matrix(
|
|
389
398
|
(w, (indice[:, 0], indice[:, 1])), shape=dense_shape
|
|
@@ -406,10 +415,10 @@ class foscat_backend:
|
|
|
406
415
|
return smat.dot(mat)
|
|
407
416
|
|
|
408
417
|
# for tensorflow wrapping only
|
|
409
|
-
def periodic_pad(self,x, pad_height, pad_width):
|
|
418
|
+
def periodic_pad(self, x, pad_height, pad_width):
|
|
410
419
|
"""
|
|
411
420
|
Applies periodic ('wrap') padding to a 4D TensorFlow tensor (N, H, W, C).
|
|
412
|
-
|
|
421
|
+
|
|
413
422
|
Args:
|
|
414
423
|
x (tf.Tensor): Input tensor with shape (batch_size, height, width, channels).
|
|
415
424
|
pad_height (tuple): Tuple (top, bottom) defining the vertical padding size.
|
|
@@ -418,40 +427,47 @@ class foscat_backend:
|
|
|
418
427
|
Returns:
|
|
419
428
|
tf.Tensor: Tensor with periodic padding applied.
|
|
420
429
|
"""
|
|
421
|
-
#Vertical padding: take slices from bottom and top to wrap around
|
|
422
|
-
top_pad = x[:, -pad_height:, :, :]
|
|
430
|
+
# Vertical padding: take slices from bottom and top to wrap around
|
|
431
|
+
top_pad = x[:, -pad_height:, :, :] # Top padding from the bottom rows
|
|
423
432
|
bottom_pad = x[:, :pad_height, :, :] # Bottom padding from the top rows
|
|
424
|
-
x_padded = self.backend.concat(
|
|
433
|
+
x_padded = self.backend.concat(
|
|
434
|
+
[top_pad, x, bottom_pad], axis=1
|
|
435
|
+
) # Concatenate vertically
|
|
436
|
+
|
|
437
|
+
# Horizontal padding: take slices from right and left to wrap around
|
|
438
|
+
left_pad = x_padded[:, :, -pad_width:, :] # Left padding from right columns
|
|
439
|
+
right_pad = x_padded[:, :, :pad_width, :] # Right padding from left columns
|
|
425
440
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
x_padded = self.backend.concat([left_pad, x_padded, right_pad], axis=2) # Concatenate horizontally
|
|
441
|
+
x_padded = self.backend.concat(
|
|
442
|
+
[left_pad, x_padded, right_pad], axis=2
|
|
443
|
+
) # Concatenate horizontally
|
|
431
444
|
|
|
432
445
|
return x_padded
|
|
433
|
-
|
|
446
|
+
|
|
434
447
|
def conv2d(self, x, w, strides=[1, 1, 1, 1], padding="SAME"):
|
|
435
448
|
if self.BACKEND == self.TENSORFLOW:
|
|
436
449
|
kx = w.shape[0]
|
|
437
450
|
ky = w.shape[1]
|
|
438
|
-
x_padded = self.periodic_pad(x, kx // 2, ky // 2)
|
|
451
|
+
x_padded = self.periodic_pad(x, kx // 2, ky // 2)
|
|
439
452
|
return self.backend.nn.conv2d(x_padded, w, strides=strides, padding="VALID")
|
|
440
|
-
|
|
453
|
+
|
|
441
454
|
if self.BACKEND == self.TORCH:
|
|
442
455
|
import torch.nn.functional as F
|
|
456
|
+
|
|
443
457
|
lx = x.permute(0, 3, 1, 2)
|
|
444
|
-
wx =
|
|
458
|
+
wx = (
|
|
459
|
+
self.backend.from_numpy(w).to(self.torch_device).permute(3, 2, 0, 1)
|
|
460
|
+
) # de (5, 5, 1, 4) à (4, 1, 5, 5)
|
|
445
461
|
|
|
446
462
|
# Calculer le padding symétrique
|
|
447
463
|
kx, ky = w.shape[0], w.shape[1]
|
|
448
|
-
|
|
464
|
+
|
|
449
465
|
# Appliquer le padding
|
|
450
|
-
x_padded = F.pad(lx, (ky // 2, ky // 2, kx // 2, kx // 2), mode=
|
|
466
|
+
x_padded = F.pad(lx, (ky // 2, ky // 2, kx // 2, kx // 2), mode="circular")
|
|
451
467
|
|
|
452
468
|
# Appliquer la convolution
|
|
453
|
-
return F.conv2d(x_padded, wx, stride=1, padding=0).permute(0,2,3,1)
|
|
454
|
-
|
|
469
|
+
return F.conv2d(x_padded, wx, stride=1, padding=0).permute(0, 2, 3, 1)
|
|
470
|
+
|
|
455
471
|
if self.BACKEND == self.NUMPY:
|
|
456
472
|
res = np.zeros(
|
|
457
473
|
[x.shape[0], x.shape[1], x.shape[2], w.shape[3]], dtype=x.dtype
|
|
@@ -552,15 +568,6 @@ class foscat_backend:
|
|
|
552
568
|
return np.concatenate([x.real.flatten(), x.imag.flatten()], 0)
|
|
553
569
|
else:
|
|
554
570
|
return x.flatten()
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
def bk_flatten(self, x):
|
|
558
|
-
if self.BACKEND == self.TENSORFLOW:
|
|
559
|
-
return self.backend.flatten(x)
|
|
560
|
-
elif self.BACKEND == self.TORCH:
|
|
561
|
-
return self.backend.flatten(x)
|
|
562
|
-
else:
|
|
563
|
-
return x.flatten()
|
|
564
571
|
|
|
565
572
|
def bk_flatten(self, x):
|
|
566
573
|
if self.BACKEND == self.TENSORFLOW:
|
|
@@ -570,25 +577,16 @@ class foscat_backend:
|
|
|
570
577
|
if self.BACKEND == self.NUMPY:
|
|
571
578
|
return x.flatten()
|
|
572
579
|
|
|
573
|
-
def bk_size(self, x):
|
|
574
|
-
if self.BACKEND == self.TENSORFLOW:
|
|
575
|
-
return self.backend.size(x)
|
|
576
|
-
if self.BACKEND == self.TORCH:
|
|
577
|
-
return x.numel()
|
|
578
|
-
|
|
579
|
-
if self.BACKEND == self.NUMPY:
|
|
580
|
-
return x.size
|
|
581
|
-
|
|
582
580
|
def bk_resize_image(self, x, shape):
|
|
583
581
|
if self.BACKEND == self.TENSORFLOW:
|
|
584
582
|
return self.bk_cast(self.backend.image.resize(x, shape, method="bilinear"))
|
|
585
583
|
|
|
586
584
|
if self.BACKEND == self.TORCH:
|
|
587
585
|
tmp = self.backend.nn.functional.interpolate(
|
|
588
|
-
x.permute(0,3,1,2), size=shape, mode="bilinear", align_corners=False
|
|
586
|
+
x.permute(0, 3, 1, 2), size=shape, mode="bilinear", align_corners=False
|
|
589
587
|
)
|
|
590
|
-
return self.bk_cast(tmp.permute(0,2,3,1))
|
|
591
|
-
|
|
588
|
+
return self.bk_cast(tmp.permute(0, 2, 3, 1))
|
|
589
|
+
|
|
592
590
|
if self.BACKEND == self.NUMPY:
|
|
593
591
|
return self.bk_cast(self.backend.image.resize(x, shape, method="bilinear"))
|
|
594
592
|
|
|
@@ -882,7 +880,7 @@ class foscat_backend:
|
|
|
882
880
|
return self.backend.constant(data).to(self.torch_device)
|
|
883
881
|
if self.BACKEND == self.NUMPY:
|
|
884
882
|
return data
|
|
885
|
-
|
|
883
|
+
|
|
886
884
|
def bk_shape_tensor(self, shape):
|
|
887
885
|
if self.BACKEND == self.TENSORFLOW:
|
|
888
886
|
return self.backend.tensor(shape=shape)
|
|
@@ -1025,22 +1023,26 @@ class foscat_backend:
|
|
|
1025
1023
|
return self.backend.fft(data)
|
|
1026
1024
|
if self.BACKEND == self.NUMPY:
|
|
1027
1025
|
return self.backend.fft.fft(data)
|
|
1028
|
-
|
|
1029
|
-
def bk_fftn(self, data,dim=None):
|
|
1026
|
+
|
|
1027
|
+
def bk_fftn(self, data, dim=None):
|
|
1030
1028
|
if self.BACKEND == self.TENSORFLOW:
|
|
1031
|
-
#Equivalent of torch.fft.fftn(x, dim=dims) in TensorFlow
|
|
1032
|
-
x=self.bk_complex(data,0*data)
|
|
1033
|
-
return self.backend.signal.fftnd(
|
|
1029
|
+
# Equivalent of torch.fft.fftn(x, dim=dims) in TensorFlow
|
|
1030
|
+
x = self.bk_complex(data, 0 * data)
|
|
1031
|
+
return self.backend.signal.fftnd(
|
|
1032
|
+
x, fft_length=tuple(x.shape[d] for d in dim), axes=dim
|
|
1033
|
+
)
|
|
1034
1034
|
if self.BACKEND == self.TORCH:
|
|
1035
|
-
return self.backend.fft.fftn(data,dim=dim)
|
|
1035
|
+
return self.backend.fft.fftn(data, dim=dim)
|
|
1036
1036
|
if self.BACKEND == self.NUMPY:
|
|
1037
1037
|
return self.backend.fft.fftn(data)
|
|
1038
1038
|
|
|
1039
|
-
def bk_ifftn(self, data,dim=None,norm=None):
|
|
1039
|
+
def bk_ifftn(self, data, dim=None, norm=None):
|
|
1040
1040
|
if self.BACKEND == self.TENSORFLOW:
|
|
1041
|
-
return self.backend.signal.ifftnd(
|
|
1041
|
+
return self.backend.signal.ifftnd(
|
|
1042
|
+
data, fft_length=tuple(data.shape[d] for d in dim), axes=dim, norm=norm
|
|
1043
|
+
)
|
|
1042
1044
|
if self.BACKEND == self.TORCH:
|
|
1043
|
-
return self.backend.fft.ifftn(data,dim=dim,norm=norm)
|
|
1045
|
+
return self.backend.fft.ifftn(data, dim=dim, norm=norm)
|
|
1044
1046
|
if self.BACKEND == self.NUMPY:
|
|
1045
1047
|
return self.backend.fft.ifftn(data)
|
|
1046
1048
|
|
|
@@ -1102,18 +1104,30 @@ class foscat_backend:
|
|
|
1102
1104
|
if self.BACKEND == self.NUMPY:
|
|
1103
1105
|
return (x > 0) * x
|
|
1104
1106
|
|
|
1105
|
-
def bk_clip_by_value(self, x,xmin,xmax):
|
|
1107
|
+
def bk_clip_by_value(self, x, xmin, xmax):
|
|
1106
1108
|
if isinstance(x, np.ndarray):
|
|
1107
|
-
x = np.clip(x,xmin,xmax)
|
|
1109
|
+
x = np.clip(x, xmin, xmax)
|
|
1108
1110
|
if self.BACKEND == self.TENSORFLOW:
|
|
1109
|
-
return self.backend.clip_by_value(x,xmin,xmax)
|
|
1111
|
+
return self.backend.clip_by_value(x, xmin, xmax)
|
|
1110
1112
|
if self.BACKEND == self.TORCH:
|
|
1111
|
-
x =
|
|
1112
|
-
|
|
1113
|
-
|
|
1113
|
+
x = (
|
|
1114
|
+
self.backend.tensor(x, dtype=self.backend.float32)
|
|
1115
|
+
if not isinstance(x, self.backend.Tensor)
|
|
1116
|
+
else x
|
|
1117
|
+
)
|
|
1118
|
+
xmin = (
|
|
1119
|
+
self.backend.tensor(xmin, dtype=self.backend.float32)
|
|
1120
|
+
if not isinstance(xmin, self.backend.Tensor)
|
|
1121
|
+
else xmin
|
|
1122
|
+
)
|
|
1123
|
+
xmax = (
|
|
1124
|
+
self.backend.tensor(xmax, dtype=self.backend.float32)
|
|
1125
|
+
if not isinstance(xmax, self.backend.Tensor)
|
|
1126
|
+
else xmax
|
|
1127
|
+
)
|
|
1114
1128
|
return self.backend.clamp(x, min=xmin, max=xmax)
|
|
1115
1129
|
if self.BACKEND == self.NUMPY:
|
|
1116
|
-
return self.backend.clip(x,xmin,xmax)
|
|
1130
|
+
return self.backend.clip(x, xmin, xmax)
|
|
1117
1131
|
|
|
1118
1132
|
def bk_cast(self, x):
|
|
1119
1133
|
if isinstance(x, np.float64):
|
|
@@ -1164,28 +1178,28 @@ class foscat_backend:
|
|
|
1164
1178
|
|
|
1165
1179
|
if self.BACKEND == self.NUMPY:
|
|
1166
1180
|
return x.astype(out_type)
|
|
1167
|
-
|
|
1168
|
-
def bk_variable(self,x):
|
|
1181
|
+
|
|
1182
|
+
def bk_variable(self, x):
|
|
1169
1183
|
if self.BACKEND == self.TENSORFLOW:
|
|
1170
1184
|
return self.backend.Variable(x)
|
|
1171
|
-
|
|
1185
|
+
|
|
1172
1186
|
return self.bk_cast(x)
|
|
1173
|
-
|
|
1174
|
-
def bk_assign(self,x,y):
|
|
1187
|
+
|
|
1188
|
+
def bk_assign(self, x, y):
|
|
1175
1189
|
if self.BACKEND == self.TENSORFLOW:
|
|
1176
1190
|
x.assign(y)
|
|
1177
|
-
x=y
|
|
1178
|
-
|
|
1179
|
-
def bk_constant(self,x):
|
|
1191
|
+
x = y
|
|
1192
|
+
|
|
1193
|
+
def bk_constant(self, x):
|
|
1180
1194
|
if self.BACKEND == self.TENSORFLOW:
|
|
1181
1195
|
return self.backend.constant(x)
|
|
1182
|
-
|
|
1196
|
+
|
|
1183
1197
|
return self.bk_cast(x)
|
|
1184
|
-
|
|
1185
|
-
def to_numpy(self,x):
|
|
1198
|
+
|
|
1199
|
+
def to_numpy(self, x):
|
|
1186
1200
|
if isinstance(x, np.ndarray):
|
|
1187
1201
|
return x
|
|
1188
|
-
|
|
1202
|
+
|
|
1189
1203
|
if self.BACKEND == self.NUMPY:
|
|
1190
1204
|
return x
|
|
1191
1205
|
if self.BACKEND == self.TENSORFLOW:
|