foscat 3.2.0__py3-none-any.whl → 3.3.1__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/CircSpline.py CHANGED
@@ -1,54 +1,75 @@
1
- import math
1
+ import numpy as np
2
2
 
3
3
 
4
4
  class CircSpline:
5
5
  def __init__(self, nodes, degree=3):
6
6
  """
7
- Initialize the circular spline with the given number of nodes and degree.
7
+ Initializes the Spline1D instance.
8
+
9
+ Parameters:
10
+ - nodes (int): The number of nodes in the spline.
11
+ - degree (int): The degree of the spline. Default is 3.
8
12
  """
9
13
  self.degree = degree
10
14
  self.nodes = nodes
11
- self.norm = [self._compute_norm(i) for i in range(degree + 1)]
12
-
13
- def _compute_norm(self, i):
15
+
16
+
17
+ def cubic_spline_function(self,x):
14
18
  """
15
- Compute normalization factor for the ith element.
19
+ Evaluate the cubic spline basis function.
20
+
21
+ Args:
22
+ x (float or array): Input value(s) to evaluate the spline basis function.
23
+
24
+ Returns:
25
+ float or array: Result of the cubic spline basis function.
16
26
  """
17
- return (
18
- pow(-1, i)
19
- * (self.degree + 1)
20
- / (math.factorial(self.degree + 1 - i) * math.factorial(i))
21
- )
27
+ return -2 * x**3 + 3 * x**2
22
28
 
23
- def yplus(self, x):
24
- """
25
- Compute yplus value for a given x based on the spline's degree.
26
- """
27
- if x < 0.0:
28
- return 0.0
29
- if self.degree == 0:
30
- return 0.5 if x == 0.0 else 1.0
31
- return pow(x, self.degree)
32
29
 
33
- def calculate(self, x):
30
+ def eval(self,x):
34
31
  """
35
- Calculate circular spline values for a given x.
32
+ Compute a 3rd-degree cubic spline with 4-point support.
33
+
34
+ Args:
35
+ x (float or array): Input value(s) to compute the spline.
36
+
37
+ Returns:
38
+ indices (array): Indices of the spline support points.
39
+ coefficients (array): Normalized spline coefficients.
36
40
  """
