def __init__(self, init_object=None): """ Polynomial initialization function init_object can be one of - list of coefficient - dict of index, coefficient - SollyaObject (sollya polynomial) """ self.degree = None self.coeff_map = {} self.sollya_object = None if isinstance(init_object, list): self.degree = len(init_object) for index, coeff_value in enumerate(init_object): self.coeff_map[index] = coeff_value elif isinstance(init_object, dict): self.degree = 0 for index in init_object: self.degree = self.degree if index <= self.degree else index self.coeff_map[index] = init_object[index] elif isinstance(init_object, SollyaObject): self.degree = int(sollya.degree(init_object)) for index in range(int(self.degree) + 1): coeff_value = coeff(init_object, index) if coeff_value != 0: self.coeff_map[index] = coeff_value self.sollya_object = 0 # building sollya object for index in self.coeff_map: self.sollya_object += self.coeff_map[index] * sollya.x**index
def generate_scheme(self): #func_implementation = CodeFunction(self.function_name, output_format = self.precision) vx = self.implementation.add_input_variable("x", self.get_input_precision()) sollya_precision = self.get_sollya_precision() # retrieving processor inverse approximation table #dummy_var = Variable("dummy", precision = self.precision) #dummy_div_seed = DivisionSeed(dummy_var, precision = self.precision) #inv_approx_table = self.processor.get_recursive_implementation(dummy_div_seed, language = None, table_getter = lambda self: self.approx_table_map) lo_bound_global = SollyaObject(0.0) hi_bound_global = SollyaObject(0.75) approx_interval = Interval(lo_bound_global, hi_bound_global) approx_interval_size = hi_bound_global - lo_bound_global # table creation table_index_size = 7 field_index_size = 2 exp_index_size = table_index_size - field_index_size table_size = 2**table_index_size table_index_range = range(table_size) local_degree = 9 coeff_table = ML_Table(dimensions = [table_size, local_degree], storage_precision = self.precision) #local_interval_size = approx_interval_size / SollyaObject(table_size) #for i in table_index_range: # degree = 6 # lo_bound = lo_bound_global + i * local_interval_size # hi_bound = lo_bound_global + (i+1) * local_interval_size # approx_interval = Interval(lo_bound, hi_bound) # local_poly_object, local_error = Polynomial.build_from_approximation_with_error(acos(x), degree, [self.precision] * (degree+1), approx_interval, absolute) # local_error = int(log2(sup(abs(local_error / acos(approx_interval))))) # print approx_interval, local_error exp_lo = 2**exp_index_size for i in table_index_range: lo_bound = (1.0 + (i % 2**field_index_size) * S2**-field_index_size) * S2**(i / 2**field_index_size - exp_lo) hi_bound = (1.0 + ((i % 2**field_index_size) + 1) * S2**-field_index_size) * S2**(i / 2**field_index_size - exp_lo) local_approx_interval = Interval(lo_bound, hi_bound) local_poly_object, local_error = Polynomial.build_from_approximation_with_error(acos(1 - x), local_degree, [self.precision] * (local_degree+1), local_approx_interval, sollya.absolute) local_error = int(log2(sup(abs(local_error / acos(1 - local_approx_interval))))) coeff_table print local_approx_interval, local_error for d in xrange(local_degree): coeff_table[i][d] = sollya.coeff(local_poly_object.get_sollya_object(), d) table_index = BitLogicRightShift(vx, vx.get_precision().get_field_size() - field_index_size) - (exp_lo << field_index_size) print "building mathematical polynomial" poly_degree = sup(sollya.guessdegree(acos(x), approx_interval, S2**-(self.precision.get_field_size()))) print "guessed polynomial degree: ", int(poly_degree) #global_poly_object = Polynomial.build_from_approximation(log10(1+x)/x, poly_degree, [self.precision]*(poly_degree+1), approx_interval, absolute) print "generating polynomial evaluation scheme" #_poly = PolynomialSchemeEvaluator.generate_horner_scheme(poly_object, _red_vx, unified_precision = self.precision) # building eval error map #eval_error_map = { # red_vx: Variable("red_vx", precision = self.precision, interval = red_vx.get_interval()), # log_inv_hi: Variable("log_inv_hi", precision = self.precision, interval = table_high_interval), # log_inv_lo: Variable("log_inv_lo", precision = self.precision, interval = table_low_interval), #} # computing gappa error #poly_eval_error = self.get_eval_error(result, eval_error_map) # main scheme print "MDL scheme" scheme = Statement(Return(vx)) return scheme
def generate_scheme(self): """ generate scheme """ vx = self.implementation.add_input_variable("x", self.get_input_precision()) # retrieving processor inverse approximation table lo_bound_global = SollyaObject(0.0) hi_bound_global = SollyaObject(0.75) approx_interval = Interval(lo_bound_global, hi_bound_global) approx_interval_size = hi_bound_global - lo_bound_global # table creation table_index_size = 7 field_index_size = 2 exp_index_size = table_index_size - field_index_size table_size = 2**table_index_size table_index_range = range(table_size) local_degree = 9 coeff_table = ML_NewTable(dimensions=[table_size, local_degree], storage_precision=self.precision) exp_lo = 2**exp_index_size for i in table_index_range: lo_bound = (1.0 + (i % 2**field_index_size) * S2**-field_index_size ) * S2**(i / 2**field_index_size - exp_lo) hi_bound = (1.0 + ((i % 2**field_index_size) + 1) * S2**-field_index_size ) * S2**(i / 2**field_index_size - exp_lo) local_approx_interval = Interval(lo_bound, hi_bound) local_poly_object, local_error = Polynomial.build_from_approximation_with_error( acos(1 - sollya.x), local_degree, [self.precision] * (local_degree + 1), local_approx_interval, sollya.absolute) local_error = int( log2(sup(abs(local_error / acos(1 - local_approx_interval))))) coeff_table for d in range(local_degree): coeff_table[i][d] = sollya.coeff( local_poly_object.get_sollya_object(), d) table_index = BitLogicRightShift( vx, vx.get_precision().get_field_size() - field_index_size) - (exp_lo << field_index_size) print "building mathematical polynomial" poly_degree = sup( sollya.guessdegree(acos(x), approx_interval, S2**-(self.precision.get_field_size()))) print "guessed polynomial degree: ", int(poly_degree) #global_poly_object = Polynomial.build_from_approximation(log10(1+x)/x, poly_degree, [self.precision]*(poly_degree+1), approx_interval, absolute) print "generating polynomial evaluation scheme" #_poly = PolynomialSchemeEvaluator.generate_horner_scheme(poly_object, _red_vx, unified_precision = self.precision) # building eval error map #eval_error_map = { # red_vx: Variable("red_vx", precision = self.precision, interval = red_vx.get_interval()), # log_inv_hi: Variable("log_inv_hi", precision = self.precision, interval = table_high_interval), # log_inv_lo: Variable("log_inv_lo", precision = self.precision, interval = table_low_interval), #} # computing gappa error #poly_eval_error = self.get_eval_error(result, eval_error_map) # main scheme print "MDL scheme" scheme = Statement(Return(vx)) return scheme