def solve(w, reputations, granularity=10000): # infer number of bidders n = reputations.size # compute an array of lower and upper extremities lowers = np.empty(n, dtype=np.float) uppers = np.empty(n, dtype=np.float) for i in np.arange(n): lowers[i] = (1-w) * reputations[i] uppers[i] = (1-w) * reputations[i] + w # estimate the upper bound on bids b_upper = upper_bound_bids(lowers, uppers) # set initial conditions for the FSM algorithm low = lowers[1] high = b_upper epsilon = 1e-6 num = granularity cond1 = np.empty(num, dtype=np.bool) cond2 = np.empty(num, dtype=np.bool) cond3 = np.empty(num-1, dtype=np.bool) # run the FSM algorithm until the estimate of the lower bound # on bids is found while high - low > epsilon: guess = 0.5 * (low + high) bids = np.linspace(guess, b_upper, num=num, endpoint=False) try: costs = fsm_internal.solve(lowers, uppers, bids).T except Exception: # if an error is raised, set low to guess and continue low = guess continue for i in np.arange(n): for j in np.arange(num): x = costs[i][j] cond1[j] = lowers[i] <= x and x <= b_upper cond2[j] = bids[j] > x for i in np.arange(1, num): cond3[i-1] = bids[i-1] < bids[i] if np.all(cond1) and np.all(cond2) and np.all(cond3): high = guess else: low = guess try: return bids, costs except UnboundLocalError: raise Exception("Algorithm failed to converge.")
def estimate_param(w, reputations): # get number of bidders n = reputations.size # estimate lower and upper extremities lower_extremities = np.array([(1-w)*r for r in reputations]) upper_extremities = np.array([(1-w)*r + w for r in reputations]) # estimate upper bound on bids b_upper = upper_bound_bids(lower_extremities, upper_extremities) # approximate param = 1e-6 while True: if param > 1e-4: return None try: bids, costs = solve(w, reputations, param=param) except Exception: param += 1e-6 continue # verify sufficiency cdfs = [] for l,u in zip(lower_extremities, upper_extremities): cdfs.append(stats.uniform(loc=l, scale=u-l)) step = len(bids) // 35 sampled_bids, best_responses = best_responses(costs, bids, b_upper, cdfs, step=step) # calculate average error errors = [] m = sampled_bids.shape[1] for i in range(n): error = 0 for b,br in zip(sampled_bids[i], best_responses[i]): error += abs(b-br) errors.append(error / m) # Check if average is low for each bidder if all([e < 1e-2 for e in errors]): break # Update param param += 1e-6 return param
def solve(w, reputations): # infer number of bidders n = reputations.size # compute an array of lower and upper extremities lowers = np.empty(n, dtype=np.float) uppers = np.empty(n, dtype=np.float) for i in np.arange(n): r = reputations[i] lowers[i] = (1-w) * r uppers[i] = (1-w) * r + w # estimate the upper bound on bids b_upper = upper_bound_bids(lowers, uppers) # set initial conditions for the PPM algorithm k = 3 K = 8 poly_coeffs = [[1e-1 for i in range(k)] for j in range(n)] b_lower = lowers[1] + 1e-3 size_box = [1e-1 for i in range(k*n + 1)] # run the PPM algorithm until k >= K while True: b_lower, poly_coeffs = ppm_internal.solve(b_lower, b_upper, lowers, uppers, poly_coeffs, size_box=size_box, granularity=100) if k >= K: break # extend polynomial coefficients by one element # for each bidder for i in range(n): poly_coeffs[i].append(1e-6) # update k k += 1 # update size box size_box = [1e-2 for i in range(n*k + 1)] return b_lower, b_upper, poly_coeffs
def solve(w, reputations): # infer number of bidders n = reputations.size # compute an array of lower and upper extremities lowers = np.empty(n, dtype=np.float) uppers = np.empty(n, dtype=np.float) for i in np.arange(n): r = reputations[i] lowers[i] = (1-w) * r uppers[i] = (1-w) * r + w # estimate the upper bound on bids b_upper = upper_bound_bids(lowers, uppers) # solve the system using EFSM method bids, costs = efsm.solve(w, reputations) # truncate solution derived by EFSM where k=n min_i = np.argmin(np.absolute(np.copy(costs[-1]) - lowers[-1])) initial = costs.T[min_i,:] b_lower = bids[min_i] length = bids.size - min_i bids = bids[:min_i] costs = costs[:,:min_i] # solve the system for k = n using PPM method coeffs = ppm.fit(initial, uppers, b_lower, b_upper) bids_ = np.linspace(b_lower, b_upper, length) def cost_func(lower, cs, b): sums = sum([c*(b - b_lower)**i for c,i in zip(cs, range(1, len(cs)+1))]) return lower + sums cost_funcs = [partial(cost_func, l, cs) for l,cs in zip(initial, coeffs)] costs_ = np.array([[f(b) for b in bids_] for f in cost_funcs]) # combine results from both methods bids = np.append(bids, bids_) costs = np.hstack((costs, costs_)) return bids, costs
f_reader = csv.DictReader(f, delimiter=' ') for row in f_reader: for key in row: data_in[key] = row[key] # Parse data common to FSM and PPM methods w = ast.literal_eval(data_in['w']) reps = ast.literal_eval(data_in['reps']) n = len(reps) # Estimate cost support bounds lower_extremities = np.array([(1-w)*r for r in reps]) upper_extremities = np.array([(1-w)*r + w for r in reps]) # Estimate upper bound on bids b_upper = upper_bound_bids(lower_extremities, upper_extremities) # Parse the rest of the data try: bids = np.array(ast.literal_eval(data_in['bids'])) costs = np.array([ast.literal_eval(data_in['costs_{}'.format(i)]) for i in range(n)]) except KeyError: bs = [ast.literal_eval(data_in['b_lower']), ast.literal_eval(data_in['b_upper'])] css = [ast.literal_eval(data_in['cs_{}'.format(i)]) for i in range(n)] # Verify sufficiency cdfs = [] for bounds in zip(lower_extremities, upper_extremities): cdfs.append(ss.uniform(loc=bounds[0], scale=bounds[1]-bounds[0]))
def solve(w, reputations, granularity=10000, param=1e-6): # infer number of bidders n = reputations.size # compute an array of lower and upper extremities lowers = np.empty(n, dtype=np.float) uppers = np.empty(n, dtype=np.float) for i in np.arange(n): lowers[i] = (1-w) * reputations[i] uppers[i] = (1-w) * reputations[i] + w # estimate the upper bound on bids b_upper = upper_bound_bids(lowers, uppers) # set initial conditions for the FSM algorithm low = lowers[1] high = b_upper epsilon = 1e-6 num = granularity cond1 = np.empty(num, dtype=np.bool) cond2 = np.empty(num, dtype=np.bool) cond3 = np.empty(num-1, dtype=np.bool) # run the FSM algorithm until the estimate of the lower bound # on bids is found while high - low > epsilon: guess = 0.5 * (low + high) bids = np.linspace(guess, b_upper-param, num=num, endpoint=False) # solve the system try: #print("guess=%f, b_upper=%f" % (guess, b_upper-param)) costs = efsm_internal.solve(lowers, uppers, bids).T except Exception: if param >= 1e-3: raise Exception("Exceeded maximum iteration limit.") param += 1e-6 continue # modify array of lower extremities to account for the bidding # extension initial = costs[0,:] for i in np.arange(n): for j in np.arange(num): x = costs[i][j] cond1[j] = initial[i] <= x and x <= b_upper cond2[j] = bids[j] > x for i in np.arange(1, num): cond3[i-1] = bids[i-1] < bids[i] if np.all(cond1) and np.all(cond2) and np.all(cond3): high = guess else: low = guess try: # print("Param=%f" % param) return bids, costs except UnboundLocalError: raise Exception("Algorithm failed to converge.")