def evaluate_contfrac(ab, accuracy, convergence_info): cont_frac = cont_fracs.ContFrac(a_coeffs=ab[0], b_coeffs=ab[1]) if convergence_info: cont_frac.set_approach_type_and_params(convergence_info) # cont_frac.reinitialize(a_coeffs=ab[0], b_coeffs=ab[1]) # This is a horrible hack, slowing down EVERYTHING. As a first step, this should be replaced by a small # correction to the convergence parameters. Maybe taking the upper/lower bound of confidence from the # fitting results. # TODO: fix accoridng to the above comment. cont_frac.gen_iterations(num_of_iterations, dec('1E-%d' % (accuracy + 100))) return cont_frac.get_result()
def polys_generator(self, range_a, range_b, prec=None): """Generates the polynomials from range_a and range_b. Parameters: range_a - for example: [ [[], []], [[], [], []], [[], [], [], []], [[], []] ] is a 4-interlace with degrees of 2,3,4,2 . [m n] means running on coefficients between m to n-1. range_b - as range_a. prec - ignored. Left for compatiblity with the _len_decorator decoration. Returns: yields pairs for (a_poly, b_poly), each of them is a list of polynomials (for interlace).""" # Create an instance. To improve runtime, this method will be reinitialized over and over instead of creating. # new instances every so often. cont_frac = cont_fracs.ContFrac([1], [1], avoid_zero_b=self._avoid_zero_b) # TODO: delete the following line. It left as a documentation backup until everything works. # cont_frac = cont_fracs.ContFrac([1]*range_a, [0]*range_b, avoid_zero_b=self._avoid_zero_b) # Catersian product of all the possibilities of a. a_params_iterator = itertools.product(*[ itertools.product(*[ range(*r) for r in ra ]) for ra in range_a ]) for pas_premanipulate in a_params_iterator: # In more complex cases, manipulated versions of the a polynomial may be wished. # Create a generator for this manipulated versions. pas_manipulated_gen = self.manipulate_poly(pas_premanipulate, 'a') for pas in pas_manipulated_gen: # Cartesian product of b. b_params_iterator = itertools.product(*[ itertools.product(*[ range(*r) for r in rb ]) for rb in range_b ]) for pbs_premanipulate in b_params_iterator: # Manipulated versions for b. pbs_manipulated_gen = self.manipulate_poly(pbs_premanipulate, 'b') for pbs in pbs_manipulated_gen: # Check for integers roots of b polynomials and avoid if required. if self._avoid_int_roots and any([self._does_have_int_positive_roots(pb) for pb in pbs]): continue # in the case of an interlace in which all the interlace-polynomials are identical, # squeeze it to a single polynomial with no interlace if len(pas) > 1 and all([ pas[0] == p for p in pas ]): pas = (pas[0],) if len(pbs) > 1 and all([ pbs[0] == p for p in pbs ]): pbs = (pbs[0],) # if no interlace and only exponential convergence contfracs should be enumerated, make sure # that 2*deg(a) >= deg(b) if len(pas) == 1 and len(pbs) == 1 and self._enum_only_exp_conv and \ self._polynom_degree(pbs[0]) > 2 * self._polynom_degree(pas[0]): continue # generate contfrac and return everything / return the polynomials if self._should_gen_contfrac: cont_frac.reinitialize(pas, pbs) try: cont_frac.gen_iterations(self.num_of_iterations) except cont_fracs.ZeroB: continue yield (cont_frac, pas, pbs) else: yield (pas, pbs)
def build_contfrac_from_params(self, params, iterations=400): """Builds a continued fraction, post-processed value and an LHS object from params. params - (ab, lhs_res_obj, post_func_ind, convergence_info) ab - [a_poly, b_poly] where a_poly/b_poly is of the format [poly1, poly2, ...] for these polynomials to be used as an interlace, and poly1/2/... is of the format [c0, c1, c2, ...] <=> c0+c1*x+c2*x^2+... lhs_res_obj - an LHS object post_func_ind - index of a postproc func in postproc_funcs list to be use. convergence_info - convergence info produced by the original contfrac object. UNUSED. Returns: (cont_frac, postproc_func(cont_frac_value), lhs_res_obj) """ ab, lhs_res_obj, post_func_ind, convergence_info = params pa, pb = ab cont_frac = cont_fracs.ContFrac(a_coeffs=pa, b_coeffs=pb) cont_frac.gen_iterations(iterations) return cont_frac, self.postproc_funcs[post_func_ind]( cont_frac.get_result()), lhs_res_obj
def filter_only_exp_convergence(self, print_surprising_nonexp_contfracs=False): """Filters out only contfracs that converge (at least) exponentially. Parameters: print_surprising_nonexp_contfracs - True for printing contfracs that DO NO converge exponentially.""" # TODO: add either here or in filter_clicks_by_approach_type the discriminant test for exp. convergence params_list = self.filtered_params filtered_params_list = [] for cf_params in progressbar.progressbar(params_list): ab, lhs_res_obj, post_func_ind, convergence_info = cf_params cont_frac = cont_fracs.ContFrac(a_coeffs=ab[0], b_coeffs=ab[1]) if cont_frac.is_convergence_fast(): filtered_params_list.append(cf_params) elif print_surprising_nonexp_contfracs: print( 'Surprising non-exponential convergence continuous fraction:' ) print(cf_params) cont_frac.estimate_approach_type_and_params() print(cont_frac.get_approach_type_and_params()) self.filtered_params = filtered_params_list
def filter_clicks_by_approach_type( self, whitelist=['exp', 'super_exp', 'fast'], blacklist=None): # , filter_uniq_list=True): """Filters only clicks withe convergence from the whitelist, or drops clicks with convergence from the black list. One of whitelist/black is required, and one only. See help for ContFrac._estimate_approach_type_and_params_inner_alg for more info about convergence types.""" if not any([whitelist, blacklist]): raise ValueError('One is required: whitelist, blacklist') if whitelist and blacklist: raise ValueError('Only one is possible: whitelist, blacklist') params_list = self.filtered_params filtered_params_list = [] for cf_params in progressbar.progressbar(params_list): ab, lhs_res_obj, post_func_ind, convergence_info = cf_params cont_frac = cont_fracs.ContFrac(a_coeffs=ab[0], b_coeffs=ab[1]) try: cont_frac.estimate_approach_type_and_params() approach_type, approach_params = cont_frac.get_approach_type_and_params( ) except Exception as e: print( 'Problems while estimating the following cf_params in "filter_clicks_by_approach_type"' ) print('Exception has occurred. Skipping.') print(cf_params) print(e) continue if (whitelist and approach_type in whitelist) or ( blacklist and approach_type not in blacklist): cf_params = (ab, lhs_res_obj, post_func_ind, (approach_type, approach_params)) filtered_params_list.append(cf_params) self.filtered_params = filtered_params_list
def cf(): return cont_fracs.ContFrac([[1]], [[1]])