modulo-vki 2.0.6__py3-none-any.whl → 2.0.7__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.
- modulo_vki/__init__.py +22 -22
- modulo_vki/core/__init__.py +9 -9
- modulo_vki/core/_dft.py +61 -61
- modulo_vki/core/_dmd_s.py +72 -72
- modulo_vki/core/_k_matrix.py +81 -81
- modulo_vki/core/_mpod_space.py +180 -180
- modulo_vki/core/_mpod_time.py +154 -154
- modulo_vki/core/_pod_space.py +184 -184
- modulo_vki/core/_pod_time.py +48 -48
- modulo_vki/core/_spod_s.py +101 -101
- modulo_vki/core/_spod_t.py +104 -104
- modulo_vki/modulo.py +828 -828
- modulo_vki/utils/__init__.py +4 -4
- modulo_vki/utils/_plots.py +51 -51
- modulo_vki/utils/_utils.py +341 -341
- modulo_vki/utils/others.py +452 -452
- modulo_vki/utils/read_db.py +339 -339
- {modulo_vki-2.0.6.dist-info → modulo_vki-2.0.7.dist-info}/LICENSE +21 -21
- {modulo_vki-2.0.6.dist-info → modulo_vki-2.0.7.dist-info}/METADATA +304 -304
- modulo_vki-2.0.7.dist-info/RECORD +22 -0
- modulo_vki-2.0.6.dist-info/RECORD +0 -22
- {modulo_vki-2.0.6.dist-info → modulo_vki-2.0.7.dist-info}/WHEEL +0 -0
- {modulo_vki-2.0.6.dist-info → modulo_vki-2.0.7.dist-info}/top_level.txt +0 -0
modulo_vki/__init__.py
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
#from ._version import get_versions
|
|
3
|
-
#__version__ = get_versions()['version']
|
|
4
|
-
#del get_versions
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# from .utils.read_db import *
|
|
8
|
-
# from .utils._utils import *
|
|
9
|
-
# from .utils._plots import *
|
|
10
|
-
# from .utils.others import *
|
|
11
|
-
|
|
12
|
-
# from .core._k_matrix import *
|
|
13
|
-
# from .core._dft import *
|
|
14
|
-
# from .core._dmd_s import *
|
|
15
|
-
# from .core._k_matrix import *
|
|
16
|
-
# from .core._mpod_time import *
|
|
17
|
-
# from .core._mpod_space import *
|
|
18
|
-
# from .core._pod_time import *
|
|
19
|
-
# from .core._pod_space import *
|
|
20
|
-
# from .core._spod_s import *
|
|
21
|
-
# from .core._spod_t import *
|
|
22
|
-
|
|
1
|
+
|
|
2
|
+
#from ._version import get_versions
|
|
3
|
+
#__version__ = get_versions()['version']
|
|
4
|
+
#del get_versions
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# from .utils.read_db import *
|
|
8
|
+
# from .utils._utils import *
|
|
9
|
+
# from .utils._plots import *
|
|
10
|
+
# from .utils.others import *
|
|
11
|
+
|
|
12
|
+
# from .core._k_matrix import *
|
|
13
|
+
# from .core._dft import *
|
|
14
|
+
# from .core._dmd_s import *
|
|
15
|
+
# from .core._k_matrix import *
|
|
16
|
+
# from .core._mpod_time import *
|
|
17
|
+
# from .core._mpod_space import *
|
|
18
|
+
# from .core._pod_time import *
|
|
19
|
+
# from .core._pod_space import *
|
|
20
|
+
# from .core._spod_s import *
|
|
21
|
+
# from .core._spod_t import *
|
|
22
|
+
|
|
23
23
|
from modulo_vki.modulo import ModuloVKI
|
modulo_vki/core/__init__.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
from ._dft import *
|
|
2
|
-
from ._dmd_s import *
|
|
3
|
-
from ._k_matrix import *
|
|
4
|
-
from ._mpod_space import *
|
|
5
|
-
from ._mpod_time import *
|
|
6
|
-
from ._pod_space import *
|
|
7
|
-
from ._pod_time import *
|
|
8
|
-
from ._spod_s import *
|
|
9
|
-
from ._spod_t import *
|
|
1
|
+
from ._dft import *
|
|
2
|
+
from ._dmd_s import *
|
|
3
|
+
from ._k_matrix import *
|
|
4
|
+
from ._mpod_space import *
|
|
5
|
+
from ._mpod_time import *
|
|
6
|
+
from ._pod_space import *
|
|
7
|
+
from ._pod_time import *
|
|
8
|
+
from ._spod_s import *
|
|
9
|
+
from ._spod_t import *
|
modulo_vki/core/_dft.py
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
from tqdm import tqdm
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def dft_fit(N_T, F_S, D, FOLDER_OUT, SAVE_DFT=False):
|
|
8
|
-
"""
|
|
9
|
-
This function computes the DFT form the dataset D.
|
|
10
|
-
Currently, this does not handle the memory saving feature.
|
|
11
|
-
|
|
12
|
-
:param N_T: int.
|
|
13
|
-
number of snapshots
|
|
14
|
-
:param F_S:
|
|
15
|
-
Sampling frequency (in Hz)
|
|
16
|
-
:param D:
|
|
17
|
-
Snapshot matrix
|
|
18
|
-
:param FOLDER_OUT:
|
|
19
|
-
Folder in which the results are saved if SAVE_SPATIAL_POD = True
|
|
20
|
-
:param SAVE_DFT:
|
|
21
|
-
If True, results are saved on disk and released from memory
|
|
22
|
-
|
|
23
|
-
:return: Sorted_Freqs, np.array
|
|
24
|
-
Frequency bins, in Hz.
|
|
25
|
-
:return: Phi_F, np.array
|
|
26
|
-
(Complex) Spatial structures for each mode
|
|
27
|
-
:return: SIGMA_F, np.array
|
|
28
|
-
(real) amplitude of each modes
|
|
29
|
-
|
|
30
|
-
"""
|
|
31
|
-
n_t = int(N_T)
|
|
32
|
-
Freqs = np.fft.fftfreq(n_t) * F_S # Compute the frequency bins
|
|
33
|
-
# PSI_F = np.conj(np.fft.fft(np.eye(n_t)) / np.sqrt(n_t)) # Prepare the Fourier Matrix.
|
|
34
|
-
|
|
35
|
-
# Method 1 (didactic!)
|
|
36
|
-
# PHI_SIGMA = np.dot(D, np.conj(PSI_F)) # This is PHI * SIGMA
|
|
37
|
-
|
|
38
|
-
# Method 2
|
|
39
|
-
PHI_SIGMA = (np.fft.fft(D, n_t, 1)) / (n_t ** 0.5)
|
|
40
|
-
|
|
41
|
-
PHI_F = np.zeros((D.shape[0], n_t), dtype=complex) # Initialize the PHI_F MATRIX
|
|
42
|
-
SIGMA_F = np.zeros(n_t) # Initialize the SIGMA_F MATRIX
|
|
43
|
-
|
|
44
|
-
# Now we proceed with the normalization. This is also intense so we time it
|
|
45
|
-
for r in tqdm(range(0, n_t)): # Loop over the PHI_SIGMA to normalize
|
|
46
|
-
# MEX = 'Proj ' + str(r + 1) + ' /' + str(n_t)
|
|
47
|
-
# print(MEX)
|
|
48
|
-
SIGMA_F[r] = abs(np.vdot(PHI_SIGMA[:, r], PHI_SIGMA[:, r])) ** 0.5
|
|
49
|
-
PHI_F[:, r] = PHI_SIGMA[:, r] / SIGMA_F[r]
|
|
50
|
-
|
|
51
|
-
Indices = np.flipud(np.argsort(SIGMA_F)) # find indices for sorting in decreasing order
|
|
52
|
-
Sorted_Sigmas = SIGMA_F[Indices] # Sort all the sigmas
|
|
53
|
-
Sorted_Freqs = Freqs[Indices] # Sort all the frequencies accordingly.
|
|
54
|
-
Phi_F = PHI_F[:, Indices] # Sorted Spatial Structures Matrix
|
|
55
|
-
SIGMA_F = Sorted_Sigmas # Sorted Amplitude Matrix (vector)
|
|
56
|
-
|
|
57
|
-
if SAVE_DFT:
|
|
58
|
-
os.makedirs(FOLDER_OUT + 'DFT', exist_ok=True)
|
|
59
|
-
np.savez(FOLDER_OUT + 'DFT/dft_fitted', Freqs=Sorted_Freqs, Phis=Phi_F, Sigmas=SIGMA_F)
|
|
60
|
-
|
|
61
|
-
return Sorted_Freqs, Phi_F, SIGMA_F
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from tqdm import tqdm
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def dft_fit(N_T, F_S, D, FOLDER_OUT, SAVE_DFT=False):
|
|
8
|
+
"""
|
|
9
|
+
This function computes the DFT form the dataset D.
|
|
10
|
+
Currently, this does not handle the memory saving feature.
|
|
11
|
+
|
|
12
|
+
:param N_T: int.
|
|
13
|
+
number of snapshots
|
|
14
|
+
:param F_S:
|
|
15
|
+
Sampling frequency (in Hz)
|
|
16
|
+
:param D:
|
|
17
|
+
Snapshot matrix
|
|
18
|
+
:param FOLDER_OUT:
|
|
19
|
+
Folder in which the results are saved if SAVE_SPATIAL_POD = True
|
|
20
|
+
:param SAVE_DFT:
|
|
21
|
+
If True, results are saved on disk and released from memory
|
|
22
|
+
|
|
23
|
+
:return: Sorted_Freqs, np.array
|
|
24
|
+
Frequency bins, in Hz.
|
|
25
|
+
:return: Phi_F, np.array
|
|
26
|
+
(Complex) Spatial structures for each mode
|
|
27
|
+
:return: SIGMA_F, np.array
|
|
28
|
+
(real) amplitude of each modes
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
n_t = int(N_T)
|
|
32
|
+
Freqs = np.fft.fftfreq(n_t) * F_S # Compute the frequency bins
|
|
33
|
+
# PSI_F = np.conj(np.fft.fft(np.eye(n_t)) / np.sqrt(n_t)) # Prepare the Fourier Matrix.
|
|
34
|
+
|
|
35
|
+
# Method 1 (didactic!)
|
|
36
|
+
# PHI_SIGMA = np.dot(D, np.conj(PSI_F)) # This is PHI * SIGMA
|
|
37
|
+
|
|
38
|
+
# Method 2
|
|
39
|
+
PHI_SIGMA = (np.fft.fft(D, n_t, 1)) / (n_t ** 0.5)
|
|
40
|
+
|
|
41
|
+
PHI_F = np.zeros((D.shape[0], n_t), dtype=complex) # Initialize the PHI_F MATRIX
|
|
42
|
+
SIGMA_F = np.zeros(n_t) # Initialize the SIGMA_F MATRIX
|
|
43
|
+
|
|
44
|
+
# Now we proceed with the normalization. This is also intense so we time it
|
|
45
|
+
for r in tqdm(range(0, n_t)): # Loop over the PHI_SIGMA to normalize
|
|
46
|
+
# MEX = 'Proj ' + str(r + 1) + ' /' + str(n_t)
|
|
47
|
+
# print(MEX)
|
|
48
|
+
SIGMA_F[r] = abs(np.vdot(PHI_SIGMA[:, r], PHI_SIGMA[:, r])) ** 0.5
|
|
49
|
+
PHI_F[:, r] = PHI_SIGMA[:, r] / SIGMA_F[r]
|
|
50
|
+
|
|
51
|
+
Indices = np.flipud(np.argsort(SIGMA_F)) # find indices for sorting in decreasing order
|
|
52
|
+
Sorted_Sigmas = SIGMA_F[Indices] # Sort all the sigmas
|
|
53
|
+
Sorted_Freqs = Freqs[Indices] # Sort all the frequencies accordingly.
|
|
54
|
+
Phi_F = PHI_F[:, Indices] # Sorted Spatial Structures Matrix
|
|
55
|
+
SIGMA_F = Sorted_Sigmas # Sorted Amplitude Matrix (vector)
|
|
56
|
+
|
|
57
|
+
if SAVE_DFT:
|
|
58
|
+
os.makedirs(FOLDER_OUT + 'DFT', exist_ok=True)
|
|
59
|
+
np.savez(FOLDER_OUT + 'DFT/dft_fitted', Freqs=Sorted_Freqs, Phis=Phi_F, Sigmas=SIGMA_F)
|
|
60
|
+
|
|
61
|
+
return Sorted_Freqs, Phi_F, SIGMA_F
|
modulo_vki/core/_dmd_s.py
CHANGED
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import numpy as np
|
|
3
|
-
from numpy import linalg as LA
|
|
4
|
-
from ..utils._utils import switch_svds
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def dmd_s(D_1, D_2, n_Modes, F_S,
|
|
8
|
-
SAVE_T_DMD=False,
|
|
9
|
-
FOLDER_OUT='./',
|
|
10
|
-
svd_solver: str = 'svd_sklearn_truncated'):
|
|
11
|
-
"""
|
|
12
|
-
This method computes the Dynamic Mode Decomposition (DMD) using hte PIP algorithm from Penland.
|
|
13
|
-
|
|
14
|
-
:param D_1: np.array
|
|
15
|
-
First portion of the data, i.e. D[:,0:n_t-1]
|
|
16
|
-
:param D_2: np.array
|
|
17
|
-
Second portion of the data, i.e. D[:,1:n_t]
|
|
18
|
-
:param Phi_P, Psi_P, Sigma_P: np.arrays
|
|
19
|
-
POD decomposition of D1
|
|
20
|
-
:param F_S: float
|
|
21
|
-
Sampling frequency in Hz
|
|
22
|
-
:param FOLDER_OUT: str
|
|
23
|
-
Folder in which the results will be saved (if SAVE_T_DMD=True)
|
|
24
|
-
:param K: np.array
|
|
25
|
-
Temporal correlation matrix
|
|
26
|
-
:param SAVE_T_POD: bool
|
|
27
|
-
A flag deciding whether the results are saved on disk or not. If the MEMORY_SAVING feature is active, it is switched True by default.
|
|
28
|
-
:param n_Modes: int
|
|
29
|
-
number of modes that will be computed
|
|
30
|
-
:param svd_solver: str,
|
|
31
|
-
svd solver to be used
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
:return1 Phi_D: np.array.
|
|
35
|
-
DMD's complex spatial structures
|
|
36
|
-
:return2 Lambda_D: np.array.
|
|
37
|
-
DMD Eigenvalues (of the reduced propagator)
|
|
38
|
-
:return3 freqs: np.array.
|
|
39
|
-
Frequencies (in Hz, associated to the DMD modes)
|
|
40
|
-
:return4 a0s: np.array.
|
|
41
|
-
Initial Coefficients of the Modes
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
Phi_P, Psi_P, Sigma_P = switch_svds(D_1, n_Modes, svd_solver)
|
|
45
|
-
print('SVD of D1 rdy')
|
|
46
|
-
Sigma_inv = np.diag(1 / Sigma_P)
|
|
47
|
-
dt = 1 / F_S
|
|
48
|
-
# %% Step 3: Compute approximated propagator
|
|
49
|
-
P_A = LA.multi_dot([np.transpose(Phi_P), D_2, Psi_P, Sigma_inv])
|
|
50
|
-
print('reduced propagator rdy')
|
|
51
|
-
|
|
52
|
-
# %% Step 4: Compute eigenvalues of the system
|
|
53
|
-
Lambda, Q = LA.eig(P_A) # not necessarily symmetric def pos! Avoid eigsh, eigh
|
|
54
|
-
freqs = np.imag(np.log(Lambda)) / (2 * np.pi * dt)
|
|
55
|
-
print(' lambdas and freqs rdy')
|
|
56
|
-
|
|
57
|
-
# %% Step 5: Spatial structures of the DMD in the PIP style
|
|
58
|
-
Phi_D = LA.multi_dot([D_2, Psi_P, Sigma_inv, Q])
|
|
59
|
-
print('Phi_D rdy')
|
|
60
|
-
|
|
61
|
-
# %% Step 6: Compute the initial coefficients
|
|
62
|
-
# a0s=LA.lstsq(Phi_D, D_1[:,0],rcond=None)
|
|
63
|
-
a0s = LA.pinv(Phi_D).dot(D_1[:, 0])
|
|
64
|
-
print('Sigma_D rdy')
|
|
65
|
-
|
|
66
|
-
if SAVE_T_DMD:
|
|
67
|
-
os.makedirs(FOLDER_OUT + "/DMD/", exist_ok=True)
|
|
68
|
-
print("Saving DMD results")
|
|
69
|
-
np.savez(FOLDER_OUT + '/DMD/dmd_decomposition',
|
|
70
|
-
Phi_D=Phi_D, Lambda=Lambda, freqs=freqs, a0s=a0s)
|
|
71
|
-
|
|
72
|
-
return Phi_D, Lambda, freqs, a0s
|
|
1
|
+
import os
|
|
2
|
+
import numpy as np
|
|
3
|
+
from numpy import linalg as LA
|
|
4
|
+
from ..utils._utils import switch_svds
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def dmd_s(D_1, D_2, n_Modes, F_S,
|
|
8
|
+
SAVE_T_DMD=False,
|
|
9
|
+
FOLDER_OUT='./',
|
|
10
|
+
svd_solver: str = 'svd_sklearn_truncated'):
|
|
11
|
+
"""
|
|
12
|
+
This method computes the Dynamic Mode Decomposition (DMD) using hte PIP algorithm from Penland.
|
|
13
|
+
|
|
14
|
+
:param D_1: np.array
|
|
15
|
+
First portion of the data, i.e. D[:,0:n_t-1]
|
|
16
|
+
:param D_2: np.array
|
|
17
|
+
Second portion of the data, i.e. D[:,1:n_t]
|
|
18
|
+
:param Phi_P, Psi_P, Sigma_P: np.arrays
|
|
19
|
+
POD decomposition of D1
|
|
20
|
+
:param F_S: float
|
|
21
|
+
Sampling frequency in Hz
|
|
22
|
+
:param FOLDER_OUT: str
|
|
23
|
+
Folder in which the results will be saved (if SAVE_T_DMD=True)
|
|
24
|
+
:param K: np.array
|
|
25
|
+
Temporal correlation matrix
|
|
26
|
+
:param SAVE_T_POD: bool
|
|
27
|
+
A flag deciding whether the results are saved on disk or not. If the MEMORY_SAVING feature is active, it is switched True by default.
|
|
28
|
+
:param n_Modes: int
|
|
29
|
+
number of modes that will be computed
|
|
30
|
+
:param svd_solver: str,
|
|
31
|
+
svd solver to be used
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
:return1 Phi_D: np.array.
|
|
35
|
+
DMD's complex spatial structures
|
|
36
|
+
:return2 Lambda_D: np.array.
|
|
37
|
+
DMD Eigenvalues (of the reduced propagator)
|
|
38
|
+
:return3 freqs: np.array.
|
|
39
|
+
Frequencies (in Hz, associated to the DMD modes)
|
|
40
|
+
:return4 a0s: np.array.
|
|
41
|
+
Initial Coefficients of the Modes
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
Phi_P, Psi_P, Sigma_P = switch_svds(D_1, n_Modes, svd_solver)
|
|
45
|
+
print('SVD of D1 rdy')
|
|
46
|
+
Sigma_inv = np.diag(1 / Sigma_P)
|
|
47
|
+
dt = 1 / F_S
|
|
48
|
+
# %% Step 3: Compute approximated propagator
|
|
49
|
+
P_A = LA.multi_dot([np.transpose(Phi_P), D_2, Psi_P, Sigma_inv])
|
|
50
|
+
print('reduced propagator rdy')
|
|
51
|
+
|
|
52
|
+
# %% Step 4: Compute eigenvalues of the system
|
|
53
|
+
Lambda, Q = LA.eig(P_A) # not necessarily symmetric def pos! Avoid eigsh, eigh
|
|
54
|
+
freqs = np.imag(np.log(Lambda)) / (2 * np.pi * dt)
|
|
55
|
+
print(' lambdas and freqs rdy')
|
|
56
|
+
|
|
57
|
+
# %% Step 5: Spatial structures of the DMD in the PIP style
|
|
58
|
+
Phi_D = LA.multi_dot([D_2, Psi_P, Sigma_inv, Q])
|
|
59
|
+
print('Phi_D rdy')
|
|
60
|
+
|
|
61
|
+
# %% Step 6: Compute the initial coefficients
|
|
62
|
+
# a0s=LA.lstsq(Phi_D, D_1[:,0],rcond=None)
|
|
63
|
+
a0s = LA.pinv(Phi_D).dot(D_1[:, 0])
|
|
64
|
+
print('Sigma_D rdy')
|
|
65
|
+
|
|
66
|
+
if SAVE_T_DMD:
|
|
67
|
+
os.makedirs(FOLDER_OUT + "/DMD/", exist_ok=True)
|
|
68
|
+
print("Saving DMD results")
|
|
69
|
+
np.savez(FOLDER_OUT + '/DMD/dmd_decomposition',
|
|
70
|
+
Phi_D=Phi_D, Lambda=Lambda, freqs=freqs, a0s=a0s)
|
|
71
|
+
|
|
72
|
+
return Phi_D, Lambda, freqs, a0s
|
modulo_vki/core/_k_matrix.py
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from tqdm import tqdm
|
|
3
|
-
import numpy as np
|
|
4
|
-
import math
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def CorrelationMatrix(N_T, N_PARTITIONS=1, MEMORY_SAVING=False, FOLDER_OUT='./', SAVE_K=False, D=None,weights = np.array([])):
|
|
8
|
-
"""
|
|
9
|
-
This method computes the temporal correlation matrix, given a data matrix as input. It's possible to use memory saving
|
|
10
|
-
then splitting the computing in different tranches if computationally heavy. If D has been computed using MODULO
|
|
11
|
-
then the dimension dim_col and N_PARTITIONS is automatically loaded
|
|
12
|
-
|
|
13
|
-
:param N_T: int. Number of temporal snapshots
|
|
14
|
-
:param D: np.array. Data matrix
|
|
15
|
-
:param SAVE_K: bool. If SAVE_K=True, the matrix K is saved on disk. If the MEMORY_SAVING feature is active, this is done by default.
|
|
16
|
-
:param MEMORY_SAVING: bool. If MEMORY_SAVING = True, the computation of the correlation matrix is done by steps. It requires the data matrix to be partitioned, following algorithm in MODULO._data_processing.
|
|
17
|
-
:param FOLDER_OUT: str. Folder in which the temporal correlation matrix will be stored
|
|
18
|
-
:param N_PARTITIONS: int. Number of partitions to be read in computing the correlation matrix. If _data_processing is used to partition the data matrix, this is inherited from the main class
|
|
19
|
-
:param weights: weight vector [w_i,....,w_{N_s}] where w_i = area_cell_i/area_grid. Only needed if grid is non-uniform & MEMORY_SAVING== True
|
|
20
|
-
:return: K (: np.array) if the memory saving is not active. None type otherwise.
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
if not MEMORY_SAVING:
|
|
24
|
-
print("\n Computing Temporal correlation matrix K ...")
|
|
25
|
-
K = np.dot(D.T, D)
|
|
26
|
-
print("\n Done.")
|
|
27
|
-
|
|
28
|
-
else:
|
|
29
|
-
SAVE_K = True
|
|
30
|
-
print("\n Using Memory Saving feature...")
|
|
31
|
-
K = np.zeros((N_T, N_T))
|
|
32
|
-
dim_col = math.floor(N_T / N_PARTITIONS)
|
|
33
|
-
|
|
34
|
-
if N_T % N_PARTITIONS != 0:
|
|
35
|
-
tot_blocks_col = N_PARTITIONS + 1
|
|
36
|
-
else:
|
|
37
|
-
tot_blocks_col = N_PARTITIONS
|
|
38
|
-
|
|
39
|
-
for k in tqdm(range(tot_blocks_col)):
|
|
40
|
-
|
|
41
|
-
di = np.load(FOLDER_OUT + f"/data_partitions/di_{k + 1}.npz")['di']
|
|
42
|
-
if weights.size != 0:
|
|
43
|
-
di = np.transpose(np.transpose(di) * np.sqrt(weights))
|
|
44
|
-
|
|
45
|
-
ind_start = k * dim_col
|
|
46
|
-
ind_end = ind_start + dim_col
|
|
47
|
-
|
|
48
|
-
if (k == tot_blocks_col - 1) and (N_T - dim_col * N_PARTITIONS > 0):
|
|
49
|
-
dim_col = N_T - dim_col * N_PARTITIONS
|
|
50
|
-
ind_end = ind_start + dim_col
|
|
51
|
-
|
|
52
|
-
K[ind_start:ind_end, ind_start:ind_end] = np.dot(di.transpose(), di)
|
|
53
|
-
|
|
54
|
-
block = k + 2
|
|
55
|
-
|
|
56
|
-
while block <= tot_blocks_col:
|
|
57
|
-
dj = np.load(FOLDER_OUT + f"/data_partitions/di_{block}.npz")['di']
|
|
58
|
-
if weights.size != 0:
|
|
59
|
-
dj = np.transpose(np.transpose(dj) * np.sqrt(weights))
|
|
60
|
-
|
|
61
|
-
ind_start_out = (block - 1) * dim_col
|
|
62
|
-
ind_end_out = ind_start_out + dim_col
|
|
63
|
-
|
|
64
|
-
if (block == tot_blocks_col) and (N_T - dim_col * N_PARTITIONS > 0):
|
|
65
|
-
dim_col = N_T - dim_col * N_PARTITIONS
|
|
66
|
-
ind_end_out = ind_start_out + dim_col
|
|
67
|
-
dj = dj[:, :dim_col]
|
|
68
|
-
|
|
69
|
-
K[ind_start:ind_end, ind_start_out:ind_end_out] = np.dot(di.T, dj)
|
|
70
|
-
|
|
71
|
-
K[ind_start_out:ind_end_out, ind_start:ind_end] = K[ind_start:ind_end, ind_start_out:ind_end_out].T
|
|
72
|
-
|
|
73
|
-
block += 1
|
|
74
|
-
|
|
75
|
-
dim_col = math.floor(N_T / N_PARTITIONS)
|
|
76
|
-
|
|
77
|
-
if SAVE_K:
|
|
78
|
-
os.makedirs(FOLDER_OUT + '/correlation_matrix', exist_ok=True)
|
|
79
|
-
np.savez(FOLDER_OUT + "/correlation_matrix/k_matrix", K=K)
|
|
80
|
-
|
|
81
|
-
return K if not MEMORY_SAVING else None
|
|
1
|
+
import os
|
|
2
|
+
from tqdm import tqdm
|
|
3
|
+
import numpy as np
|
|
4
|
+
import math
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def CorrelationMatrix(N_T, N_PARTITIONS=1, MEMORY_SAVING=False, FOLDER_OUT='./', SAVE_K=False, D=None,weights = np.array([])):
|
|
8
|
+
"""
|
|
9
|
+
This method computes the temporal correlation matrix, given a data matrix as input. It's possible to use memory saving
|
|
10
|
+
then splitting the computing in different tranches if computationally heavy. If D has been computed using MODULO
|
|
11
|
+
then the dimension dim_col and N_PARTITIONS is automatically loaded
|
|
12
|
+
|
|
13
|
+
:param N_T: int. Number of temporal snapshots
|
|
14
|
+
:param D: np.array. Data matrix
|
|
15
|
+
:param SAVE_K: bool. If SAVE_K=True, the matrix K is saved on disk. If the MEMORY_SAVING feature is active, this is done by default.
|
|
16
|
+
:param MEMORY_SAVING: bool. If MEMORY_SAVING = True, the computation of the correlation matrix is done by steps. It requires the data matrix to be partitioned, following algorithm in MODULO._data_processing.
|
|
17
|
+
:param FOLDER_OUT: str. Folder in which the temporal correlation matrix will be stored
|
|
18
|
+
:param N_PARTITIONS: int. Number of partitions to be read in computing the correlation matrix. If _data_processing is used to partition the data matrix, this is inherited from the main class
|
|
19
|
+
:param weights: weight vector [w_i,....,w_{N_s}] where w_i = area_cell_i/area_grid. Only needed if grid is non-uniform & MEMORY_SAVING== True
|
|
20
|
+
:return: K (: np.array) if the memory saving is not active. None type otherwise.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
if not MEMORY_SAVING:
|
|
24
|
+
print("\n Computing Temporal correlation matrix K ...")
|
|
25
|
+
K = np.dot(D.T, D)
|
|
26
|
+
print("\n Done.")
|
|
27
|
+
|
|
28
|
+
else:
|
|
29
|
+
SAVE_K = True
|
|
30
|
+
print("\n Using Memory Saving feature...")
|
|
31
|
+
K = np.zeros((N_T, N_T))
|
|
32
|
+
dim_col = math.floor(N_T / N_PARTITIONS)
|
|
33
|
+
|
|
34
|
+
if N_T % N_PARTITIONS != 0:
|
|
35
|
+
tot_blocks_col = N_PARTITIONS + 1
|
|
36
|
+
else:
|
|
37
|
+
tot_blocks_col = N_PARTITIONS
|
|
38
|
+
|
|
39
|
+
for k in tqdm(range(tot_blocks_col)):
|
|
40
|
+
|
|
41
|
+
di = np.load(FOLDER_OUT + f"/data_partitions/di_{k + 1}.npz")['di']
|
|
42
|
+
if weights.size != 0:
|
|
43
|
+
di = np.transpose(np.transpose(di) * np.sqrt(weights))
|
|
44
|
+
|
|
45
|
+
ind_start = k * dim_col
|
|
46
|
+
ind_end = ind_start + dim_col
|
|
47
|
+
|
|
48
|
+
if (k == tot_blocks_col - 1) and (N_T - dim_col * N_PARTITIONS > 0):
|
|
49
|
+
dim_col = N_T - dim_col * N_PARTITIONS
|
|
50
|
+
ind_end = ind_start + dim_col
|
|
51
|
+
|
|
52
|
+
K[ind_start:ind_end, ind_start:ind_end] = np.dot(di.transpose(), di)
|
|
53
|
+
|
|
54
|
+
block = k + 2
|
|
55
|
+
|
|
56
|
+
while block <= tot_blocks_col:
|
|
57
|
+
dj = np.load(FOLDER_OUT + f"/data_partitions/di_{block}.npz")['di']
|
|
58
|
+
if weights.size != 0:
|
|
59
|
+
dj = np.transpose(np.transpose(dj) * np.sqrt(weights))
|
|
60
|
+
|
|
61
|
+
ind_start_out = (block - 1) * dim_col
|
|
62
|
+
ind_end_out = ind_start_out + dim_col
|
|
63
|
+
|
|
64
|
+
if (block == tot_blocks_col) and (N_T - dim_col * N_PARTITIONS > 0):
|
|
65
|
+
dim_col = N_T - dim_col * N_PARTITIONS
|
|
66
|
+
ind_end_out = ind_start_out + dim_col
|
|
67
|
+
dj = dj[:, :dim_col]
|
|
68
|
+
|
|
69
|
+
K[ind_start:ind_end, ind_start_out:ind_end_out] = np.dot(di.T, dj)
|
|
70
|
+
|
|
71
|
+
K[ind_start_out:ind_end_out, ind_start:ind_end] = K[ind_start:ind_end, ind_start_out:ind_end_out].T
|
|
72
|
+
|
|
73
|
+
block += 1
|
|
74
|
+
|
|
75
|
+
dim_col = math.floor(N_T / N_PARTITIONS)
|
|
76
|
+
|
|
77
|
+
if SAVE_K:
|
|
78
|
+
os.makedirs(FOLDER_OUT + '/correlation_matrix', exist_ok=True)
|
|
79
|
+
np.savez(FOLDER_OUT + "/correlation_matrix/k_matrix", K=K)
|
|
80
|
+
|
|
81
|
+
return K if not MEMORY_SAVING else None
|