def _sample_row(self): """Generate a single sampled row from vine model. Returns: numpy.ndarray """ unis = np.random.uniform(0, 1, self.n_var) # randomly select a node to start with first_ind = np.random.randint(0, self.n_var) adj = self.trees[0].get_adjacent_matrix() visited = [] explore = [first_ind] sampled = np.zeros(self.n_var) itr = 0 while explore: current = explore.pop(0) neighbors = np.where(adj[current, :] == 1)[0].tolist() if itr == 0: new_x = self.ppfs[current](unis[current]) else: for i in range(itr - 1, -1, -1): current_ind = -1 if i >= self.truncated: continue current_tree = self.trees[i].edges # get index of edge to retrieve for edge in current_tree: if i == 0: if (edge.L == current and edge.R == visited[0]) or\ (edge.R == current and edge.L == visited[0]): current_ind = edge.index break else: if edge.L == current or edge.R == current: condition = set(edge.D) condition.add(edge.L) condition.add(edge.R) visit_set = set(visited) visit_set.add(current) if condition.issubset(visit_set): current_ind = edge.index break if current_ind != -1: # the node is not indepedent contional on visited node copula_type = current_tree[current_ind].name copula = Bivariate( copula_type=CopulaTypes(copula_type)) copula.theta = current_tree[current_ind].theta U = np.array([unis[visited[0]]]) if i == itr - 1: tmp = copula.percent_point( np.array([unis[current]]), U)[0] else: tmp = copula.percent_point(np.array([tmp]), U)[0] tmp = min(max(tmp, EPSILON), 0.99) new_x = self.ppfs[current](np.array([tmp])) sampled[current] = new_x for s in neighbors: if s not in visited: explore.insert(0, s) itr += 1 visited.insert(0, current) return sampled
def sample(self, num_rows=1, seed=None): """Generating samples from vine model.""" s1 = np.random.get_state() s2 = random.getstate() np.random.seed(seed) random.setstate(seed) unis = np.random.uniform(0, 1, self.n_var) # randomly select a node to start with first_ind = random.randint(0, self.n_var - 1) np.random.seed(s1) random.setstate(s2) adj = self.trees[0].get_adjacent_matrix() visited = [] explore = [first_ind] sampled = np.zeros(self.n_var) itr = 0 while explore: current = explore.pop(0) neighbors = np.where(adj[current, :] == 1)[0].tolist() if itr == 0: new_x = self.ppfs[current](unis[current]) else: for i in range(itr - 1, -1, -1): current_ind = -1 if i >= self.truncated: continue current_tree = self.trees[i].edges # get index of edge to retrieve for edge in current_tree: if i == 0: if (edge.L == current and edge.R == visited[0]) or\ (edge.R == current and edge.L == visited[0]): current_ind = edge.index break else: if edge.L == current or edge.R == current: condition = set(edge.D) condition.add(edge.L) condition.add(edge.R) visit_set = set(visited).add(current) if condition.issubset(visit_set): current_ind = edge.index break if current_ind != -1: # the node is not indepedent contional on visited node copula_type = current_tree[current_ind].name copula_para = current_tree[current_ind].param cop = Bivariate(CopulaTypes(copula_type)) derivative = cop.get_h_function() # start with last level if i == itr - 1: tmp = optimize.fminbound(derivative, EPSILON, 1.0, args=(unis[visited[0]], copula_para, unis[current])) else: tmp = optimize.fminbound(derivative, EPSILON, 1.0, args=(unis[visited[0]], copula_para, tmp)) tmp = min(max(tmp, EPSILON), 0.99) new_x = self.ppfs[current](tmp) sampled[current] = new_x for s in neighbors: if s not in visited: explore.insert(0, s) itr += 1 visited.insert(0, current) return sampled