Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #4
0
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 )
Beispiel #5
0
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
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #8
0
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
Beispiel #9
0
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
Beispiel #10
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
Beispiel #12
0
    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]))
Beispiel #13
0
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
Beispiel #14
0
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
Beispiel #15
0
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)
Beispiel #16
0
    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
Beispiel #17
0
    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
Beispiel #18
0
    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
Beispiel #19
0
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' )