37
- y = [0] * self.nodes
38
- for i in range(self.nodes + self.degree // 2 + 1):
39
- tmp = 0
40
- tx = self.nodes * math.fmod(x, 2 * math.pi) / (math.pi * 2) - i
41
- for j in range(self.degree + 1):
42
- tmp += self.norm[j] * self.yplus(tx - j + (self.degree + 1) // 2)
43
- if tmp < 0:
44
- tmp = 0.0
45
- y[i % self.nodes] += tmp
46
- for i in range(self.degree // 2):
47
- tmp = 0
48
- tx = self.nodes * math.fmod(x, 2 * math.pi) / (math.pi * 2) + 1 + i
49
- for j in range(self.degree + 1):
50
- tmp += self.norm[j] * self.yplus(tx - j + (self.degree + 1) // 2)
51
- if tmp < 0:
52
- tmp = 0.0
53
- y[self.nodes - 1 - i] += tmp
54
- return y
41
+ N=self.nodes
42
+
43
+ if isinstance(x, float):
44
+ # Single scalar input
45
+ base_idx = int(x * (N))
46
+ indices = np.zeros([4], dtype="int")
47
+ coefficients = np.zeros([4])
48
+ else:
49
+ # Array input
50
+ base_idx = (x * (N)).astype("int")
51
+ indices = np.zeros([4, x.shape[0]], dtype="int")
52
+ coefficients = np.zeros([4, x.shape[0]])
53
+
54
+ # Compute the fractional part of the input
55
+ fractional_part = x * (N) - base_idx
56
+
57
+ # Compute spline coefficients for 4 support points
58
+ coefficients[3] = self.cubic_spline_function(fractional_part / 2) / 2
59
+ coefficients[2] = self.cubic_spline_function(0.5 + fractional_part / 2) / 2
60
+ coefficients[1] = self.cubic_spline_function(1 - fractional_part / 2) / 2
61
+ coefficients[0] = self.cubic_spline_function(0.5 - fractional_part / 2) / 2
62
+
63
+ # Assign indices for the support points
64
+ indices[3] = (base_idx + 3)%N
65
+ indices[2] = (base_idx + 2)%N
66
+ indices[1] = (base_idx + 1)%N
67
+ indices[0] = base_idx
68
+
69
+ # Adjust indices to start from 0
70
+ indices = indices - 1
71
+ # Square coefficients and normalize
72
+ coefficients = coefficients * coefficients
73
+ coefficients /= np.sum(coefficients, axis=0)
74
+
75
+ return indices, coefficients
foscat/FoCUS.py CHANGED
@@ -38,7 +38,7 @@ class FoCUS:
38
38
  mpi_rank=0,
39
39
  ):
40
40
 
41
- self.__version__ = "3.2.0"
41
+ self.__version__ = "3.3.0"
42
42
  # P00 coeff for normalization for scat_cov
43
43
  self.TMPFILE_VERSION = TMPFILE_VERSION
44
44
  self.P1_dic = None
@@ -2193,7 +2193,7 @@ class FoCUS:
2193
2193
  + ishape[axis + 2 :],
2194
2194
  )
2195
2195
 
2196
- return self.backend.bk_reshape(res, in_image.shape+[self.NORIENT])
2196
+ return self.backend.bk_reshape(res, in_image.shape + [self.NORIENT])
2197
2197
  elif self.use_1D:
2198
2198
  ishape = list(in_image.shape)
2199
2199
  if len(ishape) < axis + 1:
@@ -2265,7 +2265,7 @@ class FoCUS:
2265
2265
  res, ishape[0:axis] + [res.shape[1]] + ishape[axis + 1 :]
2266
2266
  )
2267
2267
 
2268
- return self.backend.bk_reshape(res, in_image.shape+[self.NORIENT])
2268
+ return self.backend.bk_reshape(res, in_image.shape + [self.NORIENT])
2269
2269
 
2270
2270
  else:
2271
2271
  nside = int(np.sqrt(image.shape[axis] // 12))
foscat/Softmax.py CHANGED
@@ -1,4 +1,4 @@
1
- #import tensorflow as tf
1
+ # import tensorflow as tf
2
2
  from tensorflow.keras.layers import Dense, Softmax
3
3
  from tensorflow.keras.models import Sequential
4
4
 
foscat/Spline1D.py CHANGED
@@ -1,46 +1,92 @@
1
+ import numpy as np
2
+
1
3
  class Spline1D:
2
4
  def __init__(self, nodes, degree=3):
5
+ """
6
+ Initializes the Spline1D instance.
7
+
8
+ Parameters:
9
+ - nodes (int): The number of nodes in the spline.
10
+ - degree (int): The degree of the spline. Default is 3.
11
+ """
3
12
  self.degree = degree
4
13
  self.nodes = nodes
5
- self.norm = [0] * (self.degree + 1)
6
- for i in range(self.degree + 1):
7
- self.norm[i] = (
8
- pow(-1, i)
9
- * (self.degree + 1)
10
- / (self._fact_spline(self.degree + 1 - i) * self._fact_spline(i))
11
- )
12
-
13
- def _fact_spline(self, x):
14
- if x <= 1:
15
- return 1
16
- return x * self._fact_spline(x - 1)
17
-
18
- def yplus_spline1d(self, x):
19
- if x < 0.0:
20
- return 0.0
21
- if self.degree == 0:
22
- if x == 0.0:
23
- return 0.5
24
- else:
25
- return 1.0
26
- return pow(x, self.degree)
27
-
28
- def calculate(self, x):
29
- y = [0] * self.nodes
30
- for i in range(self.nodes):
31
- tmp = 0
32
- tx = (self.nodes - 1) * x - i
33
- if x < 0:
34
- tx = -i
35
- if x > 1.0:
36
- tx = (self.nodes - 1) - i
37
- for j in range(self.degree + 1):
38
- tmp += self.norm[j] * self.yplus_spline1d(
39
- tx - j + (self.degree + 1) / 2
40
- )
41
- if tmp < 0:
42
- tmp = 0.0
43
- y[i] += tmp
44
- total = sum(y)
45
- y = [yi / total for yi in y]
46
- return y
14
+
15
+
16
+ def cubic_spline_function(self,x):
17
+ """
18
+ Evaluate the cubic spline basis function.
19
+
20
+ Args:
21
+ x (float or array): Input value(s) to evaluate the spline basis function.
22
+
23
+ Returns:
24
+ float or array: Result of the cubic spline basis function.
25
+ """
26
+ return -2 * x**3 + 3 * x**2
27
+
28
+
29
+ def eval(self,x):
30
+ """
31
+ Compute a 3rd-degree cubic spline with 4-point support.
32
+
33
+ Args:
34
+ x (float or array): Input value(s) to compute the spline.
35
+
36
+ Returns:
37
+ indices (array): Indices of the spline support points.
38
+ coefficients (array): Normalized spline coefficients.
39
+ """
40
+ N=self.nodes
41
+
42
+ if isinstance(x, float):
43
+ # Single scalar input
44
+ base_idx = int(x * (N-1))
45
+ indices = np.zeros([4], dtype="int")
46
+ coefficients = np.zeros([4])
47
+ else:
48
+ # Array input
49
+ base_idx = (x * (N-1)).astype("int")
50
+ indices = np.zeros([4, x.shape[0]], dtype="int")
51
+ coefficients = np.zeros([4, x.shape[0]])
52
+
53
+ # Compute the fractional part of the input
54
+ fractional_part = x * (N-1) - base_idx
55
+
56
+ # Compute spline coefficients for 4 support points
57
+ coefficients[3] = self.cubic_spline_function(fractional_part / 2) / 2
58
+ coefficients[2] = self.cubic_spline_function(0.5 + fractional_part / 2) / 2
59
+ coefficients[1] = self.cubic_spline_function(1 - fractional_part / 2) / 2
60
+ coefficients[0] = self.cubic_spline_function(0.5 - fractional_part / 2) / 2
61
+
62
+ # Assign indices for the support points
63
+ indices[3] = base_idx + 3
64
+ indices[2] = base_idx + 2
65
+ indices[1] = base_idx + 1
66
+ indices[0] = base_idx
67
+
68
+ # Handle boundary conditions
69
+ if isinstance(x, float):
70
+ if indices[0] == 0:
71
+ indices[0] = 1
72
+ if indices[1] == 0:
73
+ indices[1] = 1
74
+ if indices[2] == N + 1:
75
+ indices[2] = N
76
+ if indices[3] == N + 1:
77
+ indices[3] = N
78
+ if indices[3] == N + 2:
79
+ indices[3] = N
80
+ else:
81
+ indices[0, indices[0] == 0] = 1
82
+ indices[1, indices[1] == 0] = 1
83
+ indices[2, indices[2] >= N + 1] = N
84
+ indices[3, indices[3] >= N + 1] = N
85
+
86
+ # Adjust indices to start from 0
87
+ indices = indices - 1
88
+ # Square coefficients and normalize
89
+ coefficients = coefficients * coefficients
90
+ coefficients /= np.sum(coefficients, axis=0)
91
+
92
+ return indices, coefficients
foscat/Synthesis.py CHANGED
@@ -18,7 +18,7 @@ class Loss:
18
18
  batch=None,
19
19
  batch_data=None,
20
20
  batch_update=None,
21
- info_callback=False
21
+ info_callback=False,
22
22
  ):
23
23
 
24
24
  self.loss_function = function
@@ -29,6 +29,7 @@ class Loss:
29
29
  self.batch_data = batch_data
30
30
  self.batch_update = batch_update
31
31
  self.info = info_callback
32
+ self.id_loss = 0
32
33
 
33
34
  def eval(self, x, batch, return_all=False):
34
35
  if self.batch is None:
@@ -46,7 +47,12 @@ class Loss:
46
47
  else:
47
48
  return self.loss_function(x, batch, self.scat_operator, self.args)
48
49
 
49
-
50
+ def set_id_loss(self,id_loss):
51
+ self.id_loss = id_loss
52
+
53
+ def get_id_loss(self,id_loss):
54
+ return self.id_loss
55
+
50
56
  class Synthesis:
51
57
  def __init__(
52
58
  self,
@@ -60,6 +66,10 @@ class Synthesis:
60
66
 
61
67
  self.loss_class = loss_list
62
68
  self.number_of_loss = len(loss_list)
69
+
70
+ for k in range(self.number_of_loss):
71
+ self.loss_class[k].set_id_loss(k)
72
+
63
73
  self.__iteration__ = 1234
64
74
  self.nlog = 0
65
75
  self.m_dw, self.v_dw = 0.0, 0.0
@@ -109,7 +119,7 @@ class Synthesis:
109
119
  "nvidia-smi | awk '$2==\"N/A\"{print substr($9,1,length($9)-3),substr($11,1,length($11)-3),substr($13,1,length($13)-1)}' > smi_tmp.txt"
110
120
  )
111
121
  except:
112
- print('No nvidia GPU: Impossible to trace')
122
+ print("No nvidia GPU: Impossible to trace")
113
123
  self.nogpu = 1
114
124
 
115
125
  def stop_synthesis(self):
@@ -203,7 +213,9 @@ class Synthesis:
203
213
  )
204
214
  self.last_info = self.KEEP_TRACK(linfo, self.mpi_rank, add=True)
205
215
  else:
206
- l_loss, g = self.bk.loss(x, l_batch, self.loss_class[k], self.KEEP_TRACK)
216
+ l_loss, g = self.bk.loss(
217
+ x, l_batch, self.loss_class[k], self.KEEP_TRACK
218
+ )
207
219
 
208
220
  if g_tot is None:
209
221
  g_tot = g
@@ -213,7 +225,9 @@ class Synthesis:
213
225
  l_tot = l_tot + l_loss.numpy()
214
226
 
215
227
  if self.l_log[self.mpi_rank * self.MAXNUMLOSS + k] == -1:
216
- self.l_log[self.mpi_rank * self.MAXNUMLOSS + k] = l_loss.numpy() / nstep
228
+ self.l_log[self.mpi_rank * self.MAXNUMLOSS + k] = (
229
+ l_loss.numpy() / nstep
230
+ )
217
231
  else:
218
232
  self.l_log[self.mpi_rank * self.MAXNUMLOSS + k] = (
219
233
  self.l_log[self.mpi_rank * self.MAXNUMLOSS + k]
@@ -346,7 +360,7 @@ class Synthesis:
346
360
  except:
347
361
  print("Error: unable to start thread for GPU survey")
348
362
 
349
- #start = time.time()
363
+ # start = time.time()
350
364
 
351
365
  if self.mpi_size > 1:
352
366
  num_loss = np.zeros([1], dtype="int32")
@@ -385,7 +399,7 @@ class Synthesis:
385
399
 
386
400
  self.noise_idx = None
387
401
 
388
- #for k in range(self.number_of_loss):
402
+ # for k in range(self.number_of_loss):
389
403
  # if self.loss_class[k].batch is not None:
390
404
  # l_batch = self.loss_class[k].batch(
391
405
  # self.loss_class[k].batch_data, 0, init=True
@@ -397,7 +411,7 @@ class Synthesis:
397
411
 
398
412
  maxitt = NUM_EPOCHS
399
413
 
400
- # start_x = x.copy()
414
+ # start_x = x.copy()
401
415
 
402
416
  for iteration in range(NUM_STEP_BIAS):
403
417
 
@@ -422,7 +436,7 @@ class Synthesis:
422
436
  self.loss_class[k].batch_update(
423
437
  self.loss_class[k].batch_data, omap
424
438
  )
425
- #if self.loss_class[k].batch is not None:
439
+ # if self.loss_class[k].batch is not None:
426
440
  # l_batch = self.loss_class[k].batch(
427
441
  # self.loss_class[k].batch_data, 0, init=True
428
442
  # )
foscat/alm.py ADDED
@@ -0,0 +1,140 @@
1
+ import healpy as hp
2
+ import numpy as np
3
+
4
+ class alm():
5
+
6
+ def __init__(self,backend=None,lmax=24,limit_range=1E7):
7
+ self._logtab={}
8
+ self.lmax=0
9
+ for k in range(1,2*lmax+1):
10
+ self._logtab[k]=np.log(k)
11
+ self._limit_range=1/limit_range
12
+ self._log_limit_range=np.log(limit_range)
13
+ if backend is None:
14
+ import foscat.scat_cov as sc
15
+ self.sc=sc.funct()
16
+ self.backend=self.sc.backend
17
+ else:
18
+ self.backend=backend.backend
19
+
20
+ def log(self,v):
21
+ #return np.log(v)
22
+ if isinstance(v,np.ndarray):
23
+ return np.array([self.log(k) for k in v])
24
+ if v<self.lmax*2+1:
25
+ return self._logtab[v]
26
+ else:
27
+ self._logtab[v]=np.log(v)
28
+ return self._logtab[v]
29
+
30
+ # Fonction pour calculer la double factorielle
31
+ def double_factorial_log(self,n):
32
+ if n <= 0:
33
+ return 0.0
34
+ result = 0.0
35
+ for i in range(n, 0, -2):
36
+ result += self.log(i)
37
+ return result
38
+
39
+ # Calcul des P_{lm}(x) pour tout l inclus dans [m,lmax]
40
+ def compute_legendre_m(self,x,m,lmax):
41
+ # Étape 1 : Calcul de P_{mm}(x)
42
+ if m == 0:
43
+ Pmm = 1.0
44
+ else:
45
+ Pmm = (-1)**m * (1 - x**2)**(m/2)
46
+
47
+ result=np.zeros([lmax-m+1,x.shape[0]])
48
+ ratio=np.zeros([lmax-m+1,1])
49
+
50
+ # Si l == m, c'est directement P_{mm}
51
+ result[0]=Pmm
52
+ ratio[0,0]= self.double_factorial_log(2*m - 1)-0.5*np.sum(self.log(1+np.arange(2*m)))
53
+
54
+ if m == lmax:
55
+ return result*np.exp(ratio)*np.sqrt((2*(np.arange(lmax-m+1)-m))/(4*np.pi)).reshape(lmax+1-m,1)
56
+
57
+ # Étape 2 : Calcul de P_{l+1, m}(x)
58
+ result[1] = x * (2*m + 1) * result[0]
59
+
60
+ ratio[1,0]=ratio[0,0]-0.5*self.log(2*m+1)
61
+
62
+ # Étape 3 : Récurence pour l > m + 1
63
+ for l in range(m + 2, lmax+1):
64
+ result[l-m] = ((2*l - 1) * x * result[l-m-1] - (l + m - 1) * result[l-m-2]) / (l - m)
65
+ ratio[l-m,0] = 0.5*self.log(l-m)-0.5*self.log(l+m)+ratio[l-m-1,0]
66
+ if np.max(abs(result[l-m]))>self._limit_range:
67
+ result[l-m-1]*=self._limit_range
68
+ result[l-m]*=self._limit_range
69
+ ratio[l-m-1,0]+=self._log_limit_range
70
+ ratio[l-m,0]+=self._log_limit_range
71
+
72
+ return result*np.exp(ratio)*(np.sqrt(4*np.pi*(2*(np.arange(lmax-m+1)+m)+1))).reshape(lmax+1-m,1)
73
+
74
+ def comp_tf(self,im,ph):
75
+ nside=int(np.sqrt(im.shape[0]//12))
76
+ n=0
77
+ ii=0
78
+ ft_im=[]
79
+ for k in range(nside-1):
80
+ N=4*(k+1)
81
+ ft_im.append(self.backend.bk_fft(im[n:n+N])[:N//2+1]*np.exp(-1J*np.arange(N//2+1)/N*ph[n]))
82
+ ft_im.append(self.backend.bk_zeros((3*nside-N//2-1),dtype=self.backend.all_cbk_type))
83
+ n+=N
84
+ ii+=1
85
+ for k in range(2*nside+1):
86
+ N=4*nside
87
+ ft_im.append(self.backend.bk_fft(im[n:n+N])[:N//2+1]*np.exp(-1J*np.arange(N//2+1)/N*ph[n]))
88
+ ft_im.append(self.backend.bk_zeros((3*nside-N//2-1),dtype=self.backend.all_cbk_type))
89
+ n+=N
90
+ ii+=1
91
+ for k in range(nside-1):
92
+ N=4*(nside-1-k)
93
+ ft_im.append(self.backend.bk_fft(im[n:n+N])[:N//2+1]*np.exp(-1J*np.arange(N//2+1)/N*ph[n]))
94
+ ft_im.append(self.backend.bk_zeros((3*nside-N//2-1),dtype=self.backend.all_cbk_type))
95
+ n+=N
96
+ ii+=1
97
+ return self.backend.bk_reshape(self.backend.bk_concat(ft_im,axis=0),[4*nside-1,3*nside])
98
+
99
+ def anafast(self,im,map2=None,nest=True):
100
+ nside=int(np.sqrt(im.shape[0]//12))
101
+ th,ph=hp.pix2ang(nside,np.arange(12*nside*nside))
102
+ if nest:
103
+ idx=hp.ring2nest(nside,np.arange(12*nside**2))
104
+ ft_im=self.comp_tf(self.backend.bk_complex(im[idx],0*im),ph)
105
+ if map2 is not None:
106
+ ft_im2=self.comp_tf(self.backend.bk_complex(map2[idx],0*im),ph)
107
+ else:
108
+ ft_im=self.comp_tf(self.backend.bk_complex(im,0*im),ph)
109
+ if map2 is not None:
110
+ ft_im2=self.comp_tf(self.backend.bk_complex(map2,0*im),ph)
111
+
112
+ co_th=np.cos(np.unique(th))
113
+
114
+ lmax=3*nside-1
115
+
116
+ cl2=None
117
+ cl2_L1=None
118
+ for m in range(lmax+1):
119
+ plm=self.compute_legendre_m(co_th,m,3*nside-1)/(12*nside**2)
120
+
121
+ tmp=self.backend.bk_reduce_sum(plm*ft_im[:,m],1)
122
+
123
+ if map2 is not None:
124
+ tmp2=self.backend.bk_reduce_sum(plm*ft_im2[:,m],1)
125
+ else:
126
+ tmp2=tmp
127
+
128
+ tmp=self.backend.bk_real((tmp*self.backend.bk_conjugate(tmp2)))
129
+ if cl2 is None:
130
+ cl2=tmp
131
+ cl2_l1=self.backend.bk_L1(tmp)
132
+ else:
133
+ tmp=self.backend.bk_concat([self.backend.bk_zeros((m),dtype=self.backend.all_bk_type),tmp],axis=0)
134
+ cl2+=2*tmp
135
+ cl2_l1+=2*self.backend.bk_L1(tmp)
136
+ cl2=cl2*(1+np.clip((np.arange(cl2.shape[0])-2*nside)/(3*nside),0,1))/(2*np.arange(cl2.shape[0])+1)* \
137
+ (1+np.clip((np.arange(cl2.shape[0])-2.4*nside)/(2.5*nside),0,1))
138
+ cl2_l1=cl2_l1*(1+np.clip((np.arange(cl2.shape[0])-2*nside)/(3*nside),0,1))/(2*np.arange(cl2.shape[0])+1)* \
139
+ (1+np.clip((np.arange(cl2.shape[0])-2.4*nside)/(2.5*nside),0,1))
140
+ return cl2,cl2_l1
foscat/backend.py CHANGED
@@ -189,18 +189,18 @@ class foscat_backend:
189
189
  tmp[:, :, 0, k * 2 + 1] = np.cos((x.T) * (k + 1))
190
190
  tmp[:, :, 0, k * 2 + 2] = np.sin((x.T) * (k + 1))
191
191
  for l_orient in range(nharm):
192
- tmp[:, :, k * 2 + 1, l_orient * 2 + 1] = np.cos(x * (k + 1)) * np.cos(
193
- (x.T) * (l_orient + 1)
194
- )
195
- tmp[:, :, k * 2 + 2, l_orient * 2 + 1] = np.sin(x * (k + 1)) * np.cos(
196
- (x.T) * (l_orient + 1)
197
- )
198
- tmp[:, :, k * 2 + 1, l_orient * 2 + 2] = np.cos(x * (k + 1)) * np.sin(
199
- (x.T) * (l_orient + 1)
200
- )
201
- tmp[:, :, k * 2 + 2, l_orient * 2 + 2] = np.sin(x * (k + 1)) * np.sin(
202
- (x.T) * (l_orient + 1)
203
- )
192
+ tmp[:, :, k * 2 + 1, l_orient * 2 + 1] = np.cos(
193
+ x * (k + 1)
194
+ ) * np.cos((x.T) * (l_orient + 1))
195
+ tmp[:, :, k * 2 + 2, l_orient * 2 + 1] = np.sin(
196
+ x * (k + 1)
197
+ ) * np.cos((x.T) * (l_orient + 1))
198
+ tmp[:, :, k * 2 + 1, l_orient * 2 + 2] = np.cos(
199
+ x * (k + 1)
200
+ ) * np.sin((x.T) * (l_orient + 1))
201
+ tmp[:, :, k * 2 + 2, l_orient * 2 + 2] = np.sin(
202
+ x * (k + 1)
203
+ ) * np.sin((x.T) * (l_orient + 1))
204
204
 
205
205
  self._fft_2_orient[(norient, nharm, imaginary)] = self.bk_cast(
206
206
  self.constant(
@@ -424,7 +424,10 @@ class foscat_backend:
424
424
  for l_orient in range(w.shape[3]):
425
425
  for j in range(res.shape[0]):
426
426
  tmp = self.scipy.signal.convolve2d(
427
- x[j, :, :, k], w[:, :, k, l_orient], mode="same", boundary="symm"
427
+ x[j, :, :, k],
428
+ w[:, :, k, l_orient],
429
+ mode="same",
430
+ boundary="symm",
428
431
  )
429
432
  res[j, :, :, l_orient] += tmp
430
433
  del tmp
@@ -549,13 +552,13 @@ class foscat_backend:
549
552
  xi = self.bk_imag(x)
550
553
 
551
554
  r = self.backend.sign(xr) * self.backend.sqrt(self.backend.sign(xr) * xr)
552
- #return r
555
+ # return r
553
556
  i = self.backend.sign(xi) * self.backend.sqrt(self.backend.sign(xi) * xi)
554
-
555
- if self.BACKEND==self.TORCH:
557
+
558
+ if self.BACKEND == self.TORCH:
556
559
  return r
557
560
  else:
558
- return self.bk_complex(r,i)
561
+ return self.bk_complex(r, i)
559
562
  else:
560
563
  return self.backend.sign(x) * self.backend.sqrt(self.backend.sign(x) * x)
561
564
 
@@ -730,21 +733,21 @@ class foscat_backend:
730
733
  def bk_reduce_std(self, data, axis=None):
731
734
  if axis is None:
732
735
  if self.BACKEND == self.TENSORFLOW:
733
- r=self.backend.math.reduce_std(data)
736
+ r = self.backend.math.reduce_std(data)
734
737
  if self.BACKEND == self.TORCH:
735
- r=self.backend.std(data)
738
+ r = self.backend.std(data)
736
739
  if self.BACKEND == self.NUMPY:
737
- r=np.std(data)
738
- return self.bk_complex(r,0*r)
740
+ r = np.std(data)
741
+ return self.bk_complex(r, 0 * r)
739
742
  else:
740
743
  if self.BACKEND == self.TENSORFLOW:
741
- r=self.backend.math.reduce_std(data, axis=axis)
744
+ r = self.backend.math.reduce_std(data, axis=axis)
742
745
  if self.BACKEND == self.TORCH:
743
- r=self.backend.std(data, axis)
746
+ r = self.backend.std(data, axis)
744
747
  if self.BACKEND == self.NUMPY:
745
- r=np.std(data, axis)
748
+ r = np.std(data, axis)
746
749
  if self.bk_is_complex(data):
747
- return self.bk_complex(r,0*r)
750
+ return self.bk_complex(r, 0 * r)
748
751
  else:
749
752
  return r
750
753
 
@@ -922,6 +925,22 @@ class foscat_backend:
922
925
  else:
923
926
  return np.concatenate(data, axis=axis)
924
927
 
928
+ def bk_zeros(self, shape,dtype=None):
929
+ if self.BACKEND == self.TENSORFLOW:
930
+ return self.backend.zeros(shape,dtype=dtype)
931
+ if self.BACKEND == self.TORCH:
932
+ return self.backend.zeros(shape,dtype=dtype)
933
+ if self.BACKEND == self.NUMPY:
934
+ return np.zeros(shape,dtype=dtype)
935
+
936
+ def bk_fft(self, data):
937
+ if self.BACKEND == self.TENSORFLOW:
938
+ return self.backend.signal.fft(data)
939
+ if self.BACKEND == self.TORCH:
940
+ return self.backend.fft(data)
941
+ if self.BACKEND == self.NUMPY:
942
+ return self.backend.fft.fft(data)
943
+
925
944
  def bk_conjugate(self, data):
926
945
 
927
946
  if self.BACKEND == self.TENSORFLOW:
foscat/backend_tens.py CHANGED
@@ -24,9 +24,10 @@ class foscat_backend_tens:
24
24
  operation.gpulist[(operation.gpupos + self.curr_gpu) % operation.ngpu]
25
25
  ):
26
26
  print(
27
- "%s Run [PROC=%04d] on GPU %s"
27
+ "%s Run %d [PROC=%04d] on GPU %s"
28
28
  % (
29
29
  loss_function.name,
30
+ loss_function.id_loss,
30
31
  self.mpi_rank,
31
32
  operation.gpulist[
32
33
  (operation.gpupos + self.curr_gpu) % operation.ngpu
@@ -43,7 +43,6 @@ class loss_backend:
43
43
  else:
44
44
  l_x = x.clone().detach().requires_grad_(True)
45
45
 
46
-
47
46
  if KEEP_TRACK is not None:
48
47
  l_loss, linfo = loss_function.eval(l_x, batch, return_all=True)
49
48
  else: