def apply(self, z, evaluation): '%(name)s[z__]' args = z.numerify(evaluation).get_sequence() mpmath_function = self.get_mpmath_function(args) result = None # if no arguments are inexact attempt to use sympy if all(not x.is_inexact() for x in args): result = Expression(self.get_name(), *args).to_sympy() result = self.prepare_mathics(result) result = from_sympy(result) # evaluate leaves to convert e.g. Plus[2, I] -> Complex[2, 1] return result.evaluate_leaves(evaluation) elif mpmath_function is None: return if not all(isinstance(arg, Number) for arg in args): return if any(arg.is_machine_precision() for arg in args): # if any argument has machine precision then the entire calculation # is done with machine precision. float_args = [ arg.round().get_float_value(permit_complex=True) for arg in args ] if None in float_args: return result = self.call_mpmath(mpmath_function, float_args) if isinstance(result, (mpmath.mpc, mpmath.mpf)): if mpmath.isinf(result) and isinstance(result, mpmath.mpc): result = Symbol('ComplexInfinity') elif mpmath.isinf(result) and result > 0: result = Expression('DirectedInfinity', Integer(1)) elif mpmath.isinf(result) and result < 0: result = Expression('DirectedInfinity', Integer(-1)) elif mpmath.isnan(result): result = Symbol('Indeterminate') else: result = Number.from_mpmath(result) else: prec = min_prec(*args) d = dps(prec) args = [ Expression('N', arg, Integer(d)).evaluate(evaluation) for arg in args ] with mpmath.workprec(prec): mpmath_args = [x.to_mpmath() for x in args] if None in mpmath_args: return result = self.call_mpmath(mpmath_function, mpmath_args) if isinstance(result, (mpmath.mpc, mpmath.mpf)): result = Number.from_mpmath(result, d) return result
def apply(self, z, evaluation): '%(name)s[z__]' args = z.numerify(evaluation).get_sequence() mpmath_function = self.get_mpmath_function(args) result = None # if no arguments are inexact attempt to use sympy if all(not x.is_inexact() for x in args): result = Expression(self.get_name(), *args).to_sympy() result = self.prepare_mathics(result) result = from_sympy(result) # evaluate leaves to convert e.g. Plus[2, I] -> Complex[2, 1] return result.evaluate_leaves(evaluation) elif mpmath_function is None: return if not all(isinstance(arg, Number) for arg in args): return if any(arg.is_machine_precision() for arg in args): # if any argument has machine precision then the entire calculation # is done with machine precision. float_args = [arg.round().get_float_value(permit_complex=True) for arg in args] if None in float_args: return result = self.call_mpmath(mpmath_function, float_args) if isinstance(result, (mpmath.mpc, mpmath.mpf)): if mpmath.isinf(result) and isinstance(result, mpmath.mpc): result = Symbol('ComplexInfinity') elif mpmath.isinf(result) and result > 0: result = Expression('DirectedInfinity', Integer(1)) elif mpmath.isinf(result) and result < 0: result = Expression('DirectedInfinity', Integer(-1)) elif mpmath.isnan(result): result = Symbol('Indeterminate') else: result = Number.from_mpmath(result) else: prec = min_prec(*args) d = dps(prec) args = [Expression('N', arg, Integer(d)).evaluate(evaluation) for arg in args] with mpmath.workprec(prec): mpmath_args = [x.to_mpmath() for x in args] if None in mpmath_args: return result = self.call_mpmath(mpmath_function, mpmath_args) if isinstance(result, (mpmath.mpc, mpmath.mpf)): result = Number.from_mpmath(result, d) return result
def __refine_results(self, intermediate_results: List[Match], print_results=True): """ validate intermediate results to 100 digit precision :param intermediate_results: list of results from first enumeration :param print_results: if true print status. :return: final results. """ results = [] counter = 0 n_iterations = len(intermediate_results) constant_vals = [const() for const in self.constants_generator] for r in intermediate_results: counter += 1 if (counter % 50) == 0 and print_results: print( 'passed {} permutations out of {}. found so far {} matches' .format(counter, n_iterations, len(results))) try: val = self.hash_table.evaluate(r.lhs_key, constant_vals) if mpmath.isinf(val) or mpmath.isnan(val): # safety continue except (ZeroDivisionError, KeyError) as e: continue # create a_n, b_n with huge length, calculate gcf, and verify result. an = self.create_an_series(r.rhs_an_poly, g_N_verify_terms) bn = self.create_bn_series(r.rhs_bn_poly, g_N_verify_terms) gcf = EfficientGCF(an, bn) val_str = mpmath.nstr(val, g_N_verify_compare_length) rhs_str = mpmath.nstr(gcf.evaluate(), g_N_verify_compare_length) if val_str == rhs_str: results.append(r) return results
def compareValues( result1, result2 ): if isinstance( result1, RPNMeasurement ) != isinstance( result2, RPNMeasurement ): return False if isinstance( result1, RPNMeasurement ): return result1.__eq__( result2 ) else: if isinf( result1 ): if isinf( result2 ): return True else: raise ValueError( 'unit test failed' ) print( '**** error in results comparison' ) print( type( result1 ), type( result2 ) ) print( result1, result2, 'are not equal' ) return almosteq( result1, result2 )
def mpf_matrix_fadd(A, B): """ Given a m x n matrix A and m x n matrix B either in numpy.matrix or mpmath.matrix format, this function computes the sum C = A + B exactly. The output matrix C is always given in the MPMATH format. Parameters ---------- A - m x n matrix B - m x n matrix Returns ------- C - m x n matrix """ if isinstance(A, numpy.matrix): try: A = python2mpf_matrix(A) except ValueError as e: raise ValueError('Cannot compute exact sum of two matrices. %s' % e) else: if not isinstance(A, mpmath.matrix): raise ValueError('Cannot compute exact sum of two matrices: unexpected input type, excpected numpy.matrix or mpmath.matrix but got %s') %type(A) if isinstance(B, numpy.matrix): try: B = python2mpf_matrix(B) except ValueError as e: raise ValueError('Cannot compute exact sum of two matrices. %s' % e) else: if not isinstance(B, mpmath.matrix): raise ValueError('Cannot compute exact sum of two matrices: unexpected input type, excpected numpy.matrix or mpmath.matrix but got %s') % type(B) #here both A and B are mpmath matrices #we consider that A and B are MPF matrices if their first elements are of type mpf, let's test it if not isinstance(A[0,0], mpmath.mpf) or not isinstance(B[0,0], mpmath.mpf): raise ValueError('Cannot compute exact product of two matrices: cannot sum complex matrices.') #test sizes if A.rows != B.rows or A.cols != B.cols: raise ValueError('Cannot compute exact sum of two matrices: incorrect sizes.') m = A.rows n = A.cols C = mp.zeros(m, n) for i in range(0, m): for j in range(0, n): C[i,j] = mpmath.fadd(A[i,j], B[i,j], exact=True) if mpmath.isnan(C[i,j]) or mpmath.isinf(C[i,j]): print('WARNING: in matrix sum an abnormal number (NaN/Inf) occured: %f' % C[i,j]) return C
def default_color_function(ctx, z): if math.isinf(z): return (1.0, 1.0, 1.0) if math.isnan(z): return (0.5, 0.5, 0.5) pi = 3.1415926535898 a = (float(math.arg(z)) + math.pi) / (2 * math.pi) a = (a + 0.5) % 1.0 b = 1.0 - float(1 / (1.0 + abs(z)**0.3)) return hls_to_rgb(a, b, 0.8)
def compareValues(result1, result2): if isinstance(result1, RPNMeasurement) != isinstance( result2, RPNMeasurement): return False if isinstance(result1, RPNMeasurement): return result1.__eq__(result2) else: if isinf(result1): if isinf(result2): return True else: print('**** error in results comparison') print(type(result1), type(result2)) print(result1, result2, 'are not equal') raise ValueError('unit test failed') return almosteq(result1, result2)
def compareLists(result1, result2): if len(result1) != len(result2): raise ValueError('lists are not of equal length:', len(result1), len(result2)) for i in range(0, len(result1)): if isinstance(result1[i], RPNGenerator): return compareLists(list(result1[i].getGenerator()), result2[i]) if isinstance(result2[i], RPNGenerator): return compareResults(result1[i], list(result2[i].getGenerator())) if isinstance(result1[i], list) != isinstance(result2[i], list): raise ValueError('lists are nested to different levels:', result1, result2) if isinstance(result1[i], list) and isinstance(result2[i], list): compareLists(result1[i], result2[i]) else: if isinf(result1[i]): if isinf(result2[i]): return True else: print('**** error in results comparison') print(type(result1[i]), type(result2[i])) print(result1[i], result2[i], 'are not equal') raise ValueError('unit test failed') if not compareValues(result1[i], result2[i]): digits = max(log10(result1[i]), log10(result2[i])) + 5 mp.dps = digits print('**** error in results comparison') print(type(result1[i]), type(result2[i])) print(result1[i], result2[i], 'are not equal') print('difference', fsub(result1[i], result2[i])) print('difference found at index', i) raise ValueError('unit test failed') return True
def select(): global lastop, a, listindex, argindex, theFile if lastop == 0: print( 'Parse Error: SELECT. came before corresponding EXP. or LOG. at instruction ' + str(pointer)) print(greporig(pointer)) left = val middle = a[listindex] right = val if listindex > 0: left = a[listindex - 1] if listindex < len(a) - 1: right = a[listindex + 1] print('Nearby Tape Values: ' + mpmath.nstr(left) + ',' + mpmath.nstr(middle) + ',' + mpmath.nstr(right)) sys.exit() elif lastop == 1: if a[argindex] != 0 or mpmath.im( a[listindex]) != 0 or a[listindex] >= 0: try: a[argindex] = mpmath.power(a[argindex], a[listindex]) except OverflowError: print( 'Number too large to represent. Try increasing precision or moving default tape value closer to 1.' ) print(greporig(pointer)) a[argindex] = mpmath.chop(a[argindex], tol) else: a[argindex] = mpmath.mpc('inf') else: if a[listindex] == 1: print('Tried to take a log base one at instruction ' + str(pointer)) print(greporig(pointer)) left = val middle = a[listindex] right = val if listindex > 0: left = a[listindex - 1] if listindex < len(a) - 1: right = a[listindex + 1] print('Nearby Tape Values: ' + mpmath.nstr(left) + ',' + mpmath.nstr(middle) + ',' + mpmath.nstr(right)) sys.exit() a[argindex] = mpmath.log(a[argindex], a[listindex]) #patch up nans when arg is infinite, since we usually want zero for the real part then if mpmath.isinf(mpmath.im(a[argindex])) and mpmath.isnan( mpmath.re(a[argindex])): a[argindex] = mpmath.mpc(0, mpmath.im(a[argindex])) a[argindex] = mpmath.chop(a[argindex], tol) oparg = 0
def _ci_upper(table, alpha): """ Compute the upper end of the confidence interval. """ if mpmath.isinf(_sample_odds_ratio(table)): return mpmath.mp.inf x, total, ngood, nsample = _hypergeom_params_from_table(table) # fnch.cdf is a decreasing function of nc, so we negate # it in the lambda expression. nc = _solve(lambda nc: -fnch.cdf(x, nc, total, ngood, nsample) + alpha) return nc
def _refine_results(self, intermediate_results: List[Match], print_results=True): """ validate intermediate results to 100 digit precision :param intermediate_results: list of results from first enumeration :param print_results: if true print status. :return: final results. """ results = [] counter = 0 n_iterations = len(intermediate_results) constant_vals = [const() for const in self.constants_generator] for res in intermediate_results: counter += 1 if (counter % 50) == 0 and print_results: print( 'passed {} permutations out of {}. found so far {} matches' .format(counter, n_iterations, len(results))) try: all_matches = self.hash_table.evaluate(res.lhs_key) # check if all values encountered are not inf or nan if not all([ not (mpmath.isinf(val) or mpmath.isnan(val)) for val, _, _ in all_matches ]): # safety print('Something wicked happened!') print( f'Encountered a NAN or inf in LHS db, at {res.lhs_key}, {constant_vals}' ) continue except (ZeroDivisionError, KeyError): # if there was an exeption here, there is no need to halt the entire execution, but only note it to the # user continue # create a_n, b_n with huge length, calculate gcf, and verify result. an = self.create_an_series(res.rhs_an_poly, g_N_verify_terms) bn = self.create_bn_series(res.rhs_bn_poly, g_N_verify_terms) gcf = EfficientGCF(an, bn) rhs_str = mpmath.nstr(gcf.evaluate(), g_N_verify_compare_length) for i, match in enumerate(all_matches): val_str = mpmath.nstr(match[0], g_N_verify_compare_length) if val_str == rhs_str: # This patch is ment to allow support for multiple matches for an # LHS key, i will later be used to determind which item in the LHS dict # was matched results.append(RefinedMatch(*res, i, match[1], match[2])) return results
def _refine_results(self, precise_intermediate_results, verbose=True): """ validate intermediate results to 100 digit precision :param precise_intermediate_results: list of results from first enumeration :param verbose: if true print status. :return: final results. """ results = [] counter = 0 n_iterations = len(precise_intermediate_results) constant_vals = [const() for const in self.constants_generator] for res, rhs_str in precise_intermediate_results: counter += 1 if (counter % 10_000 == 0 or counter == n_iterations) and verbose: print( 'Passed {} permutations out of {}. Found so far {} matches' .format(counter, n_iterations, len(results))) try: all_matches = self.hash_table.evaluate(res.lhs_key) # check if all values encountered are not inf or nan if not all([ not (mpmath.isinf(val) or mpmath.isnan(val)) for val, _, _ in all_matches ]): # safety print('Something wicked happened!') print( f'Encountered a NAN or inf in LHS db, at {res.lhs_key}, {constant_vals}' ) continue except (ZeroDivisionError, KeyError): # if there was an exception here, there is no need to halt the entire execution, # but only note it to the user continue for i, match in enumerate(all_matches): val_str = mpmath.nstr(match[0], g_N_verify_compare_length) if val_str == rhs_str: # This patch is meant to allow support for multiple matches for an # LHS key, it will later be used to determine which item in the LHS dict # was matched results.append(RefinedMatch(*res, i, match[1], match[2]))
def mpf_get_representation(a): """ Given a MP floating-point number of type mpmath.mpf this function returns a tuple (y, n) of python long integers such that a = y * 2**n exactly. If the number is +Inf, -Inf or NaN WARNING: we get into the internal structure of MPF class. a._mpf_ yeilds a tuple of four variables: _mpf_[0] - sign _mpf_[1] - mantissa _mpf_[2] - exponent _mpf_[3] - size of mantissa with which the number was created Parameters ---------- a - MP number Returns ------- y - long n - int or long """ if not isinstance(a, mpmath.mpf): raise ValueError('Expected mpmath.mpf but got %s' % type(a)) if mpmath.isinf(a) or mpmath.isnan(a): raise ValueError( 'Cannot get a representation of number: an Inf or NaN occured') t = a._mpf_ if len(t) != 4: raise ValueError( 'Something is wrong, could not get mpf number structure') n = t[2] y = -t[1] if t[0] else t[1] return y, n
def drawbox(): global a, listindex, centerx, centery, pixdict, z, red, green, blue, canv, verbose if verbose: print('Outputting: ' + mpmath.nstr(mpmath.chop(a[listindex]))) if mpmath.isnan(a[listindex]) or mpmath.isinf(a[listindex]): return try: x = int(mpmath.nint(mpmath.re(a[listindex]))) + centerx y = int(mpmath.nint(mpmath.im(a[listindex]))) + centery if (x, y) in pixdict: canv.delete(pixdict[(x, y)]) del pixdict[(x, y)] pixdict[(x, y)] = canv.create_rectangle(x * z - z + 1, y * z - z + 1, x * z + 1, y * z + 1, fill=rgb(red, green, blue), width=0) except OverflowError: #the number is so huge it's not going to be displayed anyway, so just suppress the error and move on pass
def pmean(x, p): """ Power (or generalized) mean of the values in the sequence x. """ # Special cases if p == 0: return gmean(x) elif p == 1: return mean(x) elif p == -1: return hmean(x) elif mpmath.isinf(p): with mpmath.extraprec(16): if p > 0: return max(mpmath.mpf(t) for t in x) else: return min(mpmath.mpf(t) for t in x) with mpmath.extraprec(16): p = mpmath.mpf(p) return mpmath.power(mean([mpmath.mpf(t)**p for t in x]), 1/p)
def impulse_response(self, Ts: float, Tmax: float, Tstart: float = 0, K: float = 1.0, N: int = 200, P=20, plot=False, verbose=False): ''' This function returns FDL's exp(-(L*s)^alpha) time response for the time vector t=[Tstart:Ts:Tmax]. Parameters: ----------- : L: the dead time [s] : alpha: the fractional power ]0,1[ : Ts: sampling time [s] : Tmax: the end value of the time vector [s] : Tstart: the start value [s] (default: Ts) : K: the size of the input impulse (default: 1.0) : N: Quality of the output (The number of summation terms) (default: 200) : P: Estimated peak size (default: 20) : plot: Bool, plot the impulse response (default: False) : verbose: Bool, write to terminal (default: False) Returns: -------- : t: time vector [s] : I: impulse response vector ''' # Produce time axis: the time power will converge as t > 1 if Tstart == 0: Tstart = Ts t = np.arange(Tstart, Tmax, Ts) # Prepare alpha vector diff_start_idx = [0] diff_stop_idx = [] type_alpha = [] # 0: cst| 1: var if isinstance(self.alpha, float): alpha = len(t) * [self.alpha] diff_stop_idx.append(len(alpha)) type_alpha.append(0) else: alpha = self.alpha diff_alpha = [ 1 if not math.isclose(a_diff, 0.0) else 0 for a_diff in np.diff(alpha, prepend=alpha[0]) ] add_idx_bool = True for idx, el in enumerate(diff_alpha): if not math.isclose(el, 0.0): if (not add_idx_bool) and (idx + 1 is not len(alpha)) and ( math.isclose(diff_alpha[idx + 1], 0)): add_idx_bool = True if add_idx_bool: diff_stop_idx.append(idx) diff_start_idx.append(idx) add_idx_bool = False elif not add_idx_bool: add_idx_bool = True diff_stop_idx.append(len(alpha)) for k in range(len(diff_start_idx)): if sum(diff_alpha[diff_start_idx[k]:diff_stop_idx[k]] ) == diff_stop_idx[k] - diff_start_idx[k]: type_alpha.append(1) else: type_alpha.append(0) # Init parameters of loop i = 0 summed_terms = len(t) * [0] # Set precisions mp.dps = 65 mp.prec = 100 while i < N: # Init one term vector single_term = len(t) * [0] for k in range(len(diff_start_idx)): if type_alpha[k]: single_term[diff_start_idx[k]:diff_stop_idx[ k]] = self.__calculate_single_term_var_alpha__( t[diff_start_idx[k]:diff_stop_idx[k]], i, alpha[diff_start_idx[k]:diff_stop_idx[k]]) else: single_term[diff_start_idx[k]:diff_stop_idx[ k]] = self.__calculate_single_term_cst_alpha__( t[diff_start_idx[k]:diff_stop_idx[k]], i, alpha[diff_start_idx[k]]) # Add the current iteration to the previous iterations with warnings.catch_warnings(): warnings.filterwarnings('error') try: summed_terms = [ sum_el + single_el if not math.isinf(sum_el + single_el) else sys.float_info.min for sum_el, single_el in zip(summed_terms, single_term) ] except: summed_terms = [ fsum([sum_el, single_el]) if not isinf(fsum([sum_el, single_el])) else sys.float_info.min for sum_el, single_el in zip(summed_terms, single_term) ] # Update iteration counter i += 1 if verbose and (i % 5 == 0): # Print progress print('Progress: {:d}%'.format(math.floor(i / N * 100)), end='\r', flush=True) if verbose: print('', end='\n', flush=True) # Polish off the error due to cutting of the summation q1 = [i for i, val in enumerate(summed_terms) if abs(val) > P] q2 = [i for i, val in enumerate(summed_terms) if val < 0] I_norm = summed_terms if len(q1) is not 0: #TODO: improve cleaning, no magic number 10, look at derivative? if q1[-1] + 10 < len(I_norm): I_norm[0:(q1[-1] + 10)] = (q1[-1] + 10) * [0] if len(q2) is not 0: I_norm[0:q2[-1] + 1] = (q2[-1] + 1) * [0] I = [float(K * I_norm_el) for I_norm_el in I_norm] if plot: plt.figure() plt.plot(t, I) plt.show() return t, I
def impulse_response(self, Ts: float, Tmax: float, K=1.0, N: int = 200, P=20, plot=False, verbose=False): ''' This function returns FDL's exp(-(L*s)^alpha) time response for the time vector t=[Ts:Ts:Tmax]. Parameters: ----------- : L: the dead time [s] : alpha: the fractional power ]0,1[ : Ts: sampling time [s] : Tmax: the end value of the time vector [s] : N: Quality of the output (The number of summation terms) : P: Estimated peak size Returns: -------- : t: time vector [s] : I: impulse response vector ''' # Produce time axis: the time power will converge as t > 1 t = np.arange(Ts, Tmax, Ts) if isinstance(self.alpha, float): alpha = self.alpha else: alpha = self.alpha[0] # Init parameters of loop i = 0 summed_terms = len(t) * [0] while i < N: # Gamma-function of integer argument is infinite arg = i * alpha if arg.is_integer(): single_term = len(t) * [0] else: try: # Calculate the different terms of the single_term factorial_i = math.factorial(i) gamma_ia = math.gamma(-i * alpha) with warnings.catch_warnings(): warnings.simplefilter("ignore") time_power = [t_el**(-i * alpha - 1) for t_el in t] L_ai = (-1)**i * self.L**(i * alpha) const = L_ai / (factorial_i * gamma_ia) if math.isinf(const): raise OverflowError single_term = [tp * const for tp in time_power] except OverflowError: # Check if there are any overflows mp.dps = 65 mp.prec = 100 factorial_i_hp = factorial(i) gamma_ia_hp = gamma(-i * alpha) with warnings.catch_warnings(): warnings.filterwarnings('error') try: L_ai_hp = mpf((-1)**i * self.L**(i * alpha)) except: if verbose: print('Overflow stop at {}%, due to large L'. format(math.ceil(i / N * 100))) break const_hp = mpf(L_ai_hp / (factorial_i_hp * gamma_ia_hp)) single_term = [tp * float(const_hp) for tp in time_power] # Check if time power is not infinite at t < 1 q = [ i for i, val in enumerate(time_power) if math.isinf(val) ] for j in range(len(q)): time_power_temp = power(t[q[j]], (-alpha * i - 1)) quotient_hp = time_power_temp * const_hp if math.isinf(float(quotient_hp)): single_term[q[j]] = sys.float_info.max else: single_term[q[j]] = float(quotient_hp) # Add the current iteration to the previous iterations with warnings.catch_warnings(): warnings.filterwarnings('error') try: summed_terms = [ sum_el + single_el if not math.isinf(sum_el + single_el) else sys.float_info.min for sum_el, single_el in zip(summed_terms, single_term) ] except: summed_terms = [ fsum([sum_el, single_el]) if not isinf(fsum([sum_el, single_el])) else sys.float_info.min for sum_el, single_el in zip(summed_terms, single_term) ] # Update iteration counter i += 1 if verbose and (i % 5 == 0): # Print progress print('Progress: {:d}%'.format(math.floor(i / N * 100)), end='\r', flush=True) if verbose: print('', end='\n', flush=True) # Polish off the error due to cutting of the summation q1 = [i for i, val in enumerate(summed_terms) if abs(val) > P] q2 = [i for i, val in enumerate(summed_terms) if val < 0] I_norm = summed_terms if len(q1) is not 0: #TODO: improve cleaning, no magic number 10, look at derivative? if q1[-1] + 10 < len(I_norm): I_norm[0:(q1[-1] + 10)] = (q1[-1] + 10) * [0] if len(q2) is not 0: I_norm[0:q2[-1] + 1] = (q2[-1] + 1) * [0] I = [K * I_norm_el for I_norm_el in I_norm] if plot: plt.figure() plt.plot(t, I) plt.show() return t, I
def run_quadmath_conversions(self): import pybind11_test_01 as p if not p.has_quadmath(): return try: from mpmath import mpf, mp, workprec, isnan, isinf except ImportError: return # Default precision is 53, so the conversion will fail. self.assertRaises(TypeError, lambda: p.test_real128_conversion(mpf())) self.assertRaises(TypeError, lambda: p.test_real128_conversion(mpf("inf"))) self.assertRaises(TypeError, lambda: p.test_real128_conversion(mpf("nan"))) # Set precision to quadruple. mp.prec = 113 self.assertTrue(p.test_real128_conversion(mpf()) == 0) self.assertTrue(p.test_real128_conversion(mpf(1)) == 1) self.assertTrue(p.test_real128_conversion(mpf(-1)) == -1) self.assertTrue(p.test_real128_conversion(mpf("inf")) == mpf("inf")) self.assertTrue(p.test_real128_conversion(-mpf("inf")) == -mpf("inf")) self.assertTrue(isnan(p.test_real128_conversion(mpf("nan")))) self.assertTrue( p.test_real128_conversion( mpf("1.32321321001020301293838201938121203")) == mpf( "1.32321321001020301293838201938121203")) self.assertTrue( p.test_real128_conversion( -mpf("1.32321321001020301293838201938121203")) == -mpf("1.32321321001020301293838201938121203")) self.assertTrue( p.test_real128_conversion(mpf(2)**-16382) == mpf(2)**-16382) self.assertTrue( p.test_real128_conversion(-(mpf(2)**-16382)) == -(mpf(2)**-16382)) # Try subnormal numbers behaviour. self.assertTrue(mpf(2)**-16495 != 0) self.assertTrue(p.test_real128_conversion(mpf(2)**-16495) == mpf(0)) # Try the workprec construct. with workprec(2000): self.assertRaises(TypeError, lambda: p.test_real128_conversion(mpf())) self.assertRaises(TypeError, lambda: p.test_real128_conversion(mpf("inf"))) self.assertRaises(TypeError, lambda: p.test_real128_conversion(mpf("nan"))) # Test that the real128 overload is picked before the real one, # if instantiated before. self.assertTrue(p.test_overload(mpf(2)**-16495) == 0) if not p.has_mpfr(): with workprec(2000): self.assertTrue(p.test_overload(mpf(2)**-16495) != 0) # Test we don't end up to inf if the significand has more than 113 bits. mp.prec = 40000 foo = mpf("1.1") with workprec(113): self.assertFalse(isinf(p.test_real128_conversion(foo))) # Restore prec on exit. mp.prec = 53
def compareResults( result1, result2 ): '''Compares two RPN expressions to make sure they produce the same result. Does nothing if the results compare successfully, otherwise raises an exception.''' if isinstance( result1, RPNGenerator ): return compareResults( list( result1.getGenerator( ) ), result2 ) if isinstance( result2, RPNGenerator ): return compareResults( result1, list( result2.getGenerator( ) ) ) if isinstance( result1, list ) != isinstance( result2, list ): print( '**** error in results comparison' ) print( ' result 1: ', result1 ) print( ' result 2: ', result2 ) raise ValueError( 'one result is a list, the other isn\'t' ) if isinstance( result1, str ) != isinstance( result2, str ): print( '**** error in results comparison' ) print( ' result 1: ', result1 ) print( ' result 2: ', result2 ) raise ValueError( 'one result is a string, the other isn\'t' ) if isinstance( result1, str ) and isinstance( result2, str ): if result1 != result2: print( '**** error in results comparison' ) print( type( result1 ), type( result2 ) ) print( result1, result2, 'are not equal' ) raise ValueError( 'unit test failed' ) else: return if isinstance( result1, RPNMeasurement ) and isinstance( result2, RPNMeasurement ): if result1 != result2: print( '**** error in results comparison' ) print( type( result1 ), type( result2 ) ) with workdps( 50 ): print( result1.value, result1.units, result2.value, result2.units, 'are not equal' ) raise ValueError( 'unit test failed' ) else: return True if isinstance( result1, list ) and isinstance( result2, list ): if len( result1 ) != len( result2 ): raise ValueError( 'lists are not of equal length:', len( result1 ), len( result2 ) ) for i in range( 0, len( result1 ) ): if isinf( result1[ i ] ): if isinf( result2[ i ] ): return True else: print( '**** error in results comparison' ) print( type( result1[ i ] ), type( result2[ i ] ) ) print( result1[ i ], result2[ i ], 'are not equal' ) raise ValueError( 'unit test failed' ) if not compareValues( result1[ i ], result2[ i ] ): digits = max( log10( result1[ i ] ), log10( result2[ i ] ) ) + 5 mp.dps = digits print( '**** error in results comparison' ) print( type( result1[ i ] ), type( result2[ i ] ) ) print( result1[ i ], result2[ i ], 'are not equal' ) print( 'difference', fsub( result1[ i ], result2[ i ] ) ) print( 'difference found at index', i ) raise ValueError( 'unit test failed' ) else: if not compareValues( result1, result2 ): print( '**** error in results comparison' ) print( ' result 1: ', result1 ) print( ' result 2: ', result2 ) raise ValueError( 'unit test failed' )