Source code for numerical_function_spaces.orlicz_spaces.norms

import decimal as dc

import numpy as np
from tqdm import tqdm  # for progress bar


# from numerical_function_spaces.orlicz_spaces.orlicz_functions import *


[docs] def kappa(Orlicz_function, x, k, p_norm): """ Calculates the kappa value for a given set of parameters. Parameters ---------- Orlicz_function : function The Orlicz function to be used. x : np.ndarray A 2D numpy array representing x(t). k : float must be positive. p_norm : float The p-norm to be calculated. Returns ------- The kappa value : np.float64. Raises ------ ValueError: If x[1, :] contains non-positive values. Examples -------- >>> x = np.array([[1],[1]]) >>> def Orlicz_function(u): ... return u ... >>> kappa(Orlicz_function, x=x, k=1, p_norm=1) np.float64(2.0) """ # x_abs = np.zeros(shape=np.shape(x)) # x[0, :] = abs(x[0, :]) powoduje zmianę zewnętrznej zmiennej!!! ??? # x_abs[0, :] = abs(x[0, :]) # x_abs[1, :] = x[1, :] if any(x[1, :] <= 0): raise ValueError("wrong definition of x(t): x[1, :] must be positive") x = abs(x) # np.nansum dopuszcza wagi nieskończone przyjmujemy wtedy, że 0*inf = 0. Numpy przyjmuje, że to jest Nan if p_norm == 1: return 1 / k * (1 + np.nansum(Orlicz_function((k * x[0, :])) * x[1, :])) elif p_norm == np.inf: return 1 / k * (max(1, np.nansum(Orlicz_function((k * x[0, :])) * x[1, :]))) else: return 1 / k * (1 + (np.nansum(Orlicz_function((k * x[0, :])) * x[1, :]) ** p_norm)) ** (1 / p_norm)
[docs] def p_Amemiya_norm( Orlicz_function, x: np.ndarray, p_norm: float): """ Calculates the p_Amemiya norm for a given set of parameters. Parameters ---------- Orlicz_function : function The Orlicz function to be used. x : np.ndarray A 2D numpy array representing x(t). p_norm : float The p-norm to be calculated. Returns ------- value of the p-Amemiya norm : np.float64. Raises ------ ValueError: If x[1, :] contains non-positive values. Examples -------- >>> x = np.array([[1],[1]]) >>> def Orlicz_function(u): ... return u ... >>> p_Amemiya_norm(Orlicz_function, x=x, p_norm=1) np.float64(1.0) """ if any(x[1, :] <= 0): raise ValueError("wrong definition of x(t): x[1, :] must be positive") x = abs(x) if np.max(x[0, :]) == 0: return 0, np.nan, np.nan val_k = np.empty([2, 5]) # domain and values kappa - for looking minimum val_k[:] = None val_k[1, 0] = 1 val_k[1, 1] = 2 val_k[1, 2] = 4 val_k[1, 3] = 8 val_k[1, 4] = 16 for i in range(5): val_k[0, i] = kappa(Orlicz_function, x, k=val_k[1, i], p_norm=p_norm) # print(np.nanmin(val_k[0])) # print(np.nanargmin(val_k[0])) # print(val_k) for i in range(100): if np.nanargmin(val_k[0]) == 0: # print('pierwszy najmniejszy') val_k[:, 4] = val_k[:, 3] val_k[:, 3] = val_k[:, 2] val_k[:, 2] = val_k[:, 1] val_k[:, 1] = val_k[:, 0] val_k[1, 0] = (val_k[1, 1]) / 2 val_k[0, 0] = kappa(Orlicz_function, x, k=val_k[1, 0], p_norm=p_norm) elif np.nanargmin(val_k[0]) == 1: # print('drugi najmniejszy') val_k[:, 4] = val_k[:, 3] val_k[:, 3] = val_k[:, 2] val_k[:, 2] = val_k[:, 1] val_k[1, 1] = (val_k[1, 0] + val_k[1, 2]) / 2 val_k[0, 1] = kappa(Orlicz_function, x, k=val_k[1, 1], p_norm=p_norm) elif np.nanargmin(val_k[0]) == 2: # print('trzeci najmniejszy') val_k[:, 4] = val_k[:, 3] val_k[:, 3] = val_k[:, 2] val_k[1, 2] = (val_k[1, 1] + val_k[1, 3]) / 2 val_k[0, 2] = kappa(Orlicz_function, x, k=val_k[1, 2], p_norm=p_norm) elif np.nanargmin(val_k[0]) == 3: # print('czwarty najmniejszy') val_k[:, 0] = val_k[:, 1] val_k[:, 1] = val_k[:, 2] val_k[:, 2] = val_k[:, 3] val_k[1, 3] = (val_k[1, 2] + val_k[1, 4]) / 2 val_k[0, 3] = kappa(Orlicz_function, x, k=val_k[1, 3], p_norm=p_norm) else: # print('ostatni najmniejszy') val_k[:, 0] = val_k[:, 1] val_k[:, 1] = val_k[:, 2] val_k[:, 2] = val_k[:, 3] val_k[:, 3] = val_k[:, 4] val_k[1, 4] = val_k[1, 3] * 2 val_k[0, 4] = kappa(Orlicz_function, x, k=val_k[1, 4], p_norm=p_norm) # print(f'{np.nanmin(val_k[0]):.16}') # print(np.nanargmin(val_k[0])) # print(val_k) return np.nanmin(val_k[0])
# array_for_infimum was replaced by kappa # def array_for_infimum( # tego chyba nie używamy # Orlicz_function, # x: np.ndarray, # # dt: float, # k_min: float, # k_max: float, # dk: float, # p_norm: float, # show_progress: bool = False # ) -> tuple: # x = abs(x) # domain_k = np.arange(k_min, k_max, dk) # array_k = np.array([]) # if p_norm == 1: # with tqdm( # total=len(domain_k), # # desc="counting of infimum in [" + str(k_min) + "," + str(k_max) + "]", # # desc="counting of $1/k*s_p(I_phi)(kx)$ in [" + str(k_min) + "," + str(k_max) + "]", # desc=f"counting of $\\kappa_{{p={p_norm},x}}(k)$ in [" + str(k_min) + "," + str(k_max) + "]", # disable=not show_progress # ) as pbar: # for k in domain_k: # array_k = np.append( # array_k, # 1 / k * (1 + np.nansum(Orlicz_function((k * x[0])) * x[1])), # ) # pbar.update(1) # elif p_norm == np.inf: # with tqdm( # total=len(domain_k), # # desc="counting of infimum in [" + str(k_min) + "," + str(k_max) + "]", # desc=f"counting of $\\kappa_{{p={p_norm},x}}(k)$ in [" + str(k_min) + "," + str(k_max) + "]", # disable=not show_progress # ) as pbar: # for k in domain_k: # array_k = np.append( # array_k, # 1 # / k # * ( # max( # 1, # np.nansum(Orlicz_function((k * x[0])) * x[1]), # ) # ), # ) # pbar.update(1) # else: # with tqdm( # total=len(domain_k), # # desc="counting of infimum in [" + str(k_min) + "," + str(k_max) + "]", # desc=f"counting of $\\kappa_{{p={p_norm},x}}(k)$ in [" + str(k_min) + "," + str(k_max) + "]", # disable=not show_progress # ) as pbar: # for k in domain_k: # array_k = np.append( # array_k, # 1 # / k # * ( # 1 # + ( # np.nansum(Orlicz_function((k * x[0])) * x[1]) # ** p_norm # ) # ) # ** (1 / p_norm), # ) # pbar.update(1) # # print(array_k) # return domain_k, array_k
[docs] def Orlicz_norm_with_stars( Orlicz_function, x: np.ndarray, # dt: float, k_min: float = 0.000001, k_max: float = 100, dk: float = None, len_domain_k: int = 1000, show_progress: bool = False ): """ Computes the Orlicz norm and k^{*} and k^{**} of the function "x(t)" in Orlicz space for a given set of parameters as p_Amimiya norm for p_norm=1 Parameters ---------- Orlicz_function : function The Orlicz function to be used. x : np.ndarray A 2D numpy array representing x(t). k_min : float, optional The minimum value of the k domain, by default 0.000001. k_max : float, optional The maximum value of the k domain, by default 100. dk : float, optional Step of k_domain, by default None When given, more important than len_domain_k len_domain_k : int, optional The number of points in the k domain, by default 1000. show_progress : bool, optional Whether to show a progress bar during computation, by default, False. Returns ------- - A tuple containing the value of the Orlicz norm, k^{*}, k^{**}. Examples -------- >>> x = np.array([[1],[2]]) >>> def Orlicz_function(u): ... return np.where(u <= 1, 0, u - 1) ... >>> Orlicz_norm_with_stars(Orlicz_function, x) (np.float64(1.000008302431002), np.float64(1.0000083024999329), np.float64(1.0000083024999329)) """ # return p_Amemiya_norm_with_stars(Orlicz_function, x, dt, 1, k_min, k_max, len_domain_k, # show_progress=show_progress) return p_Amemiya_norm_with_stars(Orlicz_function, x, 1, k_min, k_max, dk, len_domain_k, show_progress=show_progress)
[docs] def Luxemburg_norm_with_stars( Orlicz_function, x: np.ndarray, # dt: float, k_min: float = 0.000001, k_max: float = 100, dk: float = None, len_domain_k: int = 1000, show_progress: bool = False ): """ Computes the Luxemburg norm and k^{*} and k^{**} of the function "x(t)" in Orlicz space for a given set of parameters as p_Amimiya norm for p_norm=np.inf Parameters ---------- Orlicz_function : function The Orlicz function to be used. x : np.ndarray A 2D numpy array representing x(t). k_min : float, optional The minimum value of the k domain, by default 0.000001. k_max : float, optional The maximum value of the k domain, by default 100. dk : float, optional Step of k_domain, by default None When given, more important than len_domain_k len_domain_k : int, optional The number of points in the k domain, by default 1000. show_progress : bool, optional Whether to show a progress bar during computation, by default, False. Returns ------- - A tuple containing the value of the Luxemburg norm, k^{*}, k^{**}. Examples -------- >>> x = np.array([[1],[2]]) >>> def Orlicz_function(u): ... return np.where(u <= 1, 0, u - 1) ... >>> Luxemburg_norm_with_stars(Orlicz_function, x) (np.float64(0.666712308582787), np.float64(1.4998973127189956), np.float64(1.4998973127189956)) """ # return p_Amemiya_norm_with_stars(Orlicz_function, x, dt, np.inf, k_min, k_max, len_domain_k, # show_progress=show_progress) return p_Amemiya_norm_with_stars(Orlicz_function, x, np.inf, k_min, k_max, dk, len_domain_k, show_progress=show_progress)
[docs] def p_Amemiya_norm_with_stars( Orlicz_function, x: np.ndarray, # dt: float, p_norm: float, k_min: float = 0.000001, k_max: float = 100, dk: float = None, len_domain_k: int = 1000, show_progress: bool = False ): """ Computes the p-Amemiya norm and k^{*} and k^{**} of the function "x(t)" in Orlicz space for a given set of parameters Parameters ---------- Orlicz_function : function The Orlicz function to be used. x : np.ndarray A 2D numpy array representing x(t). p_norm : float The p-norm to be calculated. k_min : float, optional The minimum value of the k domain, by default 0.000001. k_max : float, optional The maximum value of the k domain, by default 100. dk : float, optional Step of k_domain, by default None When given, more important than len_domain_k len_domain_k : int, optional The number of points in the k domain, by default 1000. show_progress : bool, optional Whether to show a progress bar during computation, by default, False. Returns ------- A tuple containing the value of the p-Amemiya norm, k^{*}, k^{**}. Note ---- Precision problem with k^{*} false less than k^{**} for Phi = max(u,2u-1), x=chi_(0,3), p=20. Too small accuracy. Problem eliminated in slower function p_Amemiya_norm_with_stars_by_decimal(). Examples -------- >>> x = np.array([[1],[1]]) >>> def Orlicz_function(u): ... return u**2 ... >>> p_Amemiya_norm_with_stars(Orlicz_function, x=x, p_norm=1) (np.float64(2.000000000068931), np.float64(1.0000083024999067), np.float64(1.0000083024999067)) """ if any(x[1, :] <= 0): raise ValueError("wrong definition of x(t): x[1, :] must be positive") x = abs(x) if np.max(x[0, :]) == 0: return 0, np.nan, np.nan # k_min = 0.000001 # k_max = 100 # len_domain_k = 1000 if dk is None: # if len_domain_k is specified by user dk = (k_max - k_min) / len_domain_k else: len_domain_k == (k_max - k_min) * dk # domain_k = np.arange(k_min, k_max, dk) # print("k_min = ", k_min, ",k_max= ", k_max) # domain_k, array_k = array_for_infimum( # Orlicz_function, x, dt, k_min, k_max, dk, p_norm, show_progress=show_progress # ) # domain_k, array_k = array_for_infimum( # Orlicz_function, x, k_min, k_max, dk, p_norm, show_progress=show_progress # ) domain_k = np.arange(k_min, k_max, dk) array_k = np.array([]) with tqdm( total=len(domain_k), # desc="counting of infimum in [" + str(k_min) + "," + str(k_max) + "]", # desc="counting of $1/k*s_p(I_phi)(kx)$ in [" + str(k_min) + "," + str(k_max) + "]", desc=f"counting of $\\kappa_{{p={p_norm},x}}(k)$ in [" + str(k_min) + "," + str(k_max) + "]", disable=not show_progress ) as pbar: for k in domain_k: array_k = np.append(array_k, kappa(Orlicz_function, x, k, p_norm)) pbar.update(1) # Todo: precision problem with k^* false less than k^** for Phi = max(u,2u-1), x=chi_(0,3), p=10. too small accuracy. accuracy = max((np.max(array_k[np.isfinite(array_k)]) - np.min(array_k[np.isfinite(array_k)])) * 0.000001, 1e-15) osiagane_minimum = np.where( np.logical_and( # array_k < array_k[np.argmin(array_k)] + 0.00001, # array_k > array_k[np.argmin(array_k)] - 0.00001, array_k < array_k[np.argmin(array_k)] + accuracy, array_k > array_k[np.argmin(array_k)] - accuracy, ) ) # print(accuracy) # print(osiagane_minimum) # k_star = domain_k[np.min(osiagane_minimum) - 1] k_star = domain_k[np.min(osiagane_minimum)] # k_star_star = domain_k[np.max(osiagane_minimum) + 1] k_star_star = domain_k[np.max(osiagane_minimum)] # print(f"||x||={min(array_k)}, k^*={k_star}, k^(**)={k_star_star}") ''' for default values, try to count more precisely ''' ''' Problem with k^**=infinity and k^*=1 - wrong calculations ''' if k_min == 0.000001 and k_max == 100 and len_domain_k == 1000: for licz in range(4): # print(licz) # print("||x||=", min(array_k)) # print("k_min = ", k_min, ",k_max= ", k_max) if ( np.max( np.where(array_k < array_k[np.argmin(array_k)] + 0.00001) ) == len(domain_k) - 1 ): if licz == 1: # po do to jest? przy pierwszym wejściu jest licz = 0. pass # 14.07.2024 wcześniej było break, ale wyrzucało po jednym wejściu do pętli else: k_min = 0.5 * (k_min + domain_k[ np.min( np.where( array_k < np.min(array_k) + 0.00001 ) ) ] ) # print(k_min,np.min(array_k), # np.min(domain_k[np.where(array_k < (np.min(array_k) + 0.00001))])) k_max = 10 * k_max len_domain_k = 10 * len_domain_k else: parametr = (0.5 ** (licz + 1)) * ( max( domain_k[ np.min( np.where( array_k < np.min(array_k) + 0.00001 ) ) ] - k_min, k_max - domain_k[ np.max( np.where( array_k < np.min(array_k) + 0.00001 ) ) ], ) ) k_min = max( k_min, domain_k[ np.min( np.where( array_k < np.min(array_k) + 0.00001 ) ) ] - parametr, ) k_max = min( k_max, domain_k[ np.max( np.where( array_k < np.min(array_k) + 0.00001 ) ) ] + parametr, ) # print(domain_k[np.min(np.where(array_k < array_k[np.argmin(array_k)]+0.00001*0.1**licz))]) # print(domain_k[np.max(np.where(array_k < array_k[np.argmin(array_k)]+0.00001*0.1**licz))]) dk = (k_max - k_min) / len_domain_k # domain_k = np.arange(k_min, k_max, dk) # domain_k, array_k = array_for_infimum( # Orlicz_function, x, dt, k_min, k_max, dk, p_norm, show_progress=show_progress # ) # domain_k, array_k = array_for_infimum( # Orlicz_function, x, k_min, k_max, dk, p_norm, show_progress=show_progress # ) domain_k = np.arange(k_min, k_max, dk) array_k = np.array([]) with tqdm( total=len(domain_k), # desc="counting of infimum in [" + str(k_min) + "," + str(k_max) + "]", # desc="counting of $1/k*s_p(I_phi)(kx)$ in [" + str(k_min) + "," + str(k_max) + "]", desc=f"counting of $\\kappa_{{p={p_norm},x}}(k)$ in [" + str(k_min) + "," + str(k_max) + "]", disable=not show_progress ) as pbar: for k in domain_k: array_k = np.append(array_k, kappa(Orlicz_function, x, k, p_norm)) pbar.update(1) accuracy = max((np.max(array_k[np.isfinite(array_k)]) - np.min(array_k[np.isfinite(array_k)])) * 0.000001, 1e-15) osiagane_minimum = np.where( np.logical_and( # array_k < array_k[np.argmin(array_k)] + 0.00001, # array_k > array_k[np.argmin(array_k)] - 0.00001, array_k < array_k[np.argmin(array_k)] + accuracy, array_k > array_k[np.argmin(array_k)] - accuracy, ) ) # print(accuracy) # print(osiagane_minimum) # k_star = domain_k[np.min(osiagane_minimum) - 1] k_star = domain_k[np.min(osiagane_minimum)] # k_star_star = domain_k[np.max(osiagane_minimum) + 1] k_star_star = domain_k[np.max(osiagane_minimum)] if k_max >= 10000: print('\n\x1b[41m Time to consider infinity\x1b[0m ') break # print(f"||x||={min(array_k)}, k^*={k_star}, k^(**)={k_star_star}") ''' above problem with k^**=infinity and k^*=1 - ''' # print(array_k) # print(np.nanmin(osiagane_minimum), np.nanmax(osiagane_minimum)) if np.min(osiagane_minimum) == 0: print('k_star is equal to k_min: try smaller k_min') if np.max(osiagane_minimum) == len(domain_k) - 1: print('k_star_star is equal to k_max: try larger k_max') return min(array_k), k_star, k_star_star # , domain_k, array_k
[docs] def p_Amemiya_norm_with_stars_by_decimal( Orlicz_function, x: np.ndarray, # dt: float, p_norm: dc.Decimal, k_min: dc.Decimal = dc.Decimal(1) / 100000, k_max: dc.Decimal = dc.Decimal(100), dk: dc.Decimal = None, len_domain_k: int = 1000, show_progress: bool = False ) -> tuple: """ Computes the p-Amemiya norm and k^{*} and k^{**} of the function "x(t)" in Orlicz space for a given set of parameters Parameters ---------- Orlicz_function : function The Orlicz function to be used in form accepting decimal numbers x : np.ndarray A 2D numpy array representing x(t). p_norm : float The p-norm to be calculated (in decimal form). k_min : float, optional The minimum value of the k domain in decimal form, by default 1/100000. k_max : float, optional The maximum value of the k domain in decimal form, by default 100. dk : float, optional Step of k_domain, by default None When given, more important than len_domain_k len_domain_k : int, optional The number of points in the k domain in decimal form, by default 1000. show_progress : bool, optional Whether to show a progress bar during computation, by default False. Returns ------- A tuple containing the minimum value of the p-Amemiya norm, k^{*}, k^{**}, kappa_domain, and kappa_values. Raises ------ - ValueError: If any value in x[1, :] is less than or equal to 0. Examples -------- >>> x = np.array([[1], [2]]) >>> def Orlicz_function(u): ... return np.where(u <= 1, u, dc.Decimal(np.inf)) ... >>> dc.getcontext().prec = 20 >>> p_Amemiya_norm_with_stars_by_decimal(Orlicz_function, x=x, p_norm=dc.Decimal(np.inf), ... k_min = dc.Decimal(4)/10, ... k_max = dc.Decimal(11)/10, ... dk = dc.Decimal(1)/100) ... (Decimal('1.9999999999999999999'), Decimal('0.50'), Decimal('1.00')) """ if any(x[1, :] <= 0): raise ValueError("wrong definition of x(t): x[1, :] must be positive") x = abs(x) if np.max(x[0, :]) == 0: return 0, np.nan, np.nan if dk is None: # if user specifies len_domain_k dk = (k_max - k_min) / len_domain_k else: len_domain_k = (k_max - k_min) * dk kappa_domain = [] # n = dc.Decimal(0) # while k_min + n * dk < k_max: # # for n in range(len_domain_k): # kappa_domain.append(k_min + n * dk) # n += dc.Decimal(1) # kappa_domain = np.array(kappa_domain) kappa_domain = np.arange(k_min, k_max, dk) kappa_values = [] if p_norm == 1: with tqdm( total=len(kappa_domain), # desc="counting of infimum in [" + str(k_min) + "," + str(k_max) + "]", # desc="counting of $1/k*s_p(I_phi)(kx)$ in [" + str(k_min) + "," + str(k_max) + "]", desc=f"counting of $\\kappa_{{p={p_norm},x}}(k)$ in [" + str(k_min) + "," + str(k_max) + "]", disable=not show_progress ) as pbar: for k in kappa_domain: # print(k, type(k), x[0], x[1]) kappa_values = np.append( kappa_values, dc.Decimal(1) / k * (1 + np.nansum(Orlicz_function((k * x[0, :])) * x[1, :])), ) pbar.update(1) elif p_norm == np.inf: with tqdm( total=len(kappa_domain), # desc="counting of infimum in [" + str(k_min) + "," + str(k_max) + "]", desc=f"counting of $\\kappa_{{p={p_norm},x}}(k)$ in [" + str(k_min) + "," + str(k_max) + "]", disable=not show_progress ) as pbar: for k in kappa_domain: kappa_values = np.append( kappa_values, dc.Decimal(1) / k * ( max( 1, np.nansum(Orlicz_function((k * x[0, :])) * x[1, :]), ) ), ) pbar.update(1) else: with tqdm( total=len(kappa_domain), # desc="counting of infimum in [" + str(k_min) + "," + str(k_max) + "]", desc=f"counting of $\\kappa_{{p={p_norm},x}}(k)$ in [" + str(k_min) + "," + str(k_max) + "]", disable=not show_progress ) as pbar: for k in kappa_domain: kappa_values = np.append( kappa_values, dc.Decimal(1) / k * ( 1 + ( np.nansum(Orlicz_function((k * x[0, :])) * x[1, :]) ** p_norm ) ) ** (dc.Decimal(1) / p_norm), ) pbar.update(1) # print(array_k) kappa_values = np.array(kappa_values) accuracy = dc.Decimal(10 ** (-dc.getcontext().prec + 2)) # + 1 is not enough osiagane_minimum = np.where( np.logical_and( kappa_values < kappa_values[np.nanargmin(kappa_values)] + accuracy, kappa_values > kappa_values[np.nanargmin(kappa_values)] - accuracy, ) ) k_star = kappa_domain[np.nanmin(osiagane_minimum)] k_star_star = kappa_domain[np.nanmax(osiagane_minimum)] if np.nanmin(osiagane_minimum) == 0: print('k_star is equal to k_min: try smaller k_min') if np.nanmax(osiagane_minimum) == len(kappa_domain) - 1: print('k_star_star is equal to k_max: try larger k_max') return np.nanmin(kappa_values), k_star, k_star_star # , kappa_domain, kappa_values
if __name__ == "__main__": import doctest # import the doctest library doctest.testmod(verbose=True) # run the tests and display all results (pass or fail)