From 4f1347ff9e04b8ed7b9e596c732481d511bff2a3 Mon Sep 17 00:00:00 2001 From: Krzysztof Suwada Date: Tue, 8 Oct 2024 14:10:28 +0200 Subject: [PATCH 1/4] Refactor --- test.py | 135 -------------------------------------------------------- voap.py | 112 ---------------------------------------------- 2 files changed, 247 deletions(-) delete mode 100644 test.py delete mode 100644 voap.py diff --git a/test.py b/test.py deleted file mode 100644 index 147a61a..0000000 --- a/test.py +++ /dev/null @@ -1,135 +0,0 @@ -import numpy as np -import voap - -if __name__ == "__main__": - true_copula = np.array( - [ - -0.1505847, - -0.2742042, - -0.3742406, - -0.4714045, - -0.5741693, - 0.69006556, - 0.5741693, - 0.4714045, - 0.3742406, - 0.2742042, - 0.1505847, - -0.2742042, - -0.4993070, - -0.6814663, - 1.1200012, - 0.8286734, - 1.25656172, - 1.0455226, - 0.8583951, - 0.6814663, - 0.4993070, - 0.2742042, - -0.3742406, - -0.6814663, - -0.9300817, - 0.4485395, - 0.1078143, - 0.20579830, - 1.4269545, - 1.1715584, - 0.9300817, - 0.6814663, - 0.3742406, - -0.4714045, - -0.8583951, - 0.4485395, - 1.4395893, - 0.9643376, - 0.80237742, - 1.7974341, - 1.4757296, - 1.1715584, - 0.8583951, - 0.4714045, - -0.5741693, - -1.0455226, - 0.1078143, - 0.9643376, - 0.4270426, - 0.05847053, - 0.8811133, - 0.4165482, - -0.1078143, - 1.0455226, - 0.5741693, - 0.6900656, - -0.5863955, - 0.2057983, - 0.8023774, - 1.3448223, - 0.63245553, - 1.3448223, - 0.8023774, - 0.2057983, - 1.2565617, - 0.6900656, - 0.5741693, - 1.0455226, - 1.4269545, - 1.7974341, - 2.1892691, - 1.34482230, - 1.7351985, - 0.9643376, - 0.1078143, - 0.8286734, - -0.5741693, - 0.4714045, - 0.8583951, - 1.1715584, - 1.4757296, - 1.7974341, - 0.80237742, - 0.9643376, - 1.4395893, - 0.4485395, - 1.1200012, - -0.4714045, - 0.3742406, - 0.6814663, - 0.9300817, - 1.1715584, - 1.4269545, - 1.71498585, - 1.6425832, - 2.0686374, - 0.8705564, - 1.5173982, - -0.3742406, - 0.2742042, - 0.4993070, - 0.6814663, - 0.8583951, - 1.0455226, - 1.25656172, - 0.8286734, - 1.1200012, - 1.5173982, - 2.1858551, - -0.2742042, - 0.1505847, - 0.2742042, - 0.3742406, - 0.4714045, - 0.5741693, - 0.69006556, - -0.5741693, - -0.4714045, - -0.3742406, - -0.2742042, - -0.1505847, - ] - ) - true_copula = true_copula.reshape((11, 11)) - - r = np.array(range(1, 11)) - s = np.array([3, 6, 2, 9, 4, 1, 7, 5, 8, 10]) - test_copula = voap.calculate_copula_grid(r, s) - print(np.sum(true_copula - test_copula)) diff --git a/voap.py b/voap.py deleted file mode 100644 index affc173..0000000 --- a/voap.py +++ /dev/null @@ -1,112 +0,0 @@ -import numpy as np -import numba -# from tqdm.auto import tqdm - - -@numba.njit(parallel=True) -def Q_function(Q_grid, C_grid): - n = len(C_grid) - 1 - z = [] - - for i in numba.prange(len(Q_grid)): - row_idx = int(np.ceil(Q_grid[i, 0] * (n + 1)) - 1) - col_idx = int(np.ceil(Q_grid[i, 1] * (n + 1)) - 1) - if row_idx > n: - row_idx = n - if col_idx > n: - col_idx = n - z.append(C_grid[row_idx, col_idx]) - - return {"x": Q_grid[:, 0], "y": Q_grid[:, 1], "z": np.array(z)} - - -def create_Q_grid(n=10): - u = np.linspace(0.5 / (n + 1), (0.5 + n) / (n + 1), n + 1) - grid = np.stack(np.meshgrid(u, u)).T.reshape(-1, 2) - - return grid - -@numba.njit(parallel=True) -def calculate_copula_part(t, c): - n = len(t) - n_inv = 1 / n # n**-1 ## numba doesn't get n**-1 xD - c = np.zeros(c.shape) - for i in numba.prange(1, int(n / 2) + 2): - for j in numba.prange(int(n / 2) + 2): - # c[i, j] = c[i - 1, j] + (j >= t[i - 1]) * n_inv - c[i, j] = c[0, j] + n_inv * np.sum(j >= t[:i]) - return c - -@numba.njit -def wn(n, c, i, j): - u = (i + 0.5) / (n + 1) - v = (j + 0.5) / (n + 1) - return n**0.5 * (c - u * v) * (u * v * (1 - u) * (1 - v)) ** -0.5 - -@numba.njit -def fill_matrix(n, ks, c, x_prim, y_prim): - sign = (-1) ** (x_prim + y_prim) - - for i in range(int(np.floor((n + 1) / 2)) + 1): - for j in range(int(np.floor((n + 1) / 2)) + 1): - x = n - i if x_prim else i - y = n - j if y_prim else j - ks[x, y] = sign * wn(n, c[i, j], i, j) - return ks - -@numba.njit -def arma_copula(rx, ry): - n = len(rx) - - ctab = np.zeros((n + 1, n + 1)) - ctabs22 = np.zeros((n + 1, n + 1)) - ctabs12 = np.zeros((n + 1, n + 1)) - ctabs21 = np.zeros((n + 1, n + 1)) - - rsx = np.zeros(n) - rsy = np.zeros(n) - - ks = np.zeros((n + 1, n + 1)) - - rsx = len(rx) + 1 - rx - rsy = len(ry) + 1 - ry - - t = ry[np.argsort(rx)] - ts22 = rsy[np.argsort(rsx)] - ts12 = rsy[np.argsort(rx)] - ts21 = ry[np.argsort(rsx)] - - ctab = calculate_copula_part(t, ctab) - ctabs22 = calculate_copula_part(ts22, ctabs22) - ctabs12 = calculate_copula_part(ts12, ctabs12) - ctabs21 = calculate_copula_part(ts21, ctabs21) - - ks = fill_matrix(n, ks, ctab, False, False) - ks = fill_matrix(n, ks, ctabs22, True, True) - ks = fill_matrix(n, ks, ctabs12, False, True) - ks = fill_matrix(n, ks, ctabs21, True, False) - - return ks - -@numba.njit -def calculate_copula_grid(x, y): - return arma_copula( - np.argsort(np.argsort(x)) + 1, np.argsort(np.argsort(y)) + 1 - ) - -# @numba.njit(parallel=True) -def calculate_copula_mc_grid(x, y, mc=100, seed=0): - rng = np.random.RandomState(seed) - k = len(x) - g = np.zeros((k + 1, len(y) + 1)) - - for i in range(mc): - indx = rng.choice(k, size=k) - mat = calculate_copula_grid(x[indx], y[indx]) - g += mat / mc - - return g - - -# def create_Q_plot(x, y): -# return Q_function(create_Q_grid(), calculate_copula_mc_grid(x, y)) From 54b89fdc96080b3a21fc249fafc45a02b6336ab0 Mon Sep 17 00:00:00 2001 From: Krzysztof Suwada Date: Tue, 22 Oct 2024 10:12:22 +0200 Subject: [PATCH 2/4] Refactor --- setup.py | 25 +++++++ tests/test_voa.py | 30 ++++++++ voa/__init__.py | 1 + voa/copula.py | 176 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 232 insertions(+) create mode 100644 setup.py create mode 100644 tests/test_voa.py create mode 100644 voa/__init__.py create mode 100644 voa/copula.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..fe773ca --- /dev/null +++ b/setup.py @@ -0,0 +1,25 @@ +from setuptools import setup, find_packages + +setup( + name="VoA", + version="0.0.1", + author="Mateusz Przyborowski, Krzysztof Suwada", + description="Tools proposed in the paper 'Validation of Association'", + long_description=open("README.md").read(), + long_description_content_type="text/markdown", + url="https://arxiv.org/pdf/1904.06519", + packages=find_packages(), + install_requires=[ + "numpy", + "numba", + "plotly", + # Add any other dependencies here + ], + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + ], + python_requires='>=3.8', +) + diff --git a/tests/test_voa.py b/tests/test_voa.py new file mode 100644 index 0000000..b69f0d9 --- /dev/null +++ b/tests/test_voa.py @@ -0,0 +1,30 @@ +import numpy as np +import voap + +def test_copula(): + true_copula = np.array( + [ + -0.1505847, -0.2742042, -0.3742406, -0.4714045, -0.5741693, 0.69006556, 0.5741693, 0.4714045, 0.3742406, + 0.2742042, 0.1505847, -0.2742042, -0.4993070, -0.6814663, 1.1200012, 0.8286734, 1.25656172, 1.0455226, + 0.8583951, 0.6814663, 0.4993070, 0.2742042, -0.3742406, -0.6814663, -0.9300817, 0.4485395, 0.1078143, + 0.20579830, 1.4269545, 1.1715584, 0.9300817, 0.6814663, 0.3742406, -0.4714045, -0.8583951, 0.4485395, + 1.4395893, 0.9643376, 0.80237742, 1.7974341, 1.4757296, 1.1715584, 0.8583951, 0.4714045, -0.5741693, + -1.0455226, 0.1078143, 0.9643376, 0.4270426, 0.05847053, 0.8811133, 0.4165482, -0.1078143, 1.0455226, + 0.5741693, 0.6900656, -0.5863955, 0.2057983, 0.8023774, 1.3448223, 0.63245553, 1.3448223, 0.8023774, + 0.2057983, 1.2565617, 0.6900656, 0.5741693, 1.0455226, 1.4269545, 1.7974341, 2.1892691, 1.34482230, + 1.7351985, 0.9643376, 0.1078143, 0.8286734, -0.5741693, 0.4714045, 0.8583951, 1.1715584, 1.4757296, + 1.7974341, 0.80237742, 0.9643376, 1.4395893, 0.4485395, 1.1200012, -0.4714045, 0.3742406, 0.6814663, + 0.9300817, 1.1715584, 1.4269545, 1.71498585, 1.6425832, 2.0686374, 0.8705564, 1.5173982, -0.3742406, + 0.2742042, 0.4993070, 0.6814663, 0.8583951, 1.0455226, 1.25656172, 0.8286734, 1.1200012, 1.5173982, + 2.1858551, -0.2742042, 0.1505847, 0.2742042, 0.3742406, 0.4714045, 0.5741693, 0.69006556, -0.5741693, + -0.4714045, -0.3742406, -0.2742042, -0.1505847, + ] + ) + true_copula = true_copula.reshape((11, 11)) + + r = np.array(range(1, 11)) + s = np.array([3, 6, 2, 9, 4, 1, 7, 5, 8, 10]) + test_copula = voap.calculate_copula_grid(r, s) + assert np.allclose(true_copula, test_copula, atol=1e-6), "Test failed: Copula grid is incorrect" + + diff --git a/voa/__init__.py b/voa/__init__.py new file mode 100644 index 0000000..086daf0 --- /dev/null +++ b/voa/__init__.py @@ -0,0 +1 @@ +from .copula import calculate_copula_grid, create_Q_grid, calculate_copula_mc_grid, create_Q_plot diff --git a/voa/copula.py b/voa/copula.py new file mode 100644 index 0000000..35a300b --- /dev/null +++ b/voa/copula.py @@ -0,0 +1,176 @@ +import numpy as np +import numba +import time +import plotly.graph_objs as go +import plotly.io as pio + + +@numba.njit(parallel=True) +def Q_function(Q_grid, C_grid): + n = len(C_grid) - 1 + z = [] + + for i in numba.prange(len(Q_grid)): + row_idx = int(np.ceil(Q_grid[i, 0] * (n + 1)) - 1) + col_idx = int(np.ceil(Q_grid[i, 1] * (n + 1)) - 1) + if row_idx > n: + row_idx = n + if col_idx > n: + col_idx = n + z.append(C_grid[row_idx, col_idx]) + + return {"x": Q_grid[:, 0], "y": Q_grid[:, 1], "z": np.array(z)} + + +def create_Q_grid(n=10): + u = np.linspace(0.5 / (n + 1), (0.5 + n) / (n + 1), n + 1) + grid = np.stack(np.meshgrid(u, u)).T.reshape(-1, 2) + + return grid + + +@numba.njit(parallel=True) +def calculate_copula_part(t, c): + n = len(t) + n_inv = 1.0 / float(n) + c = np.zeros(c.shape) + for i in numba.prange(1, int(n / 2) + 2): + for j in numba.prange(int(n / 2) + 2): + c[i, j] = c[0, j] + n_inv * np.sum(j >= t[:i]) + return c + + +@numba.njit +def wn(n, c, i, j): + u = (i + 0.5) / (n + 1) + v = (j + 0.5) / (n + 1) + return n**0.5 * (c - u * v) * (u * v * (1 - u) * (1 - v)) ** -0.5 + + +@numba.njit +def fill_matrix(n, ks, c, x_prim, y_prim): + sign = (-1) ** (x_prim + y_prim) + + for i in range(int(np.floor((n + 1) / 2)) + 1): + for j in range(int(np.floor((n + 1) / 2)) + 1): + x = n - i if x_prim else i + y = n - j if y_prim else j + ks[x, y] = sign * wn(n, c[i, j], i, j) + return ks + + +@numba.njit +def arma_copula(rx, ry): + n = len(rx) + + ctab = np.zeros((n + 1, n + 1)) + ctabs22 = np.zeros((n + 1, n + 1)) + ctabs12 = np.zeros((n + 1, n + 1)) + ctabs21 = np.zeros((n + 1, n + 1)) + + ks = np.zeros((n + 1, n + 1)) + + rsx = len(rx) + 1 - rx + rsy = len(ry) + 1 - ry + + t = ry[np.argsort(rx)] + ts22 = rsy[np.argsort(rsx)] + ts12 = rsy[np.argsort(rx)] + ts21 = ry[np.argsort(rsx)] + + ctab = calculate_copula_part(t, ctab) + ctabs22 = calculate_copula_part(ts22, ctabs22) + ctabs12 = calculate_copula_part(ts12, ctabs12) + ctabs21 = calculate_copula_part(ts21, ctabs21) + + ks = fill_matrix(n, ks, ctab, False, False) + ks = fill_matrix(n, ks, ctabs22, True, True) + ks = fill_matrix(n, ks, ctabs12, False, True) + ks = fill_matrix(n, ks, ctabs21, True, False) + + return ks + + +@numba.njit +def calculate_copula_grid(x, y): + return arma_copula( + np.argsort(np.argsort(x)) + 1, np.argsort(np.argsort(y)) + 1 + ) + + +def calculate_copula_mc_grid(x, y, mc=100, seed=0): + rng = np.random.RandomState(seed) + k = len(x) + g = np.zeros((k + 1, len(y) + 1)) + + for i in range(mc): + indx = rng.choice(k, size=k) + mat = calculate_copula_grid(x[indx], y[indx]) + g += mat / mc + + return g + +def create_Q_plot(X, Y, k_plot_grid=100, MC=100, display=True): + """ + Plot Q function based on Monte Carlo estimation. + + Parameters: + - X: List or numpy array, first random variable e.g. [1.1, 2.2, 1.73]. + - Y: List or numpy array, second random variable e.g. [3.1, 1.2, 1.93]. + - k_plot_grid: Number of grid points for the plot, default is 100. + - MC: Number of Monte Carlo replications, default is 100. + - display: Boolean, if true the plot will be displayed, default is True. + + Returns: + - A dictionary containing Q plot data, copula grid, Q grid, and plot points. + """ + if len(X) != len(Y): + raise ValueError("Size of X and Y do not match") + + # Start the timer + start_time = time.time() + + # Calculate the copula grid using Monte Carlo estimation + C_grid = calculate_copula_mc_grid(np.array(X), np.array(Y), MC) + + # Create the Q grid + Q_grid = create_Q_grid(k_plot_grid) + + # Calculate the Q function on the grid + plot_points = Q_function(Q_grid, C_grid) + + # Stop the timer + time_taken = time.time() - start_time + print(f"Time taken for calculations: {time_taken:.2f} seconds") + + # Create a contour plot using Plotly + contour_plot = go.Contour( + z=plot_points['z'], + x=plot_points['x'], + y=plot_points['y'], + contours=dict( + coloring='heatmap' + ) + ) + + layout = go.Layout( + title='Q Function Contour Plot', + xaxis_title='X', + yaxis_title='Y', + height=600, + width=600 + ) + + fig = go.Figure(data=[contour_plot], layout=layout) + + # Display the plot if the display flag is True + if display: + fig.show() + + # Return the plot and data as a dictionary + return { + 'Q_plot': fig, + 'C_grid': C_grid, + 'Q_grid': Q_grid, + 'plot_points': plot_points + } From a2d1cd3eab7da0ea7282968c01226181d93e8d82 Mon Sep 17 00:00:00 2001 From: Krzysztof Suwada Date: Thu, 24 Oct 2024 09:37:41 +0200 Subject: [PATCH 3/4] PR changes --- setup.py | 8 ++++---- tests/test_voa.py | 37 ++++++++++++++++++++++--------------- voa/copula.py | 33 ++++++++++----------------------- 3 files changed, 36 insertions(+), 42 deletions(-) diff --git a/setup.py b/setup.py index fe773ca..6105cb0 100644 --- a/setup.py +++ b/setup.py @@ -7,12 +7,12 @@ description="Tools proposed in the paper 'Validation of Association'", long_description=open("README.md").read(), long_description_content_type="text/markdown", - url="https://arxiv.org/pdf/1904.06519", + url="https://github.com/nexocodecom/VoAPython", packages=find_packages(), install_requires=[ - "numpy", - "numba", - "plotly", + "numpy >= 1.23.5", + "numba >= 0.58.1", + "plotly >= 5.18.0", # Add any other dependencies here ], classifiers=[ diff --git a/tests/test_voa.py b/tests/test_voa.py index b69f0d9..3884ed6 100644 --- a/tests/test_voa.py +++ b/tests/test_voa.py @@ -4,23 +4,30 @@ def test_copula(): true_copula = np.array( [ - -0.1505847, -0.2742042, -0.3742406, -0.4714045, -0.5741693, 0.69006556, 0.5741693, 0.4714045, 0.3742406, - 0.2742042, 0.1505847, -0.2742042, -0.4993070, -0.6814663, 1.1200012, 0.8286734, 1.25656172, 1.0455226, - 0.8583951, 0.6814663, 0.4993070, 0.2742042, -0.3742406, -0.6814663, -0.9300817, 0.4485395, 0.1078143, - 0.20579830, 1.4269545, 1.1715584, 0.9300817, 0.6814663, 0.3742406, -0.4714045, -0.8583951, 0.4485395, - 1.4395893, 0.9643376, 0.80237742, 1.7974341, 1.4757296, 1.1715584, 0.8583951, 0.4714045, -0.5741693, - -1.0455226, 0.1078143, 0.9643376, 0.4270426, 0.05847053, 0.8811133, 0.4165482, -0.1078143, 1.0455226, - 0.5741693, 0.6900656, -0.5863955, 0.2057983, 0.8023774, 1.3448223, 0.63245553, 1.3448223, 0.8023774, - 0.2057983, 1.2565617, 0.6900656, 0.5741693, 1.0455226, 1.4269545, 1.7974341, 2.1892691, 1.34482230, - 1.7351985, 0.9643376, 0.1078143, 0.8286734, -0.5741693, 0.4714045, 0.8583951, 1.1715584, 1.4757296, - 1.7974341, 0.80237742, 0.9643376, 1.4395893, 0.4485395, 1.1200012, -0.4714045, 0.3742406, 0.6814663, - 0.9300817, 1.1715584, 1.4269545, 1.71498585, 1.6425832, 2.0686374, 0.8705564, 1.5173982, -0.3742406, - 0.2742042, 0.4993070, 0.6814663, 0.8583951, 1.0455226, 1.25656172, 0.8286734, 1.1200012, 1.5173982, - 2.1858551, -0.2742042, 0.1505847, 0.2742042, 0.3742406, 0.4714045, 0.5741693, 0.69006556, -0.5741693, - -0.4714045, -0.3742406, -0.2742042, -0.1505847, + [-0.1505847, -0.2742042, -0.3742406, -0.4714045, -0.5741693, 0.69006556, 0.5741693, 0.4714045, 0.3742406, + 0.2742042, 0.1505847], + [-0.2742042, -0.4993070, -0.6814663, 1.1200012, 0.8286734, 1.25656172, 1.0455226, 0.8583951, 0.6814663, + 0.4993070, 0.2742042], + [-0.3742406, -0.6814663, -0.9300817, 0.4485395, 0.1078143, 0.20579830, 1.4269545, 1.1715584, 0.9300817, + 0.6814663, 0.3742406], + [-0.4714045, -0.8583951, 0.4485395, 1.4395893, 0.9643376, 0.80237742, 1.7974341, 1.4757296, 1.1715584, + 0.8583951, 0.4714045], + [-0.5741693, -1.0455226, 0.1078143, 0.9643376, 0.4270426, 0.05847053, 0.8811133, 0.4165482, -0.1078143, + 1.0455226, 0.5741693], + [0.6900656, -0.5863955, 0.2057983, 0.8023774, 1.3448223, 0.63245553, 1.3448223, 0.8023774, 0.2057983, + 1.2565617, 0.6900656], + [0.5741693, 1.0455226, 1.4269545, 1.7974341, 2.1892691, 1.34482230, 1.7351985, 0.9643376, 0.1078143, + 0.8286734, -0.5741693], + [0.4714045, 0.8583951, 1.1715584, 1.4757296, 1.7974341, 0.80237742, 0.9643376, 1.4395893, 0.4485395, + 1.1200012, -0.4714045], + [0.3742406, 0.6814663, 0.9300817, 1.1715584, 1.4269545, 1.71498585, 1.6425832, 2.0686374, 0.8705564, + 1.5173982, -0.3742406], + [0.2742042, 0.4993070, 0.6814663, 0.8583951, 1.0455226, 1.25656172, 0.8286734, 1.1200012, 1.5173982, + 2.1858551, -0.2742042], + [0.1505847, 0.2742042, 0.3742406, 0.4714045, 0.5741693, 0.69006556, -0.5741693, -0.4714045, -0.3742406, + -0.2742042, -0.1505847], ] ) - true_copula = true_copula.reshape((11, 11)) r = np.array(range(1, 11)) s = np.array([3, 6, 2, 9, 4, 1, 7, 5, 8, 10]) diff --git a/voa/copula.py b/voa/copula.py index 35a300b..b636826 100644 --- a/voa/copula.py +++ b/voa/copula.py @@ -3,10 +3,11 @@ import time import plotly.graph_objs as go import plotly.io as pio +from typing import List, Dict, Tuple, Any @numba.njit(parallel=True) -def Q_function(Q_grid, C_grid): +def Q_function(Q_grid: np.ndarray, C_grid: np.ndarray) -> Dict[str, np.ndarray]: n = len(C_grid) - 1 z = [] @@ -22,7 +23,7 @@ def Q_function(Q_grid, C_grid): return {"x": Q_grid[:, 0], "y": Q_grid[:, 1], "z": np.array(z)} -def create_Q_grid(n=10): +def create_Q_grid(n: int = 10) -> np.ndarray: u = np.linspace(0.5 / (n + 1), (0.5 + n) / (n + 1), n + 1) grid = np.stack(np.meshgrid(u, u)).T.reshape(-1, 2) @@ -30,10 +31,9 @@ def create_Q_grid(n=10): @numba.njit(parallel=True) -def calculate_copula_part(t, c): +def calculate_copula_part(t: np.ndarray, c: np.ndarray) -> np.ndarray: n = len(t) n_inv = 1.0 / float(n) - c = np.zeros(c.shape) for i in numba.prange(1, int(n / 2) + 2): for j in numba.prange(int(n / 2) + 2): c[i, j] = c[0, j] + n_inv * np.sum(j >= t[:i]) @@ -41,14 +41,14 @@ def calculate_copula_part(t, c): @numba.njit -def wn(n, c, i, j): +def wn(n: int, c: float, i: int, j: int) -> float: u = (i + 0.5) / (n + 1) v = (j + 0.5) / (n + 1) return n**0.5 * (c - u * v) * (u * v * (1 - u) * (1 - v)) ** -0.5 @numba.njit -def fill_matrix(n, ks, c, x_prim, y_prim): +def fill_matrix(n: int, ks: np.ndarray, c: np.ndarray, x_prim: bool, y_prim: bool) -> np.ndarray: sign = (-1) ** (x_prim + y_prim) for i in range(int(np.floor((n + 1) / 2)) + 1): @@ -60,7 +60,7 @@ def fill_matrix(n, ks, c, x_prim, y_prim): @numba.njit -def arma_copula(rx, ry): +def arma_copula(rx: np.ndarray, ry: np.ndarray) -> np.ndarray: n = len(rx) ctab = np.zeros((n + 1, n + 1)) @@ -92,13 +92,13 @@ def arma_copula(rx, ry): @numba.njit -def calculate_copula_grid(x, y): +def calculate_copula_grid(x: np.ndarray, y: np.ndarray) -> np.ndarray: return arma_copula( np.argsort(np.argsort(x)) + 1, np.argsort(np.argsort(y)) + 1 ) -def calculate_copula_mc_grid(x, y, mc=100, seed=0): +def calculate_copula_mc_grid(x: np.ndarray, y: np.ndarray, mc: int = 100, seed: int = 0) -> np.ndarray: rng = np.random.RandomState(seed) k = len(x) g = np.zeros((k + 1, len(y) + 1)) @@ -110,20 +110,7 @@ def calculate_copula_mc_grid(x, y, mc=100, seed=0): return g -def create_Q_plot(X, Y, k_plot_grid=100, MC=100, display=True): - """ - Plot Q function based on Monte Carlo estimation. - - Parameters: - - X: List or numpy array, first random variable e.g. [1.1, 2.2, 1.73]. - - Y: List or numpy array, second random variable e.g. [3.1, 1.2, 1.93]. - - k_plot_grid: Number of grid points for the plot, default is 100. - - MC: Number of Monte Carlo replications, default is 100. - - display: Boolean, if true the plot will be displayed, default is True. - - Returns: - - A dictionary containing Q plot data, copula grid, Q grid, and plot points. - """ +def create_Q_plot(X: List[float], Y: List[float], k_plot_grid: int = 100, MC: int = 100, display: bool = True) -> Dict: if len(X) != len(Y): raise ValueError("Size of X and Y do not match") From 0e04522adf07e8eb86e973fcd6ea18aa00433fd8 Mon Sep 17 00:00:00 2001 From: Krzysztof Suwada Date: Thu, 24 Oct 2024 09:41:26 +0200 Subject: [PATCH 4/4] PR changes --- tests/test_voa.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_voa.py b/tests/test_voa.py index 3884ed6..f079a68 100644 --- a/tests/test_voa.py +++ b/tests/test_voa.py @@ -1,5 +1,5 @@ import numpy as np -import voap +import voa def test_copula(): true_copula = np.array( @@ -31,7 +31,7 @@ def test_copula(): r = np.array(range(1, 11)) s = np.array([3, 6, 2, 9, 4, 1, 7, 5, 8, 10]) - test_copula = voap.calculate_copula_grid(r, s) + test_copula = voa.calculate_copula_grid(r, s) assert np.allclose(true_copula, test_copula, atol=1e-6), "Test failed: Copula grid is incorrect"