From 56e6c08b550a6767bf6e660a738d7ce87cd2f6c6 Mon Sep 17 00:00:00 2001 From: hageldave Date: Fri, 13 Sep 2024 15:35:29 +0200 Subject: [PATCH] more consist use of 'n' for number of something --- uadapy/dr/uamds.py | 13 ++++--- uadapy/plotting/plots2D.py | 39 ++++++++++---------- uadapy/plotting/plotsND.py | 73 +++++++++++++++++++------------------- 3 files changed, 63 insertions(+), 62 deletions(-) diff --git a/uadapy/dr/uamds.py b/uadapy/dr/uamds.py index 2e48039..79c3068 100644 --- a/uadapy/dr/uamds.py +++ b/uadapy/dr/uamds.py @@ -307,14 +307,13 @@ def iterate_simple_gradient_descent( normal_distr_spec: np.ndarray, uamds_transforms_init: np.ndarray, precalc_constants: tuple = None, - num_iter: int = 100, + n_iter: int = 100, a: float = 0.0001, optimizer="plain", b1: float = 0.9, b2: float = 0.999, e: float = 10e-8, - mass=0.8 -) -> np.ndarray: + mass=0.8) -> np.ndarray: """ Performs gradient descent on the UAMDS stress to find an optimal projection. This uses a fixed number of iterations after which the method returns. @@ -332,7 +331,7 @@ def iterate_simple_gradient_descent( precalc_constants : tuple a tuple containing the pre-computed constant expressions of the stress and gradient. Can be None and will be computed by precalculate_constants(normal_distr_spec) - num_iter : int + n_iter : int number of iterations to perform. The required number of iterations varies with the used descent scheme. a : float step size (learning rate). Depends on the size of the optimization problem and used descent scheme. @@ -360,7 +359,7 @@ def iterate_simple_gradient_descent( case "adam": m = np.zeros_like(uamds_transforms_init) v = np.zeros_like(uamds_transforms_init) - for i in range(num_iter): + for i in range(n_iter): grad = gradient(normal_distr_spec, uamds_transforms, precalc_constants) m = (1 - b1) * grad + b1 * m # first moment estimate. v = (1 - b2) * (grad ** 2) + b2 * v # second moment estimate. @@ -370,13 +369,13 @@ def iterate_simple_gradient_descent( case "momentum": velocity = np.zeros_like(uamds_transforms_init) - for i in range(num_iter): + for i in range(n_iter): grad = gradient(normal_distr_spec, uamds_transforms, precalc_constants) velocity = mass * velocity + (1.0 - mass) * grad uamds_transforms = uamds_transforms - a * velocity case _: - for i in range(num_iter): + for i in range(n_iter): grad = gradient(normal_distr_spec, uamds_transforms, precalc_constants) uamds_transforms = uamds_transforms - a * grad diff --git a/uadapy/plotting/plots2D.py b/uadapy/plotting/plots2D.py index 7a38088..f8a9b31 100644 --- a/uadapy/plotting/plots2D.py +++ b/uadapy/plotting/plots2D.py @@ -4,7 +4,7 @@ from numpy import ma from matplotlib import ticker -def plot_samples(distributions, num_samples, seed=55, **kwargs): +def plot_samples(distributions, n_samples, seed=55, **kwargs): """ Plot samples from the given distribution. If several distributions should be plotted together, an array can be passed to this function. @@ -13,7 +13,7 @@ def plot_samples(distributions, num_samples, seed=55, **kwargs): ---------- distributions : list List of distributions to plot. - num_samples : int + n_samples : int Number of samples per distribution. seed : int Seed for the random number generator for reproducibility. It defaults to 55 if not provided. @@ -38,7 +38,7 @@ def plot_samples(distributions, num_samples, seed=55, **kwargs): if isinstance(distributions, Distribution): distributions = [distributions] for d in distributions: - samples = d.sample(num_samples, seed) + samples = d.sample(n_samples, seed) plt.scatter(x=samples[:,0], y=samples[:,1]) if 'xlabel' in kwargs: plt.xlabel(kwargs['xlabel']) @@ -121,22 +121,22 @@ def plot_contour(distributions, resolution=128, ranges=None, quantiles:list=None # Monte Carlo approach for determining isovalues isovalues = [] - num_samples = 10_000 #TODO: cleverly determine how many samples are needed based on the largest quantile - samples = d.sample(num_samples, seed) + n_samples = 10_000 #TODO: cleverly determine how many samples are needed based on the largest quantile + samples = d.sample(n_samples, seed) densities = d.pdf(samples) densities.sort() if quantiles is None: - isovalues.append(densities[int((1 - 99.7/100) * num_samples)]) # 99.7% quantile - isovalues.append(densities[int((1 - 95/100) * num_samples)]) # 95% quantile - isovalues.append(densities[int((1 - 68/100) * num_samples)]) # 68% quantile + isovalues.append(densities[int((1 - 99.7/100) * n_samples)]) # 99.7% quantile + isovalues.append(densities[int((1 - 95/100) * n_samples)]) # 95% quantile + isovalues.append(densities[int((1 - 68/100) * n_samples)]) # 68% quantile else: quantiles.sort(reverse=True) for quantile in quantiles: if not 0 < quantile < 100: raise ValueError(f"Invalid quantile: {quantile}. Quantiles must be between 0 and 100 (exclusive).") - elif int((1 - quantile/100) * num_samples) >= num_samples: + elif int((1 - quantile/100) * n_samples) >= n_samples: raise ValueError(f"Quantile {quantile} results in an index that is out of bounds.") - isovalues.append(densities[int((1 - quantile/100) * num_samples)]) + isovalues.append(densities[int((1 - quantile/100) * n_samples)]) plt.contour(xv, yv, pdf, levels=isovalues, colors = [color]) @@ -151,7 +151,8 @@ def plot_contour(distributions, resolution=128, ranges=None, quantiles:list=None return fig, axs -def plot_contour_bands(distributions, num_samples, resolution=128, ranges=None, quantiles:list=None, seed=55, **kwargs): +def plot_contour_bands(distributions, n_samples, resolution=128, ranges=None, quantiles: list = None, seed=55, + **kwargs): """ Plot contour bands for samples drawn from given distributions. @@ -159,7 +160,7 @@ def plot_contour_bands(distributions, num_samples, resolution=128, ranges=None, ---------- distributions : list List of distributions to plot. - num_samples : int + n_samples : int Number of samples per distribution. resolution : int, optional The resolution of the plot. Default is 128. @@ -219,25 +220,25 @@ def plot_contour_bands(distributions, num_samples, resolution=128, ranges=None, coordinates = coordinates.reshape((-1, 2)) pdf = d.pdf(coordinates) pdf = pdf.reshape(xv.shape) - pdf = ma.masked_where(pdf <= 0, pdf) # Mask non-positive values to avoid log scale issues + pdf = np.ma.masked_where(pdf <= 0, pdf) # Mask non-positive values to avoid log scale issues # Monte Carlo approach for determining isovalues isovalues = [] - samples = d.sample(num_samples, seed) + samples = d.sample(n_samples, seed) densities = d.pdf(samples) densities.sort() if quantiles is None: - isovalues.append(densities[int((1 - 99.7/100) * num_samples)]) # 99.7% quantile - isovalues.append(densities[int((1 - 95/100) * num_samples)]) # 95% quantile - isovalues.append(densities[int((1 - 68/100) * num_samples)]) # 68% quantile + isovalues.append(densities[int((1 - 99.7/100) * n_samples)]) # 99.7% quantile + isovalues.append(densities[int((1 - 95/100) * n_samples)]) # 95% quantile + isovalues.append(densities[int((1 - 68/100) * n_samples)]) # 68% quantile else: quantiles.sort(reverse=True) for quantile in quantiles: if not 0 < quantile < 100: raise ValueError(f"Invalid quantile: {quantile}. Quantiles must be between 0 and 100 (exclusive).") - elif int((1 - quantile/100) * num_samples) >= num_samples: + elif int((1 - quantile/100) * n_samples) >= n_samples: raise ValueError(f"Quantile {quantile} results in an index that is out of bounds.") - isovalues.append(densities[int((1 - quantile/100) * num_samples)]) + isovalues.append(densities[int((1 - quantile/100) * n_samples)]) # Generate logarithmic levels and create the contour plot with different colormap for each distribution plt.contourf(xv, yv, pdf, levels=isovalues, locator=ticker.LogLocator(), cmap=colormaps[i % len(colormaps)]) diff --git a/uadapy/plotting/plotsND.py b/uadapy/plotting/plotsND.py index 073300a..79f7b80 100644 --- a/uadapy/plotting/plotsND.py +++ b/uadapy/plotting/plotsND.py @@ -3,7 +3,7 @@ from uadapy import Distribution import uadapy.plotting.utils as utils -def plot_samples(distributions, num_samples, seed=55, **kwargs): +def plot_samples(distributions, n_samples, seed=55, **kwargs): """ Plot samples from the multivariate distribution as a SLOM. @@ -11,7 +11,7 @@ def plot_samples(distributions, num_samples, seed=55, **kwargs): ---------- distributions : list List of distributions to plot. - num_samples : int + n_samples : int Number of samples per distribution. seed : int Seed for the random number generator for reproducibility. It defaults to 55 if not provided. @@ -32,8 +32,8 @@ def plot_samples(distributions, num_samples, seed=55, **kwargs): if isinstance(distributions, Distribution): distributions = [distributions] # Create matrix - numvars = distributions[0].n_dims - fig, axes = plt.subplots(nrows=numvars, ncols=numvars) + n_dims = distributions[0].n_dims + fig, axes = plt.subplots(nrows=n_dims, ncols=n_dims) contour_colors = utils.generate_spectrum_colors(len(distributions)) for ax in axes.flat: # Hide all ticks and labels @@ -44,18 +44,18 @@ def plot_samples(distributions, num_samples, seed=55, **kwargs): for k, d in enumerate(distributions): if d.n_dims < 2: raise Exception('Wrong dimension of distribution') - samples = d.sample(num_samples, seed) + samples = d.sample(n_samples, seed) for i, j in zip(*np.triu_indices_from(axes, k=1)): for x, y in [(i, j), (j, i)]: axes[x,y].scatter(samples[:,y], y=samples[:,x], color=contour_colors[k]) # Fill diagonal - for i in range(numvars): + for i in range(n_dims): axes[i,i].hist(samples[:,i], histtype='stepfilled', fill=False, alpha=1.0, density=True, ec=contour_colors[k]) axes[i,i].xaxis.set_visible(True) axes[i,i].yaxis.set_visible(True) - for i in range(numvars): + for i in range(n_dims): axes[-1,i].xaxis.set_visible(True) axes[i,0].yaxis.set_visible(True) axes[0,1].yaxis.set_visible(True) @@ -71,7 +71,7 @@ def plot_samples(distributions, num_samples, seed=55, **kwargs): return fig, axs -def plot_contour(distributions, num_samples, resolution=128, ranges=None, quantiles:list=None, seed=55, **kwargs): +def plot_contour(distributions, n_samples, resolution=128, ranges=None, quantiles: list = None, seed=55, **kwargs): """ Visualizes a multidimensional distribution in a matrix of contour plots. @@ -79,7 +79,7 @@ def plot_contour(distributions, num_samples, resolution=128, ranges=None, quanti ---------- distributions : list List of distributions to plot. - num_samples : int + n_samples : int Number of samples per distribution. resolution : int, optional The resolution for the pdf. Default is 128. @@ -114,7 +114,7 @@ def plot_contour(distributions, num_samples, resolution=128, ranges=None, quanti distributions = [distributions] contour_colors = utils.generate_spectrum_colors(len(distributions)) # Create matrix - numvars = distributions[0].n_dims + n_dims = distributions[0].n_dims if ranges is None: min_val = np.zeros(distributions[0].mean().shape)+1000 max_val = np.zeros(distributions[0].mean().shape)-1000 @@ -125,7 +125,7 @@ def plot_contour(distributions, num_samples, resolution=128, ranges=None, quanti cov_max = np.max(np.array([np.diagonal(d.cov()), cov_max]), axis=0) cov_max = np.sqrt(cov_max) ranges = [(mi-3*co, ma+3*co) for mi,ma, co in zip(min_val, max_val, cov_max)] - fig, axes = plt.subplots(nrows=numvars, ncols=numvars) + fig, axes = plt.subplots(nrows=n_dims, ncols=n_dims) for i, ax in enumerate(axes.flat): # Hide all ticks and labels ax.xaxis.set_visible(False) @@ -141,28 +141,28 @@ def plot_contour(distributions, num_samples, resolution=128, ranges=None, quanti test = (*test, i) x = np.linspace(ranges[i][0], ranges[i][1], resolution) dims = (*dims, x) - coordinates = np.array(np.meshgrid(*dims)).transpose(tuple(range(1, numvars+1)) + (0,)) + coordinates = np.array(np.meshgrid(*dims)).transpose(tuple(range(1, n_dims+1)) + (0,)) pdf = d.pdf(coordinates.reshape((-1, coordinates.shape[-1]))) pdf = pdf.reshape(coordinates.shape[:-1]) - pdf = pdf.transpose((1,0)+tuple(range(2,numvars))) + pdf = pdf.transpose((1,0)+tuple(range(2,n_dims))) # Monte Carlo approach for determining isovalues isovalues = [] - samples = d.sample(num_samples, seed) + samples = d.sample(n_samples, seed) densities = d.pdf(samples) densities.sort() if quantiles is None: - isovalues.append(densities[int((1 - 99.7/100) * num_samples)]) # 99.7% quantile - isovalues.append(densities[int((1 - 95/100) * num_samples)]) # 95% quantile - isovalues.append(densities[int((1 - 68/100) * num_samples)]) # 68% quantile + isovalues.append(densities[int((1 - 99.7/100) * n_samples)]) # 99.7% quantile + isovalues.append(densities[int((1 - 95/100) * n_samples)]) # 95% quantile + isovalues.append(densities[int((1 - 68/100) * n_samples)]) # 68% quantile else: quantiles.sort(reverse=True) for quantile in quantiles: if not 0 < quantile < 100: raise ValueError(f"Invalid quantile: {quantile}. Quantiles must be between 0 and 100 (exclusive).") - elif int((1 - quantile/100) * num_samples) >= num_samples: + elif int((1 - quantile/100) * n_samples) >= n_samples: raise ValueError(f"Quantile {quantile} results in an index that is out of bounds.") - isovalues.append(densities[int((1 - quantile/100) * num_samples)]) + isovalues.append(densities[int((1 - quantile/100) * n_samples)]) for i, j in zip(*np.triu_indices_from(axes, k=1)): for x, y in [(i, j), (j, i)]: @@ -176,14 +176,14 @@ def plot_contour(distributions, num_samples, resolution=128, ranges=None, quanti axes[x,y].contour(dims[y], dims[x], pdf_agg, levels=isovalues, colors=[color]) # Fill diagonal - for i in range(numvars): + for i in range(n_dims): indices = list(np.arange(d.n_dims)) indices.remove(i) axes[i,i].plot(dims[i], np.sum(pdf, axis=tuple(indices)), color=color) axes[i,i].xaxis.set_visible(True) axes[i,i].yaxis.set_visible(True) - for i in range(numvars): + for i in range(n_dims): axes[-1,i].xaxis.set_visible(True) axes[i,0].yaxis.set_visible(True) axes[0,1].yaxis.set_visible(True) @@ -199,7 +199,8 @@ def plot_contour(distributions, num_samples, resolution=128, ranges=None, quanti return fig, axs -def plot_contour_samples(distributions, num_samples, resolution=128, ranges=None, quantiles:list=None, seed=55, **kwargs): +def plot_contour_samples(distributions, n_samples, resolution=128, ranges=None, quantiles: list = None, seed=55, + **kwargs): """ Visualizes a multidimensional distribution in a matrix visualization where the upper diagonal contains contour plots and the lower diagonal contains scatterplots. @@ -208,7 +209,7 @@ def plot_contour_samples(distributions, num_samples, resolution=128, ranges=None ---------- distributions : list List of distributions to plot. - num_samples : int + n_samples : int Number of samples for the scatterplot. resolution : int, optional The resolution for the pdf. Default is 128. @@ -243,7 +244,7 @@ def plot_contour_samples(distributions, num_samples, resolution=128, ranges=None distributions = [distributions] contour_colors = utils.generate_spectrum_colors(len(distributions)) # Create matrix - numvars = distributions[0].n_dims + n_dims = distributions[0].n_dims if ranges is None: min_val = np.zeros(distributions[0].mean().shape)+1000 max_val = np.zeros(distributions[0].mean().shape)-1000 @@ -254,7 +255,7 @@ def plot_contour_samples(distributions, num_samples, resolution=128, ranges=None cov_max = np.max(np.array([np.diagonal(d.cov()), cov_max]), axis=0) cov_max = np.sqrt(cov_max) ranges = [(mi-3*co, ma+3*co) for mi,ma, co in zip(min_val, max_val, cov_max)] - fig, axes = plt.subplots(nrows=numvars, ncols=numvars) + fig, axes = plt.subplots(nrows=n_dims, ncols=n_dims) for i, ax in enumerate(axes.flat): # Hide all ticks and labels ax.xaxis.set_visible(False) @@ -262,35 +263,35 @@ def plot_contour_samples(distributions, num_samples, resolution=128, ranges=None # Fill matrix with data for k, d in enumerate(distributions): - samples = d.sample(num_samples, seed) + samples = d.sample(n_samples, seed) if d.n_dims < 2: raise Exception('Wrong dimension of distribution') dims = () for i in range(d.n_dims): x = np.linspace(ranges[i][0], ranges[i][1], resolution) dims = (*dims, x) - coordinates = np.array(np.meshgrid(*dims)).transpose(tuple(range(1, numvars+1)) + (0,)) + coordinates = np.array(np.meshgrid(*dims)).transpose(tuple(range(1, n_dims+1)) + (0,)) pdf = d.pdf(coordinates.reshape((-1, coordinates.shape[-1]))) pdf = pdf.reshape(coordinates.shape[:-1]) - pdf = pdf.transpose((1,0)+tuple(range(2,numvars))) + pdf = pdf.transpose((1,0)+tuple(range(2,n_dims))) # Monte Carlo approach for determining isovalues isovalues = [] - samples = d.sample(num_samples, seed) + samples = d.sample(n_samples, seed) densities = d.pdf(samples) densities.sort() if quantiles is None: - isovalues.append(densities[int((1 - 99.7/100) * num_samples)]) # 99.7% quantile - isovalues.append(densities[int((1 - 95/100) * num_samples)]) # 95% quantile - isovalues.append(densities[int((1 - 68/100) * num_samples)]) # 68% quantile + isovalues.append(densities[int((1 - 99.7/100) * n_samples)]) # 99.7% quantile + isovalues.append(densities[int((1 - 95/100) * n_samples)]) # 95% quantile + isovalues.append(densities[int((1 - 68/100) * n_samples)]) # 68% quantile else: quantiles.sort(reverse=True) for quantile in quantiles: if not 0 < quantile < 100: raise ValueError(f"Invalid quantile: {quantile}. Quantiles must be between 0 and 100 (exclusive).") - elif int((1 - quantile/100) * num_samples) >= num_samples: + elif int((1 - quantile/100) * n_samples) >= n_samples: raise ValueError(f"Quantile {quantile} results in an index that is out of bounds.") - isovalues.append(densities[int((1 - quantile/100) * num_samples)]) + isovalues.append(densities[int((1 - quantile/100) * n_samples)]) for i, j in zip(*np.triu_indices_from(axes, k=1)): for x, y in [(i, j), (j, i)]: @@ -307,14 +308,14 @@ def plot_contour_samples(distributions, num_samples, resolution=128, ranges=None axes[x, y].set_ylim(ranges[y][0], ranges[y][1]) # Fill diagonal - for i in range(numvars): + for i in range(n_dims): indices = list(np.arange(d.n_dims)) indices.remove(i) axes[i,i].plot(dims[i], np.sum(pdf, axis=tuple(indices)), color=color) axes[i,i].xaxis.set_visible(True) axes[i,i].yaxis.set_visible(True) - for i in range(numvars): + for i in range(n_dims): axes[-1,i].xaxis.set_visible(True) axes[i,0].yaxis.set_visible(True) axes[0,1].yaxis.set_visible(True)