Coverage for pySDC/helpers/ParaDiagHelper.py: 100%
36 statements
« prev ^ index » next coverage.py v7.10.4, created at 2025-08-21 06:49 +0000
« prev ^ index » next coverage.py v7.10.4, created at 2025-08-21 06:49 +0000
1import numpy as np
2import scipy.sparse as sp
5def get_FFT_matrix(N):
6 """
7 Get matrix for computing FFT of size N. Normalization is like "ortho" in numpy.
8 Compute inverse FFT by multiplying by the complex conjugate (numpy.conjugate) of this matrix
10 Args:
11 N (int): Size of the data to be transformed
13 Returns:
14 numpy.ndarray: Dense square matrix to compute forward transform
15 """
16 idx_1d = np.arange(N, dtype=complex)
17 i1, i2 = np.meshgrid(idx_1d, idx_1d)
19 return np.exp(-2 * np.pi * 1j * i1 * i2 / N) / np.sqrt(N)
22def get_E_matrix(N, alpha=0):
23 """
24 Get NxN matrix with -1 on the lower subdiagonal, -alpha in the top right and 0 elsewhere
26 Args:
27 N (int): Size of the matrix
28 alpha (float): Negative of value in the top right
30 Returns:
31 sparse E matrix
32 """
33 E = sp.diags(
34 [
35 -1.0,
36 ]
37 * (N - 1),
38 offsets=-1,
39 ).tolil()
40 E[0, -1] = -alpha
41 return E
44def get_J_matrix(N, alpha):
45 """
46 Get matrix for weights in the weighted inverse FFT
48 Args:
49 N (int): Size of the matrix
50 alpha (float): alpha parameter in ParaDiag
52 Returns:
53 sparse J matrix
54 """
55 gamma = alpha ** (-np.arange(N) / N)
56 return sp.diags(gamma)
59def get_J_inv_matrix(N, alpha):
60 """
61 Get matrix for weights in the weighted FFT
63 Args:
64 N (int): Size of the matrix
65 alpha (float): alpha parameter in ParaDiag
67 Returns:
68 sparse J_inv matrix
69 """
70 gamma = alpha ** (-np.arange(N) / N)
71 return sp.diags(1 / gamma)
74def get_weighted_FFT_matrix(N, alpha):
75 """
76 Get matrix for the weighted FFT
78 Args:
79 N (int): Size of the matrix
80 alpha (float): alpha parameter in ParaDiag
82 Returns:
83 Dense weighted FFT matrix
84 """
85 return get_FFT_matrix(N) @ get_J_inv_matrix(N, alpha)
88def get_weighted_iFFT_matrix(N, alpha):
89 """
90 Get matrix for the weighted inverse FFT
92 Args:
93 N (int): Size of the matrix
94 alpha (float): alpha parameter in ParaDiag
96 Returns:
97 Dense weighted FFT matrix
98 """
99 return get_J_matrix(N, alpha) @ np.conjugate(get_FFT_matrix(N))
102def get_H_matrix(N, sweeper_params):
103 """
104 Get sparse matrix for computing the collocation update. Requires not to do a collocation update!
106 Args:
107 N (int): Number of collocation nodes
108 sweeper_params (dict): Parameters for the sweeper
110 Returns:
111 Sparse matrix for collocation update
112 """
113 assert sweeper_params['quad_type'] == 'RADAU-RIGHT'
114 H = sp.eye(N).tolil() * 0
115 H[:, -1] = 1
116 return H
119def get_G_inv_matrix(l, L, alpha, sweeper_params):
120 M = sweeper_params['num_nodes']
121 I_M = sp.eye(M)
122 E_alpha = get_E_matrix(L, alpha)
123 H = get_H_matrix(M, sweeper_params)
125 gamma = alpha ** (-np.arange(L) / L)
126 diags = np.fft.fft(1 / gamma * E_alpha[:, 0].toarray().flatten(), norm='backward')
127 G = (diags[l] * H + I_M).tocsc()
128 if M > 1:
129 return sp.linalg.inv(G).toarray()
130 else:
131 return 1 / G.toarray()