Example #1
0
def logSpaceAdd(update, before):
    '''
	Assume a >= b

	We want to calculate ln(exp(ln(a))+exp(ln(b))), thus
	ln(
	exp(ln(b))*(1+exp(ln(a)-ln(b)))
	)
	->
	ln(b) + ln(1+exp(ln(a)-ln(b)))
	->
	ln(b) + ln1p(exp(ln(a)-ln(b)))
	'''
    #As there is no neutral element of addition in log space we only start adding when two values are given
    if before == None:
        return update
    else:
        a = None
        b = None
        #Check which value is larger
        if update > before:
            b = update
            a = before
        else:
            b = before
            a = update

        x = mp.mpf(a) - mp.mpf(b)
        #print(update,before)
        xexp = memoexp(x)
        #print('Exp:',xexp)
        val = memolog1p(xexp)
        #print('Log:',val)
        val = val + b
        if val == 0:
            print('a:{} b:{} x:{} xexp:{} log1p:{}'.format(a, b, x, xexp, val))
            raise ValueError(
                'LogSpace Addition has resulted in a value of 0: a = {} b = {} (possible underflow)'
                .format(a, b))
        #elif val > 0:
        #print('a:{} b:{} x:{} xexp:{} log1p:{}'.format(a,b,x,xexp,val))
        #raise ValueError('Prior Update has resulted in a value > 0: a = {} b = {} val = {}'.format(a,b,val))

        if before == val:
            #print('a:{} b:{} x:{} xexp:{} log1p:{}'.format(a,b,x,xexp,val))
            logging.warning(
                'LogAddition had no effect: a = {} b = {} val = {}'.format(
                    a, b, val))
            #raise ValueError('LogAddition had no effect: a = {} b = {} val = {}'.format(a,b,val))
            #raise ValueError('LogAddition had no effect!')

        if mp.isnan(val):
            raise ValueError(
                'LogSpace Addition has resulted in a value of nan: a = {} b = {}'
                .format(a, b))

        if mp.fabs(val) > 1000:  #At this point who cares let's round a bit
            val = mp.floor(val)

        return val
    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
Example #3
0
def mpc_to_np(x):
    if isnan(x):
        return np.nan
    if x.imag == 0:
        return np.float64(x.real)

    return np.complex128(x)
Example #4
0
def mpc_to_np(x):
    if isnan(x):
        return np.nan
    if x.imag == 0:
        return np.float64(x.real)
    
    return np.complex128(x)
Example #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
Example #6
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
Example #7
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)
Example #8
0
    def run_mpfr_conversions(self):
        import pybind11_test_01 as p

        if not p.has_mpfr():
            return

        try:
            from mpmath import mpf, mp, workprec, isnan
        except ImportError:
            return

        self.assertTrue(p.test_real_conversion(mpf()) == 0)
        self.assertTrue(p.test_real_conversion(mpf(1)) == 1)
        self.assertTrue(p.test_real_conversion(mpf(-1)) == -1)
        self.assertTrue(p.test_real_conversion(mpf("inf")) == mpf("inf"))
        self.assertTrue(p.test_real_conversion(-mpf("inf")) == -mpf("inf"))
        self.assertTrue(isnan(p.test_real_conversion(mpf("nan"))))
        self.assertTrue(
            p.test_real_conversion(mpf("1.323213210010203")) == mpf(
                "1.323213210010203"))
        self.assertTrue(
            p.test_real_conversion(-mpf("1.323213210010203")) ==
            -mpf("1.323213210010203"))

        # Test with different precision.
        # Less precision in output from C++ is ok.
        self.assertTrue(p.test_real_conversion(mpf(-1), 30) == -1)
        self.assertTrue(p.test_real_conversion(mpf("inf"), 30) == mpf("inf"))
        self.assertTrue(isnan(p.test_real_conversion(mpf("nan"), 30)))
        # More precision in output from C++ will be lossy, so an error
        # is raised instead.
        self.assertRaises(ValueError,
                          lambda: p.test_real_conversion(mpf(-1), 300))
        self.assertRaises(ValueError,
                          lambda: p.test_real_conversion(mpf("inf"), 300))
        self.assertRaises(ValueError,
                          lambda: p.test_real_conversion(mpf("nan"), 300))

        # Try the workprec construct.
        with workprec(100):
            self.assertTrue(p.test_real_conversion(mpf("1.1")) == mpf("1.1"))
            self.assertTrue(p.test_real_conversion(mpf("-1.1")) == mpf("-1.1"))
Example #9
0
def are_matrices_close(mat1, mat2, rtol=1e-05, atol=1e-08, equal_nan=False):
    if mode == mode_python:
        return np.allclose(mat1, mat2, rtol, atol, equal_nan)
    else:
        # Just make sure we have matrices and not lists. np.allclose supports
        # lists. List support is useful for tests as can have test data that is
        # common to both representations in list form.
        mat1_ = matrix(mat1)
        mat2_ = matrix(mat2)
        if shape(mat1_) != shape(mat2_):
            return False
        for r in range(mat1_.rows):
            for c in range(mat1_.cols):
                a = mat1_[r, c]
                b = mat2_[r, c]
                if mpmath.isnan(a) and mpmath.isnan(b) and equal_nan:
                    pass
                elif not num_cmp(a, b, atol, rtol):
                    return False
    return True
Example #10
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
Example #11
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 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
Example #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
Example #14
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]))
Example #15
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
Example #16
0
def Perr(Qtildep, Q, Qp, FNR, FPR):
    """
    Returns observed error-prone probability distribution.
    
    Args
    ----
    Qtildep (int): number of positive tests.
    Qp (int): number of positive tests.
    Q (int): number of tests.
    FNR (float): false-negative fraction.
    FPR (float): false-positive fraction.
    
    """

    Qm = Q - Qp

    Perr = power(FNR, Qp) * power(1 - FPR, Qm - Qtildep ) * power(FPR, Qtildep) \
           * binomial( Qm, Qtildep ) * hyp2f1( -Qp, -Qtildep, Qm + 1 - Qtildep, \
           (FNR-1)*(FPR-1)/(FNR*FPR) )

    if isnan(Perr):
        Perr = 0

    return Perr
Example #17
0
def solve(key,debug=False,showcode=False,showequations=False):
    code = "from sympy import *\n\n"

    url = "https://docs.google.com/spreadsheets/d/%s/export?format=csv"%(key) # don't put the gid id in, then always returned the first sheet in tabs

    r = requests.get(url)
    data = r.content

    if debug:
        print data

    df = pd.read_csv(StringIO(data),header=-1)
    if debug:
        print df


    locInput = 1
    locName = 2
    locOutput = 3
    locRule = 0
    locSt = 0
    locGroup = 0

    parserState = None
    variables = []
    rules = []

    #print df.iloc[0,0]
    for i in range(0,len(df)):
        if df.iloc[i,locGroup] == 'st':
            continue
        if df.iloc[i,locGroup] == 'variables':
            parserState = 'inVariables'
            continue
        if parserState == 'inVariables':
            if pd.isnull(df.iloc[i,locName]):
                parserState = None
            else:
                variables.append({'st':df.iloc[i,locSt],
                                  'name':df.iloc[i,locName],
                                  'input':df.iloc[i,locInput],
                                 'row':i})

        if df.iloc[i,locGroup] == 'rules':
            parserState = 'inRules'
            continue
        if parserState == 'inRules':
            if pd.isnull(df.iloc[i,locRule]):
                parserState = None
                break
            else:
                rules.append(df.iloc[i,locRule])

    if debug:
        print variables
        print rules

    code += "# variables\n"
    initialGuess = 10000.1
    outputs = collections.OrderedDict()

    for v in variables:
        if len(v['name']) == 1:
            code += "%-5s = Symbol('%s')\n"%(v['name'],v['name'])
        else:
            code += "%-5s = Symbol('%c_%s')\n"%(v['name'],v['name'][0],v['name'][1:])

        if v['st'] =='g':
            outputs[v['name']] = float(v['input'])
        else:
            if isnan(v['input']):
                outputs[v['name']] = initialGuess
            else:
                code += "%-5s = %f\n"%(v['name'],float(v['input']))
    code += "\n"

    if debug:
        print code
        print outputs

    code += "# rules\n"
    ans = "ans = nsolve(("
    i = 1
    for r in rules:
        lhs,rhs = r.split('=',1)
        code += "e%d = Eq(   %10s,%-20s   )\n"%(i,lhs,rhs)
        if showequations:
            code += "display(e%d)\n"%i
        ans += "e%d,"%i
        i += 1



    code += "\n# solve\n"+ans[0:-1]+"),("+",".join(outputs.keys())+"),("
    code += ",".join(map(str,outputs.values()))+"),verify=True)"

    code += "\n\n# answers\n"

    i = 0
    if len(outputs.keys()) == 1:
        code += "print ans\n" 
    else:
        for k in outputs.keys():
            code += "print \"%-5s = %%14.6f\"%%ans[%d]\n"%(k,i)
            i += 1
        
    if debug or showcode:
        print code
        print 
        print "# ------------------------------------------------------------------\n\n"

    try:
        exec(code)
    except ValueError as msg:
        print msg
    except TypeError as msg:
        print msg
        print "modify initial values"
Example #18
0
def solve(key,debug=False,showcode=False,showequations=False):
    code = "from sympy import *\n\n"

    url = "https://docs.google.com/spreadsheets/d/%s/export?format=csv"%(key) # don't put the gid id in, then always returned the first sheet in tabs

    r = requests.get(url)
    data = r.content

    if debug:
        print data

    df = pd.read_csv(StringIO(data),header=-1)
    if debug:
        print df

    locInput = 1
    locName = 2
    locOutput = 3
    locRule = 0
    locSt = 0
    locGroup = 0

    parserState = None
    variables = []
    rules = []

    #print df.iloc[0,0]
    for i in range(0,len(df)):
        if df.iloc[i,locGroup] == 'st':
            continue
        if df.iloc[i,locGroup] == 'variables':
            parserState = 'inVariables'
            continue
        if parserState == 'inVariables':
            if pd.isnull(df.iloc[i,locName]):
                parserState = None
            else:
                variables.append({'st':df.iloc[i,locSt],
                                  'name':df.iloc[i,locName],
                                  'input':df.iloc[i,locInput],
                                 'row':i})

        if df.iloc[i,locGroup] == 'rules':
            parserState = 'inRules'
            continue
        if parserState == 'inRules':
            if pd.isnull(df.iloc[i,locRule]):
                parserState = None
                break
            else:
                rules.append(df.iloc[i,locRule])

    if debug:
        print variables
        print rules

    code += "# variables\n"
    initialGuess = 10000.1
    outputs = collections.OrderedDict()

    for v in variables:
        if len(v['name']) == 1:
            code += "%-10s = Symbol('%s')\n"%(v['name'],v['name'])
        else:
            code += "%-10s = Symbol('%c_%s')\n"%(v['name'],v['name'][0],v['name'][1:])

        if v['st'] =='g':
            outputs[v['name']] = float(v['input'])
        else:
            if isnan(v['input']):
                outputs[v['name']] = initialGuess
            else:
                code += "%-10s = %f\n"%(v['name'],float(v['input']))
    code += "\n"

    if debug:
        print "-- code -----------------------------------------------------------"
        print code
        print "-- code -----------------------------------------------------------"
        print
        print outputs

    code += "# rules\n"
    ans = "ans = nsolve(("
    i = 1
    for r in rules:
        lhs,rhs = r.split('=',1)
        code += "e%d = Eq(   %10s,%-20s   )\n"%(i,lhs,rhs)
        if showequations:
            code += "display(e%d)\n"%i
        ans += "e%d,"%i
        i += 1



    code += "\n# solve\n"+ans[0:-1]+"),("+",".join(outputs.keys())+"),("
    code += ",".join(map(str,outputs.values()))+"),verify=True)"

    code += "\n\n# answers\n"

    i = 0
    if len(outputs.keys()) == 1:
        code += "print ans\n" 
    else:
        for v in variables:
            if not isnan(v['input']) and v['st'] != 'g':
                code += "print \"%-10s = %14.6f\"\n"%(v['name'],float(v['input']))
        
        code += "print\n"

        for k in outputs.keys():
            code += "print \"%-10s = %%14.6f\"%%ans[%d]\n"%(k,i)
            i += 1

        
    if debug or showcode:
        print variables
        print code

    try:
        exec(code)
    except ValueError as msg:
        print msg
    except TypeError as msg:
        print msg
        print "modify initial values"
Example #19
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
Example #20
0
    def _estimate_approach_type_and_params_inner_alg(
            self,
            find_poly_parameter=False,
            iters=5000,
            initial_cutoff=1500,
            iters_step=500,
            exponential_threshold=1.1):
        """Returns 'exp', 'super_exp', 'poly2sympoly', 'undefined', 'fast' and 'mixed', as a tuple of (string,num):
        (approach_type, approach_parameter) or ('poly2sympoly', (approach_parameter, R**2))."""
        # This is an old function. It's still in use, but it's yucky and I don't feel like going through it and
        # document it. Sorry :(
        # Hopefully it will be replaced with some theoretical insights.
        # HOWEVER, IT IS GENERAL AND MAY BE USEFUL FOR NEW, FUTURE REPRESENTATION METHODS.
        # See the "convergence_analysis.pdf" file for further details about theory behind this function.
        # It evaluates and categorizes by computing linear fitting to the error/iterations plot. Regular or logarithmic.

        effective_zero = dec(10)**-mp.dps

        if iters_step < 6:
            ValueError('iters_step should be at least 4')

        approach_type = None
        approach_parameter = 0

        delta_pair = []
        delta_odd = []
        self.gen_iterations(initial_cutoff)
        res_0 = self.get_result()
        self.add_iterations(1)
        res_1 = self.get_result()
        self.add_iterations(1)
        res_2 = self.get_result()
        self.add_iterations(1)
        res_3 = self.get_result()
        self.add_iterations(1)
        res_4 = self.get_result()
        self.add_iterations(1)
        res_5 = self.get_result()
        delta_pair.append((initial_cutoff, abs(res_2 - res_0)))
        delta_pair.append((initial_cutoff + 2, abs(res_4 - res_2)))
        delta_odd.append((initial_cutoff + 1, abs(res_3 - res_1)))
        delta_odd.append((initial_cutoff + 3, abs(res_5 - res_3)))

        for i in range(initial_cutoff + iters_step, iters + 1, iters_step):
            # -3 for the iterations of res_1, res_2, res_3 that were already executed
            self.add_iterations(iters_step - 5)
            res_0 = self.get_result()
            self.add_iterations(1)
            res_1 = self.get_result()
            self.add_iterations(1)
            res_2 = self.get_result()
            self.add_iterations(1)
            res_3 = self.get_result()
            self.add_iterations(1)
            res_4 = self.get_result()
            self.add_iterations(1)
            res_5 = self.get_result()
            delta_pair.append((i, abs(res_2 - res_0)))
            delta_pair.append((i + 2, abs(res_4 - res_2)))
            delta_odd.append((i + 1, abs(res_3 - res_1)))
            delta_odd.append((i + 3, abs(res_5 - res_3)))

        pair_diminish = False
        odd_diminish = False
        if len(delta_pair) > 3 and all(
            [abs(p[1]) < effective_zero for p in delta_pair[-3:]]):
            pair_diminish = True
        if len(delta_odd) > 3 and all(
            [abs(p[1]) < effective_zero for p in delta_odd[-3:]]):
            odd_diminish = True
        # if one diminishes and the other isn't, return 'undefined'
        if pair_diminish ^ odd_diminish:
            approach_type = 'undefined'
        elif pair_diminish and odd_diminish:
            approach_type = 'fast'

        # if approach_type:
        #     return (approach_type, approach_parameter)

        pair_ratio = [
            (delta_pair[i][0], delta_pair[i][1] / delta_pair[i + 1][1])
            for i in range(0, len(delta_pair), 2)
            if delta_pair[i][1] != 0 and delta_pair[i + 1][1] != 0
            and not isnan(delta_pair[i][1]) and not isnan(delta_pair[i + 1][1])
        ]
        odd_ratio = [
            (delta_odd[i][0], delta_odd[i][1] / delta_odd[i + 1][1])
            for i in range(0, len(delta_odd), 2)
            if delta_odd[i][1] != 0 and delta_odd[i + 1][1] != 0
            and not isnan(delta_odd[i][1]) and not isnan(delta_odd[i + 1][1])
        ]

        if len(pair_ratio) < 6:
            return (approach_type, approach_parameter)

        mean_pair_ratio = sum([p for i, p in pair_ratio]) / len(pair_ratio)
        mean_pair_ratio_avg_square_error = sum([
            (r - mean_pair_ratio)**2 for i, r in pair_ratio
        ]).sqrt() / len(pair_ratio)
        mean_odd_ratio = sum([p for i, p in odd_ratio]) / len(odd_ratio)
        mean_odd_ratio_avg_square_error = sum([
            (r - mean_odd_ratio)**2 for i, r in odd_ratio
        ]).sqrt() / len(odd_ratio)
        relative_pair_sq_err = mean_pair_ratio_avg_square_error / mean_pair_ratio
        relative_odd_sq_err = mean_odd_ratio_avg_square_error / mean_odd_ratio
        if relative_pair_sq_err > 0.5 or relative_odd_sq_err > 0.5:
            if all([
                    i[1] > 2
                    for i in (pair_ratio[3 * int(len(pair_ratio) / 4):] +
                              odd_ratio[3 * int(len(odd_ratio) / 4):])
            ]):

                approach_type = 'super_exp'
            else:
                approach_type = 'undefined'
        if (relative_odd_sq_err <= 0.5 and
                relative_pair_sq_err <= 0.5) or approach_type == 'super_exp':
            is_pair_exp = mean_pair_ratio > exponential_threshold
            is_odd_exp = mean_odd_ratio > exponential_threshold
            # in case one is exponential and the other isn't return 'mixed'
            if is_pair_exp ^ is_odd_exp:
                approach_type = 'mixed'
            elif is_pair_exp and is_odd_exp:
                if approach_type != 'super_exp':
                    approach_type = 'exp'
                approach_parameter_pair = mean_pair_ratio**type(
                    mean_pair_ratio)(0.5)
                approach_parameter_odd = mean_odd_ratio**type(mean_odd_ratio)(
                    0.5)
                approach_parameter = min(approach_parameter_pair,
                                         approach_parameter_odd)
                approach_coeff_pair_list = [
                    abs(delta_pair[i][1] *
                        approach_parameter**(delta_pair[i][0]) /
                        (1 - approach_parameter**(-2)))
                    for i in range(0, len(delta_pair))
                    if delta_pair[i][1] != 0 and not isnan(delta_pair[i][1])
                ]
                approach_coeff_pair = sum(approach_coeff_pair_list) / len(
                    approach_coeff_pair_list)
                approach_coeff_odd_list = [
                    abs(delta_odd[i][1] *
                        approach_parameter**(delta_odd[i][0]) /
                        (1 - approach_parameter**(-2)))
                    for i in range(0, len(delta_odd))
                    if delta_odd[i][1] != 0 and not isnan(delta_odd[i][1])
                ]
                approach_coeff_odd = sum(approach_coeff_odd_list) / len(
                    approach_coeff_odd_list)
                approach_coeff = min(approach_coeff_pair, approach_coeff_odd)
                approach_parameter = (approach_parameter, approach_coeff)
            else:
                approach_type = 'poly2sympoly'

        if approach_type != 'poly2sympoly' or not find_poly_parameter:
            return (approach_type, approach_parameter)

    #     We're requested to find the poly2sympoly parameter
        log_x_pair = [math.log(i) for i, d in delta_pair]
        log_y_pair = [math.log(d) for i, d in delta_pair]
        slope_pair, intercept_pair, r_value_pair, p_value_pair, std_err_pair = scipy.stats.linregress(
            log_x_pair, log_y_pair)
        log_x_odd = [math.log(i) for i, d in delta_odd]
        log_y_odd = [math.log(d) for i, d in delta_odd]
        slope_odd, intercept_odd, r_value_odd, p_value_odd, std_err_odd = scipy.stats.linregress(
            log_x_odd, log_y_odd)

        # TODO: replace the -1 by *0.95? need to make sure first what is the slop (is it negative?)
        approach_parameter = (min(abs(slope_pair), abs(slope_odd)) - 1,
                              min(intercept_pair, intercept_odd),
                              min(r_value_pair**2, r_value_odd**2))
        return (approach_type, approach_parameter)
def compute_points_individually(values, colors, convergence_iterations, iteration, stop_iteration_near, predefined_zones_of_attraction, f, compute_timeout):
    new_values = ['f**k']*len(values)
    new_colors = ['f**k']*len(colors)
    new_convergence_iterations = ['f**k']*len(convergence_iterations)
    # update values and colors matrices
    for i, val in enumerate(values):
        # don't reprocess errors
        if mpmath.isnan(val):
            new_values[i] = val
            new_colors[i] = colors[i]
            continue

        # stop iteration on values sufficiently close to, for instance zero
        if any([mpmath.almosteq(stop_iteration_value, val) for stop_iteration_value in stop_iteration_near]):
            new_values[i] = mpmath.nan
            new_colors[i] = (0.2588, 0.8314, 1.0)
            continue

        # sometimes convergence is too slow to measure with mathematical precision alone, so we predefine some zones of attraction where convergence is known
        # some examples are converging at a rate that slows the closer it is, or a decaying swirl that traces an infinite path length around the convergence point (but which still converges at infinity)
        satisfied_zone_of_attraction = False
        for condition, convergence_value in predefined_zones_of_attraction:
            if condition(val):
                new_values[i] = convergence_value
                new_colors[i] = 'converged'
                if colors[i] != 'converged':
                    new_convergence_iterations[i] = iteration
                else:
                    new_convergence_iterations[i] = convergence_iterations[i]
                satisfied_zone_of_attraction = True
                break
        if satisfied_zone_of_attraction == True:
            continue

        # try processing point
        try:
            new_val = func_timeout(compute_timeout, f, args=(val,))
        except FunctionTimedOut:
                new_values[i] = mpmath.nan
                new_colors[i] = (0.0, 0.0, 1.0)
        except OverflowError as e:
            if e.__str__() in ['int too large to convert to float',
                               'Python int too large to convert to C ssize_t',
                               'cannot convert float infinity to integer',
                               'too many digits in integer']:
                new_values[i] = mpmath.nan
                new_colors[i] = (0.0, 0.0, 1.0)
            else:
                reraise_error(val)
        except MemoryError:
                new_values[i] = mpmath.nan
                new_colors[i] = (0.0, 0.0, 1.0)
        except RecursionError:
                new_values[i] = mpmath.nan
                new_colors[i] = (0.0, 0.0, 1.0)
        except:  # handle unknown errors
            reraise_error(val)
        else: # color point according to normal math rules and store new value
            if mpmath.almosteq(new_val, val):
                new_colors[i] = 'converged'
                if colors[i] != 'converged':
                    new_convergence_iterations[i] = iteration
                else:
                    new_convergence_iterations[i] = convergence_iterations[i]
            else:
                new_colors[i] = (1.0, 1.0, 1.0)
            new_values[i] = new_val

    return new_values, new_colors, new_convergence_iterations