Skip to content

Commit 76545ad

Browse files
committed
Spectral differentiation fix
1 parent e9ba07f commit 76545ad

1 file changed

Lines changed: 53 additions & 47 deletions

File tree

epde/preprocessing/deriv_calculators.py

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,20 @@ def spectral_derivative_1d(self, func: np.ndarray, grid: np.ndarray, n=None, ste
176176
frequencies = np.fft.rfftfreq(spacing_vector.size, d=(spacing_vector[0][1] - spacing_vector[0][0]))
177177
frequencies_filtered = self.butterworth_filter(frequencies, n, steepness)
178178
return np.real(np.fft.irfft(1j * 2 * np.pi * frequencies_filtered * func_projection_filtered))
179-
180-
def spectral_derivative_nd(self, func: np.ndarray, grid: list, n=None, steepness=1,
181-
deriv_hist: list = []):
182-
'''Многомерная спектральная производная,принимает на вход количество частот по каждой размерности и крутизну для фильтра Баттерворта, если они не указаны-фильтрация не производится'''
183179

180+
def spectral_derivative_nd(self, func : np.ndarray, grid : list, n = None, steepness = 1,
181+
deriv_hist : list = []):
182+
'''Многомерная спектральная производная,принимает на вход количество частот по каждой размерности и крутизну для фильтра Баттерворта, если они не указаны-фильтрация не производится'''
183+
184184
if isinstance(n, int):
185185
n = np.full(shape=len(grid), fill_value=n)
186-
if n is None:
186+
if isinstance(n, type(None)):
187187
n = np.min(func.shape)
188188
all_dim_derivative = []
189-
func_projection = np.fft.fftn(func, axes=[0,1])
190-
189+
func_projection = np.fft.fftn(func)
190+
print(func_projection.shape) #marker
191+
inverter = lambda x: 1 if x == 0 else (x if x != 1 else 0)
192+
191193
for counter, i in enumerate(grid):
192194
spacing_vector = np.reshape(grid[counter], (1, grid[counter].size))
193195
frequencies = np.fft.fftfreq(spacing_vector.size, d=(spacing_vector[0][1] - spacing_vector[0][0]))
@@ -197,9 +199,9 @@ def spectral_derivative_nd(self, func: np.ndarray, grid: list, n=None, steepness
197199
derivative = np.real(np.fft.ifftn(derivative*1j * 2 * np.pi))
198200
all_dim_derivative.append((deriv_descr, derivative))
199201
return all_dim_derivative
200-
201-
def differentiate(self, field: np.ndarray, grid: list, max_order: Union[int, list],
202-
mixed: bool = False, n=None, steepness=1, deriv_hist: list = []) -> list:
202+
203+
def differentiate(self, field : np.ndarray, grid : list, max_order : Union[int, list],
204+
mixed : bool = False, n = None, steepness = 1, deriv_hist : list = []) -> list:
203205
if isinstance(max_order, int):
204206
max_order = [max_order,] * field.ndim
205207
else:
@@ -210,70 +212,74 @@ def differentiate(self, field: np.ndarray, grid: list, max_order: Union[int, lis
210212
def num_of_derivs_with_ord(ords):
211213
temp = ords + field.ndim - 1
212214
numerator = np.math.factorial(temp)
213-
denominator = np.math.factorial(
214-
ords) * np.math.factorial(field.ndim - 1)
215+
denominator = np.math.factorial(ords) * np.math.factorial(field.ndim - 1)
215216
return int(numerator / denominator)
216-
expeced_num_of_derivs = sum([num_of_derivs_with_ord(
217-
cur_ord + 1) for cur_ord in range(max_order[0])])
217+
expeced_num_of_derivs = sum([num_of_derivs_with_ord(cur_ord + 1) for cur_ord in range(max_order[0])])
218218
else:
219219
expeced_num_of_derivs = sum(max_order)
220-
derivatives = {}
221-
220+
derivatives = {}
221+
222222
if mixed:
223223
for axis in range(field.ndim):
224-
higher_ord_derivs = self.spectral_derivative_nd(field, grid, n=n, steepness=steepness,
225-
deriv_hist=deriv_hist)
224+
higher_ord_derivs = self.spectral_derivative_nd(field, grid, n = n, steepness = steepness,
225+
deriv_hist = deriv_hist)
226226
part_derivs = []
227227
for history, field in higher_ord_derivs:
228-
part_derivs.extend(self.differentiate(
229-
field, grid, max_order - 1, deriv_hist=history))
228+
part_derivs.extend(self.differentiate(field, grid, max_order - 1, deriv_hist=history))
230229
# self.differentiate(field, grid, max_order)
231230
for key, deriv in part_derivs:
232231
if key in derivatives.keys():
233-
assert np.all(np.isclose(
234-
deriv, derivatives[key])), 'Shuffle in differentiation orders shall not affect the values.'
232+
assert np.all(np.isclose(deriv, derivatives[key])), 'Shuffle in differentiation orders shall not affect the values.'
235233
derivatives[key] = deriv
236234
else:
237235
for axis in range(field.ndim):
238-
axis_derivs = self.spectral_derivative_high_ord(field, grid, axis=axis, max_order=max_order[axis],
239-
n=n, steepness=steepness)
236+
axis_derivs = self.spectral_derivative_high_ord(field, grid, axis = axis, max_order = max_order[axis],
237+
n = n, steepness = steepness)
240238
for key, deriv in axis_derivs:
241239
derivatives[key] = deriv
242-
243-
# print(f'derivatives orders are {[deriv[0] for deriv in derivatives]}')
240+
241+
print(f'derivatives orders are {[deriv[0] for deriv in derivatives]}')
244242
if len(derivatives) != expeced_num_of_derivs:
245-
raise Exception(
246-
f'Expected number of derivatives {expeced_num_of_derivs} does not match obtained {len(derivatives)}')
243+
raise Exception(f'Expected number of derivatives {expeced_num_of_derivs} does not match obtained {len(derivatives)}')
247244
return derivatives
248-
249-
def __call__(self, data: np.ndarray, grid: list, max_order: Union[int, list],
250-
mixed: bool = False, n=None, steepness=1) -> np.ndarray:
251-
def make_unsparse_sparse(*grids): # TODO^ find more elegant solution
245+
246+
def __call__(self, data : np.ndarray, grid : list, max_order : Union[int, list],
247+
mixed : bool = False, n = None, steepness = 1) -> np.ndarray:
248+
def make_unsparse_sparse(*grids): # TODO^ find more e;egant solution
252249
unique_vals = [np.unique(grid) for grid in grids]
253-
return np.meshgrid(*unique_vals, sparse=True, indexing='ij')
254-
250+
return np.meshgrid(*unique_vals, sparse = True, indexing = 'ij')
251+
255252
if len(grid) > 1 and grid[0].shape == grid[1].shape:
256253
grid = make_unsparse_sparse(*grid)
257-
if isinstance(n, int) or n is None:
258-
n = np.full(shape=len(grid), fill_value=n)
259-
254+
if isinstance(n, int) or isinstance(n, type(None)):
255+
n = np.full(shape=len(grid), fill_value=n)
256+
260257
derivatives = self.differentiate(data, grid, max_order, mixed, n, steepness).values()
261258
derivatives = np.vstack([der.reshape(-1) for der in derivatives]).T
262-
259+
263260
return derivatives
264-
265-
def spectral_derivative_high_ord(self, func: np.ndarray, grid: list, axis: int = 0,
266-
max_order: int = 1, n: np.ndarray = None, steepness=1) -> list:
261+
262+
def spectral_derivative_high_ord(self, func : np.ndarray, grid : list, axis : int = 0,
263+
max_order : int = 1, n = None, steepness = 1) -> list:
267264
derivs = []
268265
cur_deriv = func
266+
func_projection = np.fft.fftn(func)
267+
spacing_vector = np.reshape(grid[axis], (1, grid[axis].size))
268+
frequencies = np.fft.fftfreq(spacing_vector.size, d=(spacing_vector[0][1] - spacing_vector[0][0]))
269+
print(func_projection.shape) #marker
269270
# inverter = lambda x: 1 if x == 0 else (x if x != 1 else 0)
270-
271-
for deriv_idx in range(max_order):
272-
deriv_descr = tuple([axis,] * (deriv_idx + 1))
273-
cur_deriv = np.apply_along_axis(self.spectral_derivative_1d, axis, cur_deriv, grid[axis],
274-
n[axis], steepness)
271+
if isinstance(n, int):
272+
n = np.full(shape=len(grid), fill_value=n)
273+
if isinstance(n, type(None)):
274+
n = np.min(func.shape)
275+
frequencies_filtered = self.butterworth_filter(frequencies, n[axis], steepness)
276+
for deriv_idx in range(1,max_order+1):
277+
deriv_descr = tuple([axis,] * (deriv_idx)) # inverter(axis) V
278+
derivative = np.apply_along_axis(np.multiply, axis, func_projection,
279+
np.power(frequencies_filtered*1j * 2 * np.pi, deriv_idx,dtype = complex))
280+
cur_deriv= np.real(np.fft.ifftn(derivative))
275281
derivs.append((deriv_descr, cur_deriv))
276-
282+
277283
return derivs
278284

279285
class TotalVariation(AbstractDeriv):

0 commit comments

Comments
 (0)