### Get the effective ground set Source: https://submodlib.readthedocs.io/en/latest/functions/concaveOverModular.html Retrieve the effective ground set of the ConcaveOverModularFunction object. ```python from submodlib.functions.concaveOverModular import ConcaveOverModularFunction com_function = ConcaveOverModularFunction(n=10, num_queries=5) # Get the effective ground set ground_set = com_function.getEffectiveGroundSet() ``` -------------------------------- ### DisparityMin Initialization and Kernel Handling Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/disparityMin.html This snippet shows the core initialization logic for the `DisparityMin` class, including validation of input similarity kernels (dense or sparse) or raw data, and their conversion into internal C++ compatible structures for efficient computation. ```python if type(self.sijs) != type(None): # User has provided similarity kernel if type(self.sijs) == scipy.sparse.csr.csr_matrix: if num_neighbors is None or num_neighbors <= 0: raise Exception("ERROR: Positive num_neighbors must be provided for given sparse kernel") if mode != "sparse": raise Exception("ERROR: Sparse kernel provided, but mode is not sparse") elif type(self.sijs) == np.ndarray: if mode != "dense": raise Exception("ERROR: Dense kernel provided, but mode is not dense") else: raise Exception("Invalid kernel provided") #TODO: is the below dimensionality check valid for both dense and sparse kernels? if np.shape(self.sijs)[0]!=self.n or np.shape(self.sijs)[1]!=self.n: raise Exception("ERROR: Inconsistentcy between n and dimensionality of given similarity kernel") if type(self.data) != type(None): print("WARNING: similarity kernel found. Provided data matrix will be ignored.") else: #similarity kernel has not been provided if type(self.data) != type(None): if np.shape(self.data)[0]!=self.n: raise Exception("ERROR: Inconsistentcy between n and no of examples in the given data matrix") if self.mode == "dense": if self.num_neighbors is not None: raise Exception("num_neighbors wrongly provided for dense mode") self.num_neighbors = np.shape(self.data)[0] #Using all data as num_neighbors in case of dense mode self.cpp_content = np.array(subcp.create_kernel(self.data.tolist(), self.metric, self.num_neighbors)) val = self.cpp_content[0] row = list(self.cpp_content[1].astype(int)) col = list(self.cpp_content[2].astype(int)) if self.mode=="dense": self.sijs = np.zeros((n,n)) self.sijs[row,col] = val if self.mode=="sparse": self.sijs = sparse.csr_matrix((val, (row, col)), [n,n]) else: raise Exception("ERROR: Neither ground set data matrix nor similarity kernel provided") cpp_ground_sub = {-1} #Provide a dummy set for pybind11 binding to be successful #Breaking similarity matrix to simpler native data structures for implicit pybind11 binding if self.mode=="dense": self.cpp_sijs = self.sijs.tolist() #break numpy ndarray to native list of list datastructure if type(self.cpp_sijs[0])==int or type(self.cpp_sijs[0])==float: #Its critical that we pass a list of list to pybind11 #This condition ensures the same in case of a 1D numpy array (for 1x1 sim matrix) l=[] l.append(self.cpp_sijs) self.cpp_sijs=l self.cpp_obj = DisparityMin(self.n, self.cpp_sijs, False, cpp_ground_sub) if self.mode=="sparse": #break scipy sparse matrix to native component lists (for csr implementation) self.cpp_sijs = {} self.cpp_sijs['arr_val'] = self.sijs.data.tolist() #contains non-zero values in matrix (row major traversal) self.cpp_sijs['arr_count'] = self.sijs.indptr.tolist() #cumulitive count of non-zero elements upto but not including current row self.cpp_sijs['arr_col'] = self.sijs.indices.tolist() #contains col index corrosponding to non-zero values in arr_val self.cpp_obj = DisparityMin(self.n, self.cpp_sijs['arr_val'], self.cpp_sijs['arr_count'], self.cpp_sijs['arr_col']) self.effective_ground = self.cpp_obj.getEffectiveGroundSet() ``` -------------------------------- ### FacilityLocationConditionalMutualInformation Initialization and Kernel Handling Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocationConditionalMutualInformation.html Handles the initialization of the FacilityLocationConditionalMutualInformation class, including validation of provided similarity kernels or construction of kernels from data matrices. It ensures data types and dimensions are correct before proceeding. ```python if (type(self.data_sijs) != type(None)) and (type(self.query_sijs) != type(None)) and (type(self.private_sijs) != type(None)): if type(self.data_sijs) != np.ndarray: raise Exception("Invalid data kernel type provided, must be ndarray") if type(self.query_sijs) != np.ndarray: raise Exception("Invalid query kernel type provided, must be ndarray") if type(self.private_sijs) != np.ndarray: raise Exception("Invalid private kernel type provided, must be ndarray") if np.shape(self.data_sijs)[0]!=self.n or np.shape(self.data_sijs)[1]!=self.n: raise Exception("ERROR: data kernel should be n X n") if np.shape(self.query_sijs)[0]!=self.n or np.shape(self.query_sijs)[1]!=self.num_queries: raise Exception("ERROR: Query Kernel should be n X num_queries") if np.shape(self.private_sijs)[0]!=self.n or np.shape(self.private_sijs)[1]!=self.num_privates: raise Exception("ERROR: Query Kernel should be n X num_privates") if (type(self.data) != type(None)) or (type(self.queryData) != type(None)) or (type(self.privateData) != type(None)): print("WARNING: similarity kernels found. Provided data and query and private matrices will be ignored.") else: #similarity kernels have not been provided if (type(self.data) == type(None)) or (type(self.queryData) == type(None)) or (type(self.privateData) == type(None)): raise Exception("Since kernels are not provided, data matrices are a must") if np.shape(self.data)[0]!=self.n: raise Exception("ERROR: Inconsistentcy between n and no of examples in the given data matrix") if np.shape(self.queryData)[0]!=self.num_queries: raise Exception("ERROR: Inconsistentcy between num_queries and no of examples in the given query data matrix") if np.shape(self.privateData)[0]!=self.num_privates: raise Exception("ERROR: Inconsistentcy between num_privates and no of examples in the given query data matrix") #construct imageKernel self.num_neighbors = self.n #Using all data as num_neighbors in case of dense mode self.cpp_content = np.array(subcp.create_kernel(self.data.tolist(), self.metric, self.num_neighbors)) val = self.cpp_content[0] row = list(self.cpp_content[1].astype(int)) col = list(self.cpp_content[2].astype(int)) self.data_sijs = np.zeros((self.n,self.n)) self.data_sijs[row,col] = val #construct queryKernel self.query_sijs = np.array(subcp.create_kernel_NS(self.queryData.tolist(),self.data.tolist(), self.metric)) #construct privateKernel self.private_sijs = np.array(subcp.create_kernel_NS(self.privateData.tolist(),self.data.tolist(), self.metric)) ``` -------------------------------- ### Get Effective Ground Set Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/setFunction.html Retrieves the effective ground set associated with this object. ```python return self.cpp_obj.getEffectiveGroundSet() ``` -------------------------------- ### FacilityLocation Initialization with Sparse Matrix Components Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocation.html Initializes FacilityLocation using components extracted from a SciPy sparse matrix (CSR format). ```python self.cpp_sijs = {} self.cpp_sijs['arr_val'] = self.sijs.data.tolist() self.cpp_sijs['arr_count'] = self.sijs.indptr.tolist() self.cpp_sijs['arr_col'] = self.sijs.indices.tolist() self.cpp_obj = FacilityLocation(self.n, self.cpp_sijs['arr_val'], self.cpp_sijs['arr_count'], self.cpp_sijs['arr_col']) ``` -------------------------------- ### Get Effective Ground Set Source: https://submodlib.readthedocs.io/en/latest/functions/facilityLocationConditionalMutualInformation.html Retrieve the effective ground set for the FLCMI function object. ```python getEffectiveGroundSet() ``` -------------------------------- ### Get Effective Ground Set Source: https://submodlib.readthedocs.io/en/latest/functions/logDeterminantConditionalGain.html Retrieves the effective ground set of the LogDeterminantConditionalGain object. This represents the set of all possible elements that can be considered. ```python ground_set = logDetCG.getEffectiveGroundSet() ``` -------------------------------- ### FacilityLocation Initialization with NumPy Array Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocation.html Initializes FacilityLocation using a NumPy array for pairwise similarities. ```python self.cpp_obj = FacilityLocation(self.n, self.sijs, False, self.cpp_ground_sub, self.separate_rep) ``` -------------------------------- ### Initialize ConcaveOverModular without Query Kernel Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/concaveOverModular.html Handles initialization when no query similarity kernel is provided. It requires data and query data matrices to be present and validates their dimensions against 'n' and 'num_queries' respectively. It then constructs the query kernel using `subcp.create_kernel_NS`. ```python else: #similarity query kernel has not been provided if (type(self.data) == type(None)) or (type(self.queryData) == type(None)): raise Exception("Since query kernel is not provided, data matrices are a must") if np.shape(self.data)[0]!=self.n: raise Exception("ERROR: Inconsistentcy between n and no of examples in the given data matrix") if np.shape(self.queryData)[0]!=self.num_queries: raise Exception("ERROR: Inconsistentcy between num_queries and no of examples in the given query data matrix") #construct queryKernel self.query_sijs = np.array(subcp.create_kernel_NS(self.queryData.tolist(),self.data.tolist(), self.metric)) ``` -------------------------------- ### FacilityLocation Initialization with Dense Data Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocation.html Initializes FacilityLocation with dense data represented as a list of lists. ```python self.cpp_obj = FacilityLocation(self.n, self.data.tolist(), self.data_rep.tolist(), True, self.metric) ``` ```python self.cpp_obj = FacilityLocation(self.n, self.data.tolist(), [[0.]], False, self.metric) ``` -------------------------------- ### FacilityLocation Class Kernel Initialization Logic Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocation.html This code defines the internal logic for initializing similarity kernels within the `FacilityLocation` class. It handles various scenarios including user-provided kernels (dense or sparse), data matrices, and different modes of operation, performing validation and kernel creation. ```python if type(self.sijs) != type(None): # User has provided similarity kernel if create_dense_cpp_kernel_in_python == False: raise Exception("ERROR: create_dense_cpp_kernel_in_python is to be set to False ONLY when a similarity kernel is not provided and a CPP kernel is desired to be created in CPP") if type(self.sijs) == scipy.sparse.csr.csr_matrix: if num_neighbors is None or num_neighbors <= 0: raise Exception("ERROR: Positive num_neighbors must be provided for given sparse kernel") if mode != "sparse": raise Exception("ERROR: Sparse kernel provided, but mode is not sparse") elif type(self.sijs) == np.ndarray: if self.separate_rep is None: raise Exception("ERROR: separate_rep bool must be specified with custom dense kernel") if mode != "dense": raise Exception("ERROR: Dense kernel provided, but mode is not dense") else: raise Exception("Invalid kernel provided") #TODO: is the below dimensionality check valid for both dense and sparse kernels? if self.separate_rep == True: if np.shape(self.sijs)[1]!=self.n or np.shape(self.sijs)[0]!=self.n_rep: raise Exception("ERROR: Inconsistency between n_rep, n and no of rows, columns of given kernel") else: if np.shape(self.sijs)[0]!=self.n or np.shape(self.sijs)[1]!=self.n: raise Exception("ERROR: Inconsistentcy between n and dimensionality of given similarity kernel") if type(self.data) != type(None) or type(self.data_rep) != type(None): print("WARNING: similarity kernel found. Provided data matrix will be ignored.") else: #similarity kernel has not been provided if type(self.data) != type(None): if self.separate_rep == True: if type(self.data_rep) == type(None): raise Exception("Represented data matrix not given") if np.shape(self.data)[0]!=self.n or np.shape(self.data_rep)[0]!=self.n_rep: raise Exception("ERROR: Inconsistentcy between n, n_rep and no of examples in the given ground data matrix and represented data matrix") else: if type(self.data_rep) != type(None): print("WARNING: Represented data matrix not required but given, will be ignored.") if np.shape(self.data)[0]!=self.n: raise Exception("ERROR: Inconsistentcy between n and no of examples in the given data matrix") if self.mode=="clustered": self.clusters, self.cluster_sijs, self.cluster_map = create_cluster_kernels(self.data.tolist(), self.metric, self.cluster_labels, self.num_clusters) #creates clusters if not provided else: if self.separate_rep==True: #mode in this case will always be dense if create_dense_cpp_kernel_in_python == True: self.sijs = np.array(subcp.create_kernel_NS(self.data.tolist(),self.data_rep.tolist(), self.metric)) else: if self.mode == "dense": if self.num_neighbors is not None: raise Exception("num_neighbors wrongly provided for dense mode") #self.num_neighbors = np.shape(self.data)[0] #Using all data as num_neighbors in case of dense mode if create_dense_cpp_kernel_in_python == True: self.sijs = np.array(subcp.create_square_kernel_dense(self.data.tolist(), self.metric)) else: self.cpp_content = np.array(subcp.create_kernel(self.data.tolist(), self.metric, self.num_neighbors)) val = self.cpp_content[0] #TODO: these two lambdas take quite a bit of time, worth optimizing #row = list(map(lambda arg: int(arg), self.cpp_content[1])) #col = list(map(lambda arg: int(arg), self.cpp_content[2])) # row = [int(x) for x in self.cpp_content[1]] # col = [int(x) for x in self.cpp_content[2]] row = list(self.cpp_content[1].astype(int)) col = list(self.cpp_content[2].astype(int)) self.sijs = sparse.csr_matrix((val, (row, col)), [n,n]) else: raise Exception("ERROR: Neither ground set data matrix nor similarity kernel provided") # if self.partial==None: # self.partial = False if separate_rep==None: self.separate_rep = False # if self.partial==False: self.cpp_ground_sub = {-1} #Provide a dummy set for pybind11 binding to be successful #Breaking similarity matrix to simpler native data structures for implicit pybind11 binding if self.mode=="dense" and create_dense_cpp_kernel_in_python == True: if pybind_mode == "list": self.cpp_sijs = self.sijs.tolist() #break numpy ndarray to native list of list datastructure if type(self.cpp_sijs[0])==int or type(self.cpp_sijs[0])==float: #Its critical that we pass a list of list to pybind11 #This condition ensures the same in case of a 1D numpy array (for 1x1 sim matrix) l=[] l.append(self.cpp_sijs) self.cpp_sijs=l ``` -------------------------------- ### FacilityLocationConditionalGain Initialization Logic Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocationConditionalGain.html This code block handles the initialization of the FacilityLocationConditionalGain class. It validates input types and dimensions for similarity kernels (data_sijs, private_sijs) or constructs them from provided data matrices (data, privateData) if kernels are not supplied. It also converts NumPy arrays to lists for pybind11 compatibility. ```python if (type(self.data_sijs) != type(None)) and (type(self.private_sijs) != type(None)): if type(self.data_sijs) != np.ndarray: raise Exception("Invalid data kernel type provided, must be ndarray") if type(self.private_sijs) != np.ndarray: raise Exception("Invalid private kernel type provided, must be ndarray") if np.shape(self.data_sijs)[0]!=self.n or np.shape(self.data_sijs)[1]!=self.n: raise Exception("ERROR: data kernel should be n X n") if np.shape(self.private_sijs)[0]!=self.n or np.shape(self.private_sijs)[1]!=self.num_privates: raise Exception("ERROR: Private Kernel should be n X num_privates") if (type(self.data) != type(None)) or (type(self.privateData) != type(None)): print("WARNING: similarity kernels found. Provided data matrix and query matrix will be ignored.") else: #similarity kernels have not been provided if (type(self.data) == type(None)) or (type(self.privateData) == type(None)): raise Exception("Since kernels are not provided, data matrices are a must") if np.shape(self.data)[0]!=self.n: raise Exception("ERROR: Inconsistentcy between n and no of examples in the given data matrix") if np.shape(self.privateData)[0]!=self.num_privates: raise Exception("ERROR: Inconsistentcy between num_privates and no of examples in the given query data matrix") #construct imageKernel self.num_neighbors = self.n #Using all data as num_neighbors in case of dense mode self.cpp_content = np.array(subcp.create_kernel(self.data.tolist(), self.metric, self.num_neighbors)) val = self.cpp_content[0] row = list(self.cpp_content[1].astype(int)) col = list(self.cpp_content[2].astype(int)) self.data_sijs = np.zeros((self.n,self.n)) self.data_sijs[row,col] = val #construct privateKernel self.private_sijs = np.array(subcp.create_kernel_NS(self.privateData.tolist(),self.data.tolist(), self.metric)) #Breaking similarity matrix to simpler native data structures for implicit pybind11 binding self.cpp_data_sijs = self.data_sijs.tolist() #break numpy ndarray to native list of list datastructure if type(self.cpp_data_sijs[0])==int or type(self.cpp_data_sijs[0])==float: #Its critical that we pass a list of list to pybind11 #This condition ensures the same in case of a 1D numpy array (for 1x1 sim matrix) l=[] l.append(self.cpp_data_sijs) self.cpp_data_sijs=l self.cpp_private_sijs = self.private_sijs.tolist() #break numpy ndarray to native list of list datastructure if type(self.cpp_private_sijs[0])==int or type(self.cpp_private_sijs[0])==float: #Its critical that we pass a list of list to pybind11 #This condition ensures the same in case of a 1D numpy array (for 1x1 sim matrix) l=[] l.append(self.cpp_private_sijs) self.cpp_private_sijs=l self.cpp_obj = FacilityLocationConditionalGain(self.n, self.num_privates, self.cpp_data_sijs, self.cpp_private_sijs, self.privacyHardness) self.effective_ground = set(range(n)) ``` -------------------------------- ### FacilityLocationMutualInformation Initialization Logic Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocationMutualInformation.html This code block outlines the initialization logic for the FacilityLocationMutualInformation class. It includes checks for provided similarity kernels (data_sijs, query_sijs) or data matrices (data, queryData). If kernels are not provided, it constructs them using helper functions. It also handles the conversion of NumPy arrays to lists for pybind11 compatibility and initializes the C++ object. ```python if (type(self.data_sijs) != type(None)) and (type(self.query_sijs) != type(None)): if type(self.data_sijs) != np.ndarray: raise Exception("Invalid data kernel type provided, must be ndarray") if type(self.query_sijs) != np.ndarray: raise Exception("Invalid query kernel type provided, must be ndarray") if np.shape(self.data_sijs)[0]!=self.n or np.shape(self.data_sijs)[1]!=self.n: raise Exception("ERROR: data kernel should be n X n") if np.shape(self.query_sijs)[0]!=self.n or np.shape(self.query_sijs)[1]!=self.num_queries: raise Exception("ERROR: Query Kernel should be n X num_queries") if (type(self.data) != type(None)) or (type(self.queryData) != type(None)): print("WARNING: similarity kernels found. Provided data and query matrices will be ignored.") else: #similarity kernels have not been provided if (type(self.data) == type(None)) or (type(self.queryData) == type(None)): raise Exception("Since kernels are not provided, data matrices are a must") if np.shape(self.data)[0]!=self.n: raise Exception("ERROR: Inconsistentcy between n and no of examples in the given data matrix") if np.shape(self.queryData)[0]!=self.num_queries: raise Exception("ERROR: Inconsistentcy between num_queries and no of examples in the given query data matrix") #construct imageKernel self.num_neighbors = self.n #Using all data as num_neighbors in case of dense mode self.cpp_content = np.array(subcp.create_kernel(self.data.tolist(), self.metric, self.num_neighbors)) val = self.cpp_content[0] row = list(self.cpp_content[1].astype(int)) col = list(self.cpp_content[2].astype(int)) self.data_sijs = np.zeros((self.n,self.n)) self.data_sijs[row,col] = val #construct queryKernel self.query_sijs = np.array(subcp.create_kernel_NS(self.queryData.tolist(),self.data.tolist(), self.metric)) #Breaking similarity matrix to simpler native data structures for implicit pybind11 binding self.cpp_data_sijs = self.data_sijs.tolist() #break numpy ndarray to native list of list datastructure if type(self.cpp_data_sijs[0])==int or type(self.cpp_data_sijs[0])==float: #Its critical that we pass a list of list to pybind11 #This condition ensures the same in case of a 1D numpy array (for 1x1 sim matrix) l=[] l.append(self.cpp_data_sijs) self.cpp_data_sijs=l self.cpp_query_sijs = self.query_sijs.tolist() #break numpy ndarray to native list of list datastructure if type(self.cpp_query_sijs[0])==int or type(self.cpp_query_sijs[0])==float: #Its critical that we pass a list of list to pybind11 #This condition ensures the same in case of a 1D numpy array (for 1x1 sim matrix) l=[] l.append(self.cpp_query_sijs) self.cpp_query_sijs=l self.cpp_obj = FacilityLocationMutualInformation(self.n, self.num_queries, self.cpp_data_sijs, self.cpp_query_sijs, self.magnificationEta) self.effective_ground = set(range(n)) ``` -------------------------------- ### FacilityLocation Initialization with Clustered Data Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocation.html Initializes FacilityLocation with clustered data, processing cluster similarities. ```python l_temp = [] for el in self.cluster_sijs: temp=el.tolist() if type(temp[0])==int or type(temp[0])==float: l=[] l.append(temp) temp=l l_temp.append(temp) self.cluster_sijs = l_temp self.cpp_obj = FacilityLocation(self.n, self.clusters, self.cluster_sijs, self.cluster_map) ``` -------------------------------- ### FacilityLocation Initialization with Array64 Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocation.html Initializes FacilityLocation with float64 NumPy array. Ensures the array is float64. ```python self.sijs.astype('float64', copy=False) self.cpp_obj = FacilityLocation2() self.cpp_obj.pybind_init(self.n, self.sijs, False, {-1}, self.separate_rep) ``` -------------------------------- ### FacilityLocationMutualInformationFunction Initialization Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocationMutualInformation.html Initializes the FacilityLocationMutualInformationFunction with parameters like ground set size, number of queries, and similarity kernels. It includes validation for input parameters. ```python import numpy as np import scipy from .setFunction import SetFunction import submodlib_cpp as subcp from submodlib_cpp import FacilityLocationMutualInformation #from submodlib.helper import create_kernel class FacilityLocationMutualInformationFunction(SetFunction): """Implementation of the Facility Location Mutual Information (FLMI or FL1MI) function. Given a :ref:`functions.submodular-mutual-information` function, Facility Location Mutual Information function is its instantiation using a :class:`~submodlib.functions.facilityLocation.FacilityLocationFunction`. Mathematically, it takes the following form: .. math:: I_f(A; Q) = \sum\limits_{i \in V}\min(\max\limits_{j \in A}s_{ij}, \eta \max\limits_{j \in Q}s_{ij}) .. note:: FL1MI tends to get *saturated*. That is, once the query is satisfied, it doesn't see any gain in picking another query-relevant data point. Also, while GCMI lies at one end of the spectrum favoring query-relevance, FLMI lies at the other end favoring diversity and query coverage over query-relevance. Parameters ---------- n : int Number of elements in the ground set. Must be > 0. num_queries : int Number of query points in the target. data_sijs : numpy.ndarray, optional Similarity kernel between the elements of the ground set. Shape: n X n. When not provided, it is computed using data. query_sijs : numpy.ndarray, optional Similarity kernel between the ground set and the queries. Shape: n X num_queries. When not provided, it is computed using data, queryData and metric. data : numpy.ndarray, optional Matrix of shape n X num_features containing the ground set data elements. data[i] should contain the num-features dimensional features of element i. Mandatory, if either if data_sijs or private_sijs is not provided. Ignored if both data_sijs and private_sijs are provided. queryData : numpy.ndarray, optional Matrix of shape num_queries X num_features containing the query elements. queryData[i] should contain the num-features dimensional features of query i. It is optional (and is ignored if provided) if query_sijs has been provided. metric : str, optional Similarity metric to be used for computing the similarity kernels. Can be "cosine" for cosine similarity or "euclidean" for similarity based on euclidean distance. Default is "cosine". magnificationEta : float, optional The value of the query-relevance vs diversity trade-off. Increasing :math:`\eta` tends to increase query-relevance while reducing query-coverage and diversity. Default is 1. """ def __init__(self, n, num_queries, data_sijs=None, query_sijs=None, data=None, queryData=None, metric="cosine", magnificationEta=1): self.n = n self.num_queries = num_queries self.metric = metric self.data_sijs = data_sijs self.query_sijs = query_sijs self.data = data self.queryData = queryData self.magnificationEta=magnificationEta self.cpp_obj = None self.cpp_data_sijs = None self.cpp_query_sijs = None self.cpp_content = None self.effective_ground = None if self.n <= 0: raise Exception("ERROR: Number of elements in ground set must be positive") if self.num_queries < 0: raise Exception("ERROR: Number of queries must be >= 0") # if self.metric not in ['euclidean', 'cosine']: # raise Exception("ERROR: Unsupported metric. Must be 'euclidean' or 'cosine'") ``` -------------------------------- ### Initialize GraphCutMutualInformationFunction Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/graphCutMutualInformation.html Initializes the GraphCutMutualInformationFunction. It requires the number of elements in the ground set (n) and the number of queries. Optionally, a pre-computed similarity kernel (query_sijs) can be provided. If not, data and queryData matrices along with a metric (e.g., 'cosine', 'euclidean') must be supplied to compute the kernel. Input validation is performed for dimensions and types. ```python def __init__(self, n, num_queries, query_sijs=None, data=None, queryData=None, metric="cosine"): self.n = n self.num_queries = num_queries self.metric = metric self.query_sijs = query_sijs self.data = data self.queryData = queryData self.cpp_obj = None self.cpp_query_sijs = None self.cpp_content = None self.effective_ground = None if self.n <= 0: raise Exception("ERROR: Number of elements in ground set must be positive") if self.num_queries < 0: raise Exception("ERROR: Number of queries must be >= 0") # if self.metric not in ['euclidean', 'cosine']: # raise Exception("ERROR: Unsupported metric. Must be 'euclidean' or 'cosine'") if type(self.query_sijs) != type(None): # User has provided query kernel if type(self.query_sijs) != np.ndarray: raise Exception("Invalid query kernel type provided, must be ndarray") if np.shape(self.query_sijs)[0]!=self.n or np.shape(self.query_sijs)[1]!=self.num_queries: raise Exception("ERROR: Query Kernel should be n X num_queries") if (type(self.data) != type(None)) or (type(self.queryData) != type(None)): print("WARNING: similarity query kernel found. Provided data and query matrices will be ignored.") else: #similarity query kernel has not been provided if (type(self.data) == type(None)) or (type(self.queryData) == type(None)): raise Exception("Since query kernel is not provided, data matrices are a must") if np.shape(self.data)[0]!=self.n: raise Exception("ERROR: Inconsistentcy between n and no of examples in the given data matrix") if np.shape(self.queryData)[0]!=self.num_queries: raise Exception("ERROR: Inconsistentcy between num_queries and no of examples in the given query data matrix") #construct queryKernel self.query_sijs = np.array(subcp.create_kernel_NS(self.queryData.tolist(),self.data.tolist(), self.metric)) #Breaking similarity matrix to simpler native data structures for implicit pybind11 binding self.cpp_query_sijs = self.query_sijs.tolist() #break numpy ndarray to native list of list datastructure if type(self.cpp_query_sijs[0])==int or type(self.cpp_query_sijs[0])==float: #Its critical that we pass a list of list to pybind11 #This condition ensures the same in case of a 1D numpy array (for 1x1 sim matrix) l=[] l.append(self.cpp_query_sijs) self.cpp_query_sijs=l self.cpp_obj = GraphCutMutualInformation(self.n, self.num_queries, self.cpp_query_sijs) self.effective_ground = set(range(n)) ``` -------------------------------- ### FacilityLocation Initialization with Generic Array Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocation.html Initializes FacilityLocation with a generic NumPy array. ```python self.cpp_obj = FacilityLocation2() self.cpp_obj.pybind_init(self.n, self.sijs, False, {-1}, self.separate_rep) ``` -------------------------------- ### GraphCutConditionalGain Initialization Logic Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/graphCutConditionalGain.html This code block handles the initialization of the GraphCutConditionalGain class. It checks for the presence of user-provided similarity kernels (data_sijs and private_sijs) or constructs them from input data matrices (data and privateData) using C++ helper functions. It also performs essential data validation and converts NumPy arrays to Python lists for C++ binding. ```python if (type(self.data_sijs) != type(None)) and (type(self.private_sijs) != type(None)): if type(self.data_sijs) != np.ndarray: raise Exception("Invalid data kernel type provided, must be ndarray") if type(self.private_sijs) != np.ndarray: raise Exception("Invalid query kernel type provided, must be ndarray") if np.shape(self.data_sijs)[0]!=self.n or np.shape(self.data_sijs)[1]!=self.n: raise Exception("ERROR: data kernel should be n X n") if np.shape(self.private_sijs)[0]!=self.n or np.shape(self.private_sijs)[1]!=self.num_privates: raise Exception("ERROR: Query Kernel should be n X num_privates") if (type(self.data) != type(None)) or (type(self.privateData) != type(None)): print("WARNING: similarity kernels found. Provided data and query matrices will be ignored.") else: if (type(self.data) == type(None)) or (type(self.privateData) == type(None)): raise Exception("Since kernels are not provided, data matrices are a must") if np.shape(self.data)[0]!=self.n: raise Exception("ERROR: Inconsistentcy between n and no of examples in the given data matrix") if np.shape(self.privateData)[0]!=self.num_privates: raise Exception("ERROR: Inconsistentcy between num_privates and no of examples in the given query data matrix") self.num_neighbors = self.n self.cpp_content = np.array(subcp.create_kernel(self.data.tolist(), self.metric, self.num_neighbors)) val = self.cpp_content[0] row = list(self.cpp_content[1].astype(int)) col = list(self.cpp_content[2].astype(int)) self.data_sijs = np.zeros((self.n,self.n)) self.data_sijs[row,col] = val self.private_sijs = np.array(subcp.create_kernel_NS(self.privateData.tolist(),self.data.tolist(), self.metric)) self.cpp_data_sijs = self.data_sijs.tolist() if type(self.cpp_data_sijs[0])==int or type(self.cpp_data_sijs[0])==float: l=[] l.append(self.cpp_data_sijs) self.cpp_data_sijs=l self.cpp_private_sijs = self.private_sijs.tolist() if type(self.cpp_private_sijs[0])==int or type(self.cpp_private_sijs[0])==float: l=[] l.append(self.cpp_private_sijs) self.cpp_private_sijs=l self.cpp_obj = GraphCutConditionalGain(self.n, self.num_privates, self.cpp_data_sijs, self.cpp_private_sijs, self.privacyHardness, self.lambdaVal) self.effective_ground = set(range(n)) ``` -------------------------------- ### FacilityLocation Class Initialization Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocation.html Initializes the FacilityLocation class with parameters for ground set size, mode, and optional representations. It includes validation for input parameters such as mode, metric, and cluster configurations. ```python def __init__(self, n, mode, separate_rep=None, n_rep=None, sijs=None, data=None, data_rep=None, num_clusters=None, cluster_labels=None, metric="cosine", num_neighbors=None, create_dense_cpp_kernel_in_python=True, pybind_mode="array"): self.n = n self.n_rep = n_rep self.mode = mode self.metric = metric self.sijs = sijs self.data = data self.data_rep=data_rep self.num_neighbors = num_neighbors #self.partial = partial #self.ground_sub = ground_sub self.separate_rep=separate_rep self.clusters=None self.cluster_sijs=None self.cluster_map=None self.cluster_labels=cluster_labels self.num_clusters=num_clusters self.cpp_obj = None self.cpp_sijs = None self.cpp_ground_sub = None self.cpp_content = None self.effective_ground = None if self.n <= 0: raise Exception("ERROR: Number of elements in ground set must be positive") # if self.partial==True: # if type(self.ground_sub) == type(None) or len(self.ground_sub) == 0: # raise Exception("ERROR: Restricted subset of ground set not specified or empty for partial mode") # if self.mode == "clustered" or mode == "sparse": # raise Exception("clustered or sparse mode not supported if partial = True") # if not all(ele >= 0 and ele <= self.n-1 for ele in self.ground_sub): # raise Exception("Restricted subset of ground set contains invalid values") # if self.separate_rep == True: # raise Exception("Partial not supported if separate_rep = True") if self.mode not in ['dense', 'sparse', 'clustered']: raise Exception("ERROR: Incorrect mode. Must be one of 'dense', 'sparse' or 'clustered'") # if self.metric not in ['euclidean', 'cosine']: # raise Exception("ERROR: Unsupported metric. Must be 'euclidean' or 'cosine'") if self.separate_rep == True: if self.n_rep is None or self.n_rep <=0: raise Exception("ERROR: separate represented intended but number of elements in represented not specified or not positive") if self.mode != "dense": raise Exception("Only dense mode supported if separate_rep = True") if self.mode == "clustered": if type(self.cluster_labels) != type(None) and (self.num_clusters is None or self.num_clusters <= 0): raise Exception("ERROR: Positive number of clusters must be provided in clustered mode when cluster_labels is provided") # if self.cluster_labels is None or len(cluster_labels) != self.n: # raise Exception("ERROR: Cluster ID/label for each element in the ground set is needed") if type(self.cluster_labels) == type(None) and self.num_clusters is not None and self.num_clusters <= 0: raise Exception("Invalid number of clusters provided") if type(self.cluster_labels) != type(None) and len(self.cluster_labels) != self.n: raise Exception("ERROR: cluster_labels's size is NOT same as ground set size") if type(self.cluster_labels) != type(None) and not all(ele >= 0 and ele <= self.num_clusters-1 for ele in self.cluster_labels): raise Exception("Cluster IDs/labels contain invalid values") ``` -------------------------------- ### Initialize ConcaveOverModularFunction with default parameters Source: https://submodlib.readthedocs.io/en/latest/functions/concaveOverModular.html Instantiate the ConcaveOverModularFunction with the number of ground set elements and number of queries. Other parameters like similarity kernel, data, and metric can be provided or will be computed by default. ```python from submodlib.functions.concaveOverModular import ConcaveOverModularFunction # Example with default parameters com_function = ConcaveOverModularFunction(n=10, num_queries=5) ``` -------------------------------- ### Initialize ConcaveOverModular with Query Kernel Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/concaveOverModular.html Handles initialization when a query similarity kernel is provided. It validates the kernel's type and dimensions, and warns if data matrices are also supplied as they will be ignored. If the kernel is not a numpy ndarray, it raises an exception. ```python if type(self.query_sijs) != type(None): # User has provided query kernel if type(self.query_sijs) != np.ndarray: raise Exception("Invalid query kernel type provided, must be ndarray") if np.shape(self.query_sijs)[0]!=self.n or np.shape(self.query_sijs)[1]!=self.num_queries: raise Exception("ERROR: Query Kernel should be n X num_queries") if (type(self.data) != type(None)) or (type(self.queryData) != type(None)): print("WARNING: similarity query kernel found. Provided data and query matrices will be ignored.") ``` -------------------------------- ### LogDeterminantConditionalGainFunction Initialization Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/logDeterminantConditionalGain.html Initializes the LogDeterminantConditionalGainFunction. It requires the number of elements in the ground set, the number of private instances, and a lambda value. Optional parameters include pre-computed similarity kernels or data for kernel computation, the similarity metric, and the privacy hardness parameter. ```python import numpy as np import scipy from .setFunction import SetFunction import submodlib_cpp as subcp from submodlib_cpp import LogDeterminantConditionalGain from submodlib.helper import create_kernel class LogDeterminantConditionalGainFunction(SetFunction): """Implementation of the Log Determinant Conditional Gain (LogDetCG) function. Given a :ref:`functions.conditional-gain` function, Log Determinantn Conditional Gain function is its instantiation using a :class:`~submodlib.functions.logDeterminant.LogDeterminantFunction`. Let :math:`S_{A, B}` be the cross-similarity matrix between the items in sets :math:`A` and :math:`B`. Also, denote :math:`S_{AB} = S_{A \cup B}`. We construct a similarity matrix :math:`S^{\nu}` (on a base matrix :math:`S`) in such a way that the cross-similarity between :math:`A` and :math:`P` is multiplied by :math:`\nu` (i.e :math:`S^{\nu}_{A,P} = \nu S_{A,P}`) to control the hardness of enforcing privacy constraints. Higher values of :math:`\nu` ensure stricter privacy constraints, such as in the context of privacy-preserving summarization, i.e., tightening the extent of dissimilarity of the subset from the private set. Using a similarity matrix defined above and with :math:`f(A) = \log\det(S^{\nu}_{A})`, we have: .. math:: f(A | P ) = \log\det(S_{A} - \nu^2 S_{A, P}S_{P}^{-1}S_{A, P}^T) Increasing :math:`\nu` increases the privacy-irrelevance score, thereby ensuring a stricter privacy-irrelevance constraint. .. note:: LogDetCG outperforms FLCG and GCCG both in terms of diversity and privacy-irrelevance. Parameters ---------- n : int Number of elements in the ground set. Must be > 0. num_privates : int Number of private instances in the target. lambdaVal : float Addition to :math:`s_{ii} (1)` so that :math:`\log` doesn't become 0 data_sijs : numpy.ndarray, optional Similarity kernel between the elements of the ground set. Shape: n X n. When not provided, it is computed using data. private_sijs : numpy.ndarray, optional Similarity kernel between the ground set and the private instances. Shape: n X num_privates. When not provided, it is computed using data and privateData. private_private_sijs : numpy.ndarray, optional Similarity kernel between the private instances. Shape: num_privates X num_privates. When not provided, it is computed using privateData. data : numpy.ndarray, optional Matrix of shape n X num_features containing the ground set data elements. data[i] should contain the num-features dimensional features of element i. Mandatory, if either if data_sijs or private_sijs is not provided. Ignored if both data_sijs and private_sijs are provided. privateData : numpy.ndarray, optional Matrix of shape num_privates X num_features containing the private instances. privateData[i] should contain the num-features dimensional features of private instance i. Must be provided if private_sijs is not provided. Ignored if both data_sijs and private_sijs are provided. metric : str, optional Similarity metric to be used for computing the similarity kernels. Can be "cosine" for cosine similarity or "euclidean" for similarity based on euclidean distance. Default is "cosine". privacyHardness : float, optional Parameter that governs the hardness of the privacy constraint. Default is 1. """ def __init__(self, n, num_privates, lambdaVal, data_sijs=None, private_sijs=None, private_private_sijs=None, data=None, privateData=None, metric="cosine", privacyHardness=1): self.n = n self.num_privates = num_privates self.lambdaVal=lambdaVal self.metric = metric self.privacyHardness=privacyHardness self.data_sijs = data_sijs self.private_sijs = private_sijs self.private_private_sijs = private_private_sijs self.data = data self.privateData = privateData self.cpp_obj = None self.cpp_data_sijs = None self.cpp_private_sijs = None self.cpp_private_private_sijs = None self.cpp_content = None self.cpp_content2 = None self.effective_ground = None if self.n <= 0: raise Exception("ERROR: Number of elements in ground set must be positive") if self.num_privates < 0: raise Exception("ERROR: Number of queries must be >= 0") # if self.metric not in ['euclidean', 'cosine']: # raise Exception("ERROR: Unsupported metric. Must be 'euclidean' or 'cosine'") ``` -------------------------------- ### FacilityLocation Initialization with Array32 Source: https://submodlib.readthedocs.io/en/latest/_modules/submodlib/functions/facilityLocation.html Initializes FacilityLocation with float32 NumPy array. Ensures the array is float32. ```python self.sijs.astype('float32', copy=False) self.cpp_obj = FacilityLocation2() self.cpp_obj.pybind_init(self.n, self.sijs, False, {-1}, self.separate_rep) ```