def TestStringRepresentations(): # Test string representations (note leading spaces) Julian.day_offset = mpf("0") Julian.interval_representation = "c" j1, j2 = mpf("2451545.0"), mpf("2451545.5") assert str(Julian(j1)) == " 1Jan2000:12:00" assert str(Julian(mpi(j1, j2))) == " <<1Jan2000:12:00, 2Jan2000:00:00>>" Julian.day_offset = mpf("0.5") assert str(Julian(j1)) == " 1Jan2000:00:00" assert str(Julian(mpi(j1, j2))) == " <<1Jan2000:00:00, 1Jan2000:12:00>>"
def check_spectral_norm(self, M, tolerance=1e-10): """ check iv_spectral_norm() and iv_spectral_norm_rough() against a numerical result from scipy. @param tolerance: assumed guaranteed relative tolerance on scipy's result """ approx_spectral_norm = scipy.linalg.norm( iv_matrix_to_numpy_ndarray(iv_matrix_mid_as_mp(M)), 2) self.assertIn(approx_spectral_norm, iv_spectral_norm(M) * (1 + tolerance * mp.mpi(-1, 1))) self.assertIn( approx_spectral_norm, iv_spectral_norm_rough(M) * (1 + tolerance * mp.mpi(-1, 1)))
def is_in(region1, region2): """ Returns True if the region1 is in the region2, returns False otherwise Args: region1 (list of pairs): (hyper)space defined by the regions region2 (list of pairs): (hyper)space defined by the regions """ if len(region1) is not len(region2): print("The intervals does not have the same size") return False for dimension in range(len(region1)): if mpi(region1[dimension]) not in mpi(region2[dimension]): return False return True
def test_special_printers(): class IntervalPrinter(LambdaPrinter): """Use ``lambda`` printer but print numbers as ``mpi`` intervals. """ def _print_Integer(self, expr): return "mpi('%s')" % super(IntervalPrinter, self)._print_Integer(expr) def _print_Rational(self, expr): return "mpi('%s')" % super(IntervalPrinter, self)._print_Rational(expr) def intervalrepr(expr): return IntervalPrinter().doprint(expr) expr = sqrt(sqrt(2) + sqrt(3)) + S(1) / 2 func0 = lambdify((), expr, modules="mpmath", printer=intervalrepr) func1 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter) func2 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter()) mpi = type(mpmath.mpi(1, 2)) assert isinstance(func0(), mpi) assert isinstance(func1(), mpi) assert isinstance(func2(), mpi)
def test_special_printers(): from sympy.printing.lambdarepr import IntervalPrinter def intervalrepr(expr): return IntervalPrinter().doprint(expr) expr = sqrt(sqrt(2) + sqrt(3)) + S.Half func0 = lambdify((), expr, modules="mpmath", printer=intervalrepr) func1 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter) func2 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter()) mpi = type(mpmath.mpi(1, 2)) assert isinstance(func0(), mpi) assert isinstance(func1(), mpi) assert isinstance(func2(), mpi) # To check Is lambdify loggamma works for mpmath or not exp1 = lambdify(x, loggamma(x), 'mpmath')(5) exp2 = lambdify(x, loggamma(x), 'mpmath')(1.8) exp3 = lambdify(x, loggamma(x), 'mpmath')(15) exp_ls = [exp1, exp2, exp3] sol1 = mpmath.loggamma(5) sol2 = mpmath.loggamma(1.8) sol3 = mpmath.loggamma(15) sol_ls = [sol1, sol2, sol3] assert exp_ls == sol_ls
def iv_P_norm_expm(P_sqrt_T, M1, A, M2, tau): """ Bound on P-ellipsoid norm of (M1 (expm(A*t) - I) M2) for |t| < tau using the theorem in arXiv:1911.02537, section "Norm bounding of summands" @param P_sqrt_T: see iv_P_norm() """ P_sqrt_T = iv.matrix(P_sqrt_T) M1 = iv.matrix(M1) A = iv.matrix(A) M2 = iv.matrix(M2) # coerce tau to maximum tau = abs(iv.mpf(tau)).b # P-ellipsoid norms M1_p = iv_P_norm(M=M1, P_sqrt_T=P_sqrt_T) M2_p = iv_P_norm(M=M2, P_sqrt_T=P_sqrt_T) A_p = iv_P_norm(M=A, P_sqrt_T=P_sqrt_T) # A_pow[i] = A ** i A_pow = _iv_matrix_powers(A) # Work around bug in mpmath, see comment in iv_P_norm() zero = iv.matrix(mp.zeros(len(A))) M1 = zero + M1 # terms from [arXiv:1911.02537] M1_Ai_M2_p = lambda i: iv_P_norm(M=M1 @ A_pow[i] @ M2, P_sqrt_T=P_sqrt_T) gamma = lambda i: 1 / math.factorial(i) * (M1_Ai_M2_p(i) - M1_p * A_p ** i * M2_p) max_norm = sum([gamma(i) * (tau ** i) for i in range(1, IV_NORM_EVAL_ORDER + 1)]) + M1_p * M2_p * (iv.exp(A_p * tau) - 1) # the lower bound is always 0 (for t=0) return mp.mpi([0, max_norm.b])
def LDL(mat): """ Algorithm for numeric LDL factization, exploiting sparse structure. This function is a modification of scipy.sparse.SparseMatrix._LDL_sparse, allowing mpmath.mpi interval arithmetic objects as entries. L, D are SparseMatrix objects. However we assign values through _smat member to avoid type conversions to Rational. """ Lrowstruc = mat.row_structure_symbolic_cholesky() print 'Number of entries in L: ', np.sum(map(len, Lrowstruc)) L = SparseMatrix(mat.rows, mat.rows, dict([((i, i), mpi(0)) for i in range(mat.rows)])) D = SparseMatrix(mat.rows, mat.cols, {}) for i in range(len(Lrowstruc)): for j in Lrowstruc[i]: if i != j: L._smat[(i, j)] = mat._smat.get((i, j), mpi(0)) summ = 0 for p1 in Lrowstruc[i]: if p1 < j: for p2 in Lrowstruc[j]: if p2 < j: if p1 == p2: summ += L[i, p1]*L[j, p1]*D[p1, p1] else: break else: break L._smat[(i, j)] = L[i, j] - summ L._smat[(i, j)] = L[i, j] / D[j, j] elif i == j: D._smat[(i, i)] = mat._smat.get((i, i), mpi(0)) summ = 0 for k in Lrowstruc[i]: if k < i: summ += L[i, k]**2*D[k, k] else: break D._smat[(i, i)] -= summ return L, D
def test_mpmath_intervals(self): print(colored('mpi math sanity check', 'blue')) ## Check more here https://docs.sympy.org/0.6.7/modules/mpmath/basics.html ## Sanity check test from mpmath import mpi ## Real intervals my_interval = mpi(0, 5) self.assertEqual(my_interval.a, 0) self.assertEqual(my_interval.b, 5) self.assertEqual(my_interval.mid, (5+0)/2) self.assertEqual(my_interval.delta, abs(0-5))
def _iv_matrix_powers(A): """ return the first IV_NORM_EVAL_ORDER+1 powers of A: [I, A, A**2, ..., A**(IV_NORM_EVAL_ORDER)] """ assert isinstance(A, iv.matrix) A = iv.matrix(A) + mp.mpi(0,0) # workaround bug A_pow = [iv.eye(len(A))] for i in range(IV_NORM_EVAL_ORDER+1): A_pow.append(A @ A_pow[-1]) return A_pow
def test_rel_tolerance(tol, matrixClass): """ test with given relative deviation """ lower = 1e3 * matrixClass.eye(4) if matrixClass == generic_matrix.IntervalMatrix: upper = lower * mp.mpi(1 - tol / 2, 1 + tol / 2) else: upper = lower * (1 + tol) self.assertMatrixAlmostEqual(lower, upper)
def iv_matrix_mid_to_numpy_ndarray(M): """ convert midpoint of interval matrix to numpy ndarray """ if isinstance(M, numpy.ndarray): return M Y = numpy.zeros((M.rows, M.cols)) for i in range(M.rows): for j in range(M.cols): Y[i, j] = float(mp.mpf(mp.mpi(M[i, j]).mid)) return Y
def test_abs_tolerance(tol, matrixClass): """ test with given absolute deviation """ lower = 1e-3 * matrixClass.eye(4) if matrixClass == generic_matrix.IntervalMatrix: upper = lower + matrixClass.ones(4, 4) * mp.mpi( -tol / 2, tol / 2) else: upper = lower + tol * matrixClass.ones(4, 4) self.assertMatrixAlmostEqual(lower, upper)
def m1_a_m2_tau_uy(self, u_index, y_index): """ constituent parts of Delta_A_uy_i_j = M1 * (exp(A*t)-I) * M2, |t|<tau: (M1, A, M2, tau, info_string) = m1_a_m2_tau_uy(i,j) info_string is a textual identifier """ d = self.abstract_matrix_type # tau = max(delta t_u - delta t_y) maximized over the range delta_t_u_min ... _max and delta_t_y_min ... _max dtu = mp.mpi(self.sys.delta_t_u_min[u_index], self.sys.delta_t_u_max[u_index]) dty = mp.mpi(self.sys.delta_t_y_min[y_index], self.sys.delta_t_y_max[y_index]) tau = ( dty - dtu ).b # max(dty_j - dtu_i) for the given intervals of dty_j and dtu_i tau = d.convert_scalar(tau) # convert to float if required if tau < 0: tau = 0 return (self.A_ctrl @ (self.A_y[y_index] - d.eye(self.n)), self.A_cont, self.A_u[u_index] - d.eye(self.n), tau, "u {} combined with y {}".format(u_index, y_index))
def v(self, s): '''Interval numbers: allowed forms are 1. 'a +- b' 2. 'a (b%)' % sign is optional 3. '[a, b]' In 1, a is the midpoint of the interval and b is the half-width. In 2, a is the midpoint of the interval and b is the half-width. In 3, the interval is indicated directly. ''' e = ValueError("Improperly formed interval number '%s'" %s) s = s.replace(" ", "") if "+-" in s: n = [mpf(strip(i)) for i in s.split("+-")] return mpi(n[0] - n[1], n[0] + n[1]) elif "(" in s: if s[0] == "(": # Don't confuse with a complex number (x,y) return None if ")" not in s: raise e s = s.replace(")", "") percent = False if "%" in s: if s[-1] != "%": raise e percent = True s = s.replace("%", "") a, p = [mpf(strip(i)) for i in s.split("(")] d = p if percent: d = a*p/mpf(100) return mpi(a - d, a + d) elif "," in s: if "[" not in s: raise e if "]" not in s: raise e s = s.replace("[", "") s = s.replace("]", "") n = [mpf(strip(i)) for i in s.split(",")] return mpi(n[0], n[1]) else: return None
def mpiTests(): # Test with mpi's onep2 = mpi("1", "2") third = Rational(1,3) # add assert no_idiff(onep2 + third, onep2 + 1/mpi(3)) # radd assert no_idiff(third + onep2, onep2 + 1/mpi(3)) # sub assert no_idiff(onep2 - third, onep2 - 1/mpi(3)) # rsub assert no_idiff(third - onep2, -onep2 + 1/mpi(3)) # mul assert no_idiff(onep2 * third, onep2 * 1/mpi(3)) # rmul assert no_idiff(third * onep2, onep2 * 1/mpi(3)) # div assert no_idiff(onep2 / third, onep2 /(1/mpi(3))) # rdiv assert no_idiff(third / onep2, (1/mpi(3)) / onep2)
def iv_matrix_mid_as_mp(M): """ entrywise midpoint of interval matrix, as (non-interval) mpmath matrix. If the input is a mpmath matrix, it is returned unchanged. If the input is a 2-dimensional numpy.ndarray, it is converted to mpmath. """ if isinstance(M, numpy.ndarray): return mp.matrix(M) Y = mp.matrix(M.rows, M.cols) for i in range(M.rows): for j in range(M.cols): Y[i, j] = mp.mpi(M[i, j]).mid return Y
def ParseRawData(show=False): '''Set show to True to have the names printed to stdout. ''' def Compact(s): return s.replace(" ", "") # Locations of fields in data locations = { "name": (0, 55), "value": (55, 77), "uncertainty": (77, 98), } s = StringIO(raw_data) lines = s.readlines() constants = {} fix = 1 for line in lines: line = line.strip() if not line: continue a, b = locations["name"] name = line[a:b].strip() a, b = locations["value"] value = Compact(line[a:b]) a, b = locations["uncertainty"] uncertainty = Compact(line[a:b]) if fix: if uncertainty == "(exact)": uncertainty = 0 if "..." in value: value = value.replace("...", "") try: x = mpf(value) dx = mpf(uncertainty) if dx == 0: num = x else: num = mpi(x - dx, x + dx) constants[name] = num except Exception as e: print(name) print(" ", str(e)) names = list(constants.keys()) names.sort() if show: for name in names: print(name) return constants
def test_special_printers(): from sympy.polys.numberfields import IntervalPrinter def intervalrepr(expr): return IntervalPrinter().doprint(expr) expr = sqrt(sqrt(2) + sqrt(3)) + S(1)/2 func0 = lambdify((), expr, modules="mpmath", printer=intervalrepr) func1 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter) func2 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter()) mpi = type(mpmath.mpi(1, 2)) assert isinstance(func0(), mpi) assert isinstance(func1(), mpi) assert isinstance(func2(), mpi)
def ParseRawData(show=False): '''Set show to True to have the names printed to stdout. ''' def Compact(s): return s.replace(" ", "") # Locations of fields in data locations = { "name" : (0, 55), "value" : (55, 77), "uncertainty" : (77, 98), } s = StringIO(raw_data) lines = s.readlines() constants = {} fix = 1 for line in lines: line = strip(line) if not line: continue a, b = locations["name"] name = strip(line[a:b]) a, b = locations["value"] value = Compact(line[a:b]) a, b = locations["uncertainty"] uncertainty = Compact(line[a:b]) if fix: if uncertainty == "(exact)": uncertainty = 0 if "..." in value: value = value.replace("...", "") try: x = mpf(value) dx = mpf(uncertainty) if dx == 0: num = x else: num = mpi(x-dx, x+dx) constants[name] = num except Exception, e: print name print " ", str(e)
def compute_strategy(self): if self.tau() > 1: # self.repetition -= 1 # if self.repetition: # return self.last_strategy # else: # self.repetition = self.n_rep p = 0.5 / (self.tau() ** self.power) b = (self.norm_const * sqrt(-log(p) / (self.tau()))) interval = mpmath.mpi(self.avg_loss - b, self.avg_loss + b) for p in sorted(self.profiles, key=lambda x: self.exp_adv_loss[x]): if self.exp_adv_loss[p] in interval: # print("exp_loss", self.exp_adv_loss[p], "is in", interval) # print("with b", b, "and avg_loss", self.avg_loss) return p.get_best_responder().compute_strategy() # print("unknown") # MODIFY to take into account the not-Unknown case # if I have not returned yet, then I must use fpl return super().compute_strategy()
def check_qlf_bounds(self, P_sqrt_T, M, abstractmatrix: AbstractMatrix): """ test qlf_upper_bound, qlf_lower_bound for given matrices P_sqrt_T, M with random vectors x. """ c1 = abstractmatrix.qlf_upper_bound(P_sqrt_T, M) # c1 sqrt(V(Mx)) <= |x| c2 = abstractmatrix.qlf_lower_bound(P_sqrt_T, M) # |Mx| <= c2 sqrt(V(x)) def sqrt_V(x): """ V(x) = x.T P_sqrt_T.T P_sqrt_T x. """ return np.sqrt(x.T @ P_sqrt_T.T @ P_sqrt_T @ x) def mag(x): """ |x| """ return np.sqrt(np.sum(x**2)) M_actual = M if M_actual is None: M_actual = np.eye(len(P_sqrt_T)) RELTOL = 1e-10 for i in range(100): x = np.random.uniform(low=-42, high=+42, size=len(P_sqrt_T)) # c1 sqrt(V(Mx)) <= |x| if not mp.iv.isnan(c1) and c1 != mp.mpi( '-inf', '+inf') and not mp.iv.isinf(c1): self.assertLessEqual(c1 * sqrt_V(M_actual @ x), mag(x) * (1 + RELTOL)) # |Mx| <= c2 sqrt(V(x)) self.assertLessEqual(mag(M_actual @ x), c2 * sqrt_V(x) * (1 + RELTOL))
def test_special_printers(): class IntervalPrinter(LambdaPrinter): """Use ``lambda`` printer but print numbers as ``mpi`` intervals.""" def _print_Integer(self, expr): return f"mpi('{super()._print_Integer(expr)}')" def _print_Rational(self, expr): return f"mpi('{super()._print_Rational(expr)}')" def intervalrepr(expr): return IntervalPrinter().doprint(expr) expr = diofant.sqrt(diofant.sqrt(2) + diofant.sqrt(3)) + diofant.Rational( 1, 2) func0 = lambdify((), expr, modules='mpmath', printer=intervalrepr) func1 = lambdify((), expr, modules='mpmath', printer=IntervalPrinter) func2 = lambdify((), expr, modules='mpmath', printer=IntervalPrinter()) mpi = type(mpmath.mpi(1, 2)) assert isinstance(func0(), mpi) assert isinstance(func1(), mpi) assert isinstance(func2(), mpi)
def test_special_printers(): class IntervalPrinter(LambdaPrinter): """Use ``lambda`` printer but print numbers as ``mpi`` intervals. """ def _print_Integer(self, expr): return "mpi('%s')" % super(IntervalPrinter, self)._print_Integer(expr) def _print_Rational(self, expr): return "mpi('%s')" % super(IntervalPrinter, self)._print_Rational(expr) def intervalrepr(expr): return IntervalPrinter().doprint(expr) expr = sympy.sqrt(sympy.sqrt(2) + sympy.sqrt(3)) + sympy.S(1)/2 func0 = lambdify((), expr, modules="mpmath", printer=intervalrepr) func1 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter) func2 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter()) mpi = type(mpmath.mpi(1, 2)) assert isinstance(func0(), mpi) assert isinstance(func1(), mpi) assert isinstance(func2(), mpi)
def list_of_basis(N,weight,prec=501,tol=1e-20,sv_min=1E-1,sv_max=1E15,set_dim=None): r""" Returns a list of pairs (r,D) forming a basis """ # First we find the smallest Discriminant for each of the components if(set_dim<>None and set_dim >0): dim=set_dim else: dim=dimension_jac_cusp_forms(int(weight+0.5),N,-1) basislist=dict() num_gotten=0 co_tmp=dict() num_gotten=0 C0=1 RF=RealField(prec) if(silent>1): print "N=",N print "dim=",dim print "sv_min=",sv_min print "sv_max=",sv_max Aold=Matrix(RF,1) tol0=1E-20 #tol # we start with the first discriminant, then the second etc. Z2N=IntegerModRing(2*N) ZZ4N=IntegerModRing(4*N) for Dp in [1..max(1000,100*dim)]: D=-Dp # we use the dual of the Weil representation D4N=ZZ4N(D) if(not(is_square(D4N))): continue for r in my_modsqrt(D4N,N): # I want to make sure that P_{(D,r)} is independent from the previously computed functions # The only sure way to do this is to compute all submatrices (to a much smaller precision than what we want at the end) # The candidate is [D,r] and we need to compute the vector of [D,r,D',r'] # for all D',r' already in the list ltmp1=dict() ltmp2=dict() j=0 for [Dp,rp] in basislist.values(): ltmp1[j]=[D,r,Dp,rp] ltmp2[j]=[Dp,rp,D,r] j=j+1 ltmp1[j]=[D,r,D,r] #print "Checking: D,r,D,r=",ltmp1 ctmp1=ps_coefficients_holomorphic_vec(N,weight,ltmp1,tol0) # print "ctmp1=",ctmp1 if(j >0): #print "Checking: D,r,Dp,rp=",ltmp2 # Data is ok?: {0: True} ctmp2=ps_coefficients_holomorphic_vec(N,weight,ltmp2,tol0) # print "ctmp2=",ctmp2 #print "num_gotten=",num_gotten A=matrix(RF,num_gotten+1) # The old matrixc with the elements that are already added to the basis # print "Aold=\n",A,"\n" # print "num_gotten=",num_gotten # print "Aold=\n",Aold,"\n" for k in range(Aold.nrows()): for l in range(Aold.ncols()): A[k,l]=Aold[k,l] # endfor # print "A set by old=\n",A,"\n" # Add the (D',r',D,r) for each D',r' in the list tmp=RF(1.0) for l in range(num_gotten): # we do not use the scaling factor when # determining linear independence # mm=RF(abs(ltmp2[l][0]))/N4 # tmp=RF(mm**(weight-one)) A[num_gotten,l]=ctmp2['data'][l]*tmp # Add the (D,r,D',r') for each D',r' in the list # print "ctmp1.keys()=",ctmp1.keys() for l in range(num_gotten+1): #mm=RF(abs(ltmp1[l][2]))/4N #tmp=RF(mm**(weight-one)) # print "scaled with=",tmp.n(200) A[l,num_gotten]=ctmp1['data'][l]*tmp #[d,B]=mat_inverse(A) # d=det(A) #if(silent>1): #d=det(A) #print "det A = ",d # Now we have to determine whether we have a linearly independent set or not dold=mpmath.mp.dps mpmath.mp.dps=int(prec/3.3) AInt=mpmath.matrix(int(A.nrows()),int(A.ncols())) AMp=mpmath.matrix(int(A.nrows()),int(A.ncols())) if(silent>0): print "tol0=",tol0 for ir in range(A.nrows()): for ik in range(A.ncols()): AInt[ir,ik]=mpmath.mp.mpi(A[ir,ik]-tol0,A[ir,ik]+tol0) AMp[ir,ik]=mpmath.mpf(A[ir,ik]) d=mpmath.det(AMp) di=mpmath.mp.mpi(mpmath.mp.det(AInt)) #for ir in range(A.nrows()): # for ik in range(A.ncols()): # #print "A.d=",AInt[ir,ik].delta if(silent>0): print "mpmath.mp.dps=",mpmath.mp.dps print "det(A)=",d print "det(A-as-interval)=",di print "d.delta=",di.delta #if(not mpmath.mpi(d) in di): # raise ArithmeticError," Interval determinant not ok?" #ANP=A.numpy() #try: # u,s,vnp=svd(ANP) # s are the singular values # sl=s.tolist() # mins=min(sl) # the smallest singular value # maxs=max(sl) # if(silent>1): # print "singular values = ",s #except LinAlgError: # if(silent>0): # print "could not compute SVD!" # print "using abs(det) instead" # mins=abs(d) # maxs=abs(d) #if((mins>sv_min and maxs< sv_max)): zero=mpmath.mpi(0) if(zero not in di): if(silent>1): print "Adding D,r=",D,r basislist[num_gotten]=[D,r] num_gotten=num_gotten+1 if(num_gotten>=dim): return basislist else: #print "setting Aold to A" Aold=A else: if(silent>1): print " do not use D,r=",D,r # endif mpmath.mp.dps=dold # endfor if(num_gotten < dim): raise ValueError," did not find enough good elements for a basis list!"
def test_interval_to_mpi(): assert Interval(0, 1).to_mpi() == mpi(0, 1) assert Interval(0, 1, True, False).to_mpi() == mpi(0, 1) assert type(Interval(0, 1).to_mpi()) == type(mpi(0, 1))
# Rational numbers Rational(3, 8) : ( "3/8", "6/16", "0 12/32", "0-15/40", "0+18/48", ), Rational(-3, 7) : ( "-3/7", "-6/14", "-0 12/28", "-0-15/35", "-0+18/42", ), Rational(3, -7) : ( "-3/7", "-6/14", "-0 12/28", "-0-15/35", "-0+18/42", ), } # Because of a bug in mpi == and != tests, we have to test them # differently. mpi_tests = { # Interval numbers mpi(1, 3) : ( "[1, 3]", "[1.0, 3]", "[1, 3.0]", "[1.0, 3.0]", "[1,3]", "[1.0,3]", "[1,3.0]", "[1.0,3.0]", "[ 1, 3]", "[ 1.0,3]", "[ 1, 3.0]", "1.5 +- 0.5", "1.5+-0.5", "1.5+- 0.5", "1.5 +-0.5", "1.5 +- 0.5", "15e-1 +- 500e-3", "1.5(33.33333333333333333333%)", "1.5 (33.33333333333333333333%)", "1.5 ( 33.33333333333333333333%)", "1.5 ( 33.33333333333333333333 % )", "1.5( 33.33333333333333333333 % )", "1.5(33.33333333333333333333 % )", ), } n = Number() status = 0
def test_Interval(self): print(colored("Interval test here", 'blue')) self.assertEqual(1.0 in mpi(1, 1), True) self.assertEqual(1.0 in mpi(1, 2), True) self.assertEqual(1.0 in mpi(0, 1), True) self.assertEqual(1.0 in mpi(0, 2), True) self.assertEqual(5.0 not in mpi(1, 1), True) self.assertEqual(5.0 not in mpi(1, 2), True) self.assertEqual(5.0 not in mpi(0, 1), True) self.assertEqual(5.0 not in mpi(0, 2), True) self.assertEqual(mpi(1, 1) in mpi(1, 1), True) self.assertEqual(mpi(1, 1) in mpi(1, 2), True) self.assertEqual(mpi(1, 1) in mpi(0, 1), True) self.assertEqual(mpi(1, 1) in mpi(0, 2), True) self.assertEqual(mpi(1, 2) in mpi(1, 3), True) self.assertEqual(mpi(1, 2) in mpi(0, 2), True) self.assertEqual(mpi(1, 2) in mpi(0, 3), True) self.assertEqual(mpi(1, 2) not in mpi(0, 1), True) self.assertEqual(mpi(1, 2) not in mpi(2, 3), True) self.assertEqual(mpi(1, 2) not in mpi(1.5, 2), True)
def test_interval_to_mpi(): assert Interval(0, 1).to_mpi() == mpi(0, 1) assert Interval(0, 1, True, False).to_mpi() == mpi(0, 1) assert isinstance(Interval(0, 1).to_mpi(), type(mpi(0, 1)))
def list_of_basis(N, weight, prec=501, tol=1e-20, sv_min=1E-1, sv_max=1E15, set_dim=None): r""" Returns a list of pairs (r,D) forming a basis """ # First we find the smallest Discriminant for each of the components if (set_dim <> None and set_dim > 0): dim = set_dim else: dim = dimension_jac_cusp_forms(int(weight + 0.5), N, -1) basislist = dict() num_gotten = 0 co_tmp = dict() num_gotten = 0 C0 = 1 RF = RealField(prec) if (silent > 1): print "N=", N print "dim=", dim print "sv_min=", sv_min print "sv_max=", sv_max Aold = Matrix(RF, 1) tol0 = 1E-20 #tol # we start with the first discriminant, then the second etc. Z2N = IntegerModRing(2 * N) ZZ4N = IntegerModRing(4 * N) for Dp in [1..max(1000, 100 * dim)]: D = -Dp # we use the dual of the Weil representation D4N = ZZ4N(D) if (not (is_square(D4N))): continue for r in my_modsqrt(D4N, N): # I want to make sure that P_{(D,r)} is independent from the previously computed functions # The only sure way to do this is to compute all submatrices (to a much smaller precision than what we want at the end) # The candidate is [D,r] and we need to compute the vector of [D,r,D',r'] # for all D',r' already in the list ltmp1 = dict() ltmp2 = dict() j = 0 for [Dp, rp] in basislist.values(): ltmp1[j] = [D, r, Dp, rp] ltmp2[j] = [Dp, rp, D, r] j = j + 1 ltmp1[j] = [D, r, D, r] #print "Checking: D,r,D,r=",ltmp1 ctmp1 = ps_coefficients_holomorphic_vec(N, weight, ltmp1, tol0) # print "ctmp1=",ctmp1 if (j > 0): #print "Checking: D,r,Dp,rp=",ltmp2 # Data is ok?: {0: True} ctmp2 = ps_coefficients_holomorphic_vec(N, weight, ltmp2, tol0) # print "ctmp2=",ctmp2 #print "num_gotten=",num_gotten A = matrix(RF, num_gotten + 1) # The old matrixc with the elements that are already added to the basis # print "Aold=\n",A,"\n" # print "num_gotten=",num_gotten # print "Aold=\n",Aold,"\n" for k in range(Aold.nrows()): for l in range(Aold.ncols()): A[k, l] = Aold[k, l] # endfor # print "A set by old=\n",A,"\n" # Add the (D',r',D,r) for each D',r' in the list tmp = RF(1.0) for l in range(num_gotten): # we do not use the scaling factor when # determining linear independence # mm=RF(abs(ltmp2[l][0]))/N4 # tmp=RF(mm**(weight-one)) A[num_gotten, l] = ctmp2['data'][l] * tmp # Add the (D,r,D',r') for each D',r' in the list # print "ctmp1.keys()=",ctmp1.keys() for l in range(num_gotten + 1): #mm=RF(abs(ltmp1[l][2]))/4N #tmp=RF(mm**(weight-one)) # print "scaled with=",tmp.n(200) A[l, num_gotten] = ctmp1['data'][l] * tmp #[d,B]=mat_inverse(A) # d=det(A) #if(silent>1): #d=det(A) #print "det A = ",d # Now we have to determine whether we have a linearly independent set or not dold = mpmath.mp.dps mpmath.mp.dps = int(prec / 3.3) AInt = mpmath.matrix(int(A.nrows()), int(A.ncols())) AMp = mpmath.matrix(int(A.nrows()), int(A.ncols())) if (silent > 0): print "tol0=", tol0 for ir in range(A.nrows()): for ik in range(A.ncols()): AInt[ir, ik] = mpmath.mp.mpi(A[ir, ik] - tol0, A[ir, ik] + tol0) AMp[ir, ik] = mpmath.mpf(A[ir, ik]) d = mpmath.det(AMp) di = mpmath.mp.mpi(mpmath.mp.det(AInt)) #for ir in range(A.nrows()): # for ik in range(A.ncols()): # #print "A.d=",AInt[ir,ik].delta if (silent > 0): print "mpmath.mp.dps=", mpmath.mp.dps print "det(A)=", d print "det(A-as-interval)=", di print "d.delta=", di.delta #if(not mpmath.mpi(d) in di): # raise ArithmeticError," Interval determinant not ok?" #ANP=A.numpy() #try: # u,s,vnp=svd(ANP) # s are the singular values # sl=s.tolist() # mins=min(sl) # the smallest singular value # maxs=max(sl) # if(silent>1): # print "singular values = ",s #except LinAlgError: # if(silent>0): # print "could not compute SVD!" # print "using abs(det) instead" # mins=abs(d) # maxs=abs(d) #if((mins>sv_min and maxs< sv_max)): zero = mpmath.mpi(0) if (zero not in di): if (silent > 1): print "Adding D,r=", D, r basislist[num_gotten] = [D, r] num_gotten = num_gotten + 1 if (num_gotten >= dim): return basislist else: #print "setting Aold to A" Aold = A else: if (silent > 1): print " do not use D,r=", D, r # endif mpmath.mp.dps = dold # endfor if (num_gotten < dim): raise ValueError, " did not find enough good elements for a basis list!"
def gram_matrix(N,weight,prec=501,tol=1E-40,sv_min=1E-1,sv_max=1E15,bl=None,set_dim=None,force_prec=False): r""" Computes a matrix of p_{r,D}(r',D') for a basis of P_{r,D}, i.e. dim linearly independent P's INPUT: N = Integer weight = Real OPTIONAL: tol = error bound for the Poincaré series sv_min = minimal allowed singular value when determining whether a given set is linarly independent or not. sv_max = maximally allowed singular value bl = list of pairs (D_i,r_i) from which we compute a matrix of coeffficients p_{D_i,r_i}(D_j,r_j) """ # If we have supplied a list of D's and r's we make a gram matrix relative to these # otherwise we find a basis, i.e. linearly independent forms with correct dimension # find the dimension wt='%.4f'% weight if(N<10): stN="0"+str(N) else: stN=str(N) v=dict() filename_work="__N"+stN+"-"+wt+"--finding basis.txt" fp=open(filename_work,"write") fp.write("starting to find basis") fp.close() if(silent>0): print "Forcing precision:",force_prec set_silence_level(0) if(bl<>None): dim=len(bl) l=bl else: if(set_dim<>None and set_dim >0): dim=set_dim else: dim=dimension_jac_cusp_forms(int(weight+0.5),N,-1) l=list_of_basis(N,weight,prec,tol,sv_min,sv_max,set_dim=dim) j=0 for [D,r] in l.values(): for [Dp,rp] in l.values(): # Recall that the gram matrix is symmetric. We need only compute the upper diagonal if(v.values().count([Dp,rp,D,r])==0): v[j]=[D,r,Dp,rp] j=j+1 # now v is a list we can get into computing coefficients # first we print the "gram data" (list of indices) to the file s=str(N)+": (AI["+str(N)+"],[" indices=dict() for j in range(len(l)): Delta=l[j][0] r=l[j][1] diff=(r*r-Delta) % (4*N) if(diff<>0): raise ValueError, "ERROR r^2=%s not congruent to Delta=%s mod %s!" %(r*r, Delta, 4*N) s=s+"("+str(Delta)+","+str(r)+")" indices[j]=[Delta,r] if(j<len(l)-1): s=s+"," else: s=s+"])," s=s+"\n" if(silent>0): print s+"\n" filename2="PS_Gramdata"+stN+"-"+wt+".txt" fp=open(filename2,"write") fp.write(s) fp.close() try: os.remove(filename_work) except os.error: print "Could not remove file:",filename_work pass filename_work="__N"+stN+"-"+wt+"--computing_gram_matrix.txt" fp=open(filename_work,"write") fp.write("") fp.close() #print "tol=",tol #set_silence_level(2) #print "force_prec(gram_mat)=",force_prec res=ps_coefficients_holomorphic_vec(N,weight,v,tol,prec,force_prec=force_prec) set_silence_level(0) res['indices']=indices maxerr=0.0 for j in res['errs'].keys(): tmperr=abs(res['errs'][j]) #print "err(",j,")=",tmperr if(tmperr>maxerr): maxerr=tmperr # switch format for easier vewing res['errs'][j]=RR(tmperr) if(silent>0): print "maxerr=",RR(maxerr) res['maxerr']=maxerr wt_phalf='%.4f'% (weight+0.5) filename3="PS_Gramerr"+stN+"-"+wt+".txt" fp=open(filename3,"write") wt s="MAXERR["+wt_phalf+"]["+stN+"]="+str(RR(maxerr)) fp.write(s) fp.close() if(res['ok']): Cps=res['data'] else: print "Failed to compute Fourier coefficients!" return 0 RF=RealField(prec) A=matrix(RF,dim) kappa=weight fourpi=RF(4.0)*pi.n(prec) one=RF(1.0) N4=RF(4*N) C=dict() if(silent>1): print "v=",v print "dim=",dim lastix=0 # First set the upper right part of A for j in range(dim): ddim=dim-j if(silent>1): print "j=",j,"ddim=",ddim," lastix=",lastix for k in range(0,ddim): # need to scale with |D|^(k+0.5) if(silent>1): print "k=",k print "lastix+k=",lastix+k mm=RF(abs(v[lastix+k][0]))/N4 tmp=RF(mm**(weight-one)) if(silent>1): print "ddim+k=",ddim+k A[j,j+k]=Cps[lastix+k]*tmp C[v[lastix+k][0],v[lastix+k][1]]=Cps[lastix+k] lastix=lastix+k+1 # And add the lower triangular part to mak the matrix symmetric for j in range(dim): for k in range(0,j): A[j,k]=A[k,j] # And print the gram matrix res['matrix']=A dold=mpmath.mp.dps mpmath.mp.dps=int(prec/3.3) AInt=mpmath.matrix(int(A.nrows()),int(A.ncols())) AMp=mpmath.matrix(int(A.nrows()),int(A.ncols())) for ir in range(A.nrows()): for ik in range(A.ncols()): AInt[ir,ik]=mpmath.mpi(A[ir,ik]-tol,A[ir,ik]+tol) AMp[ir,ik]=mpmath.mpf(A[ir,ik]) d=mpmath.det(AMp) if(silent>1): print "det(A-as-mpmath)=",d di=mpmath.det(AInt) if(silent>1): print "det(A-as-interval)=",di res['det']=(RF(di.a),RF(di.b)) filename="PS_Gram"+stN+"-"+wt+".txt" if(silent>1): print "printing to file: "+filename print_matrix_to_file(A,filename,'A['+str(N)+']') if(silent>1): print "A-A.transpose()=",norm(A-A.transpose()) B=A^-1 #[d,B]=mat_inverse(A) if(silent>1): print "A=",A.n(100) print "det(A)=",di print "Done making inverse!" #res['det']=d res['inv']=B mpmath.mp.dps=dold filename="PS_Gram-inv"+stN+"-"+wt+".txt" print_matrix_to_file(B,filename,' AI['+str(N)+']') # first make the filename s='%.1e'%tol filename3="PS_Coeffs"+stN+"-"+wt+"-"+s+".sobj" # If the file already exist we load it and append the new data if(silent>0): print "saving data to ",filename3 try: f=open(filename3,"read") except IOError: if(silent>0): print "no file before!" # do nothing else: if(silent>0): print "file: "+filename3+" exists!" f.close() Cold=load(filename3) for key in Cold.keys(): # print"key:",key if(not C.has_key(key)): # then we addd it print"key:",key," does not exist in the new version!" C[key]=Cold[key] save(C,filename3) ## Save the whole thing filename="PS_all_gram"+stN+"-"+wt+".sobj" save(res,filename) ## our work is comleted and we can remove the file try: os.remove(filename_work) except os.error: print "Could not remove file:",filename_work pass return res
Entries assumed to be integers. """ f = open(filename) v = np.array(eval(f.readline()), dtype=int) f.close() ind = np.array(v, dtype=int)[:, :2] val = np.array(v)[:, 2] return ss.csc_matrix((val, (ind[:, 0], ind[:, 1]))) text = open('results/ldl_mpi.txt', 'w') for number in range(1, 21): positive = get_matrix('./results/CHOLMOD_permuted/permuted{}.txt'.format(number)) size = max(positive.indices)+1 print >>text, 'Domain {}:'.format(number) print >>text, 'Number of entries: ', len(positive.data) # change integers into mpi intervals print >>text, 'Entries :', np.unique(positive.data) positive.data = map(lambda x: mpi(x), positive.data) positive = positive.todok() sympy_positive = SparseMatrix(size, size, positive) L, D = LDL(sympy_positive) D = D._smat.values() delta = [x.delta/x.mid for x in D] print >>text, "The smallest diagonal element in LDL': ", min(D) print >>text, 'Ratio largest/smallest : ', max(D)/min(D) print >>text, "Maximal relative delta around diagonal elements: ", max(delta) print >>text, '\n' text.close()
def gram_matrix(N, weight, prec=501, tol=1E-40, sv_min=1E-1, sv_max=1E15, bl=None, set_dim=None, force_prec=False): r""" Computes a matrix of p_{r,D}(r',D') for a basis of P_{r,D}, i.e. dim linearly independent P's INPUT: N = Integer weight = Real OPTIONAL: tol = error bound for the Poincaré series sv_min = minimal allowed singular value when determining whether a given set is linarly independent or not. sv_max = maximally allowed singular value bl = list of pairs (D_i,r_i) from which we compute a matrix of coeffficients p_{D_i,r_i}(D_j,r_j) """ # If we have supplied a list of D's and r's we make a gram matrix relative to these # otherwise we find a basis, i.e. linearly independent forms with correct dimension # find the dimension wt = '%.4f' % weight if (N < 10): stN = "0" + str(N) else: stN = str(N) v = dict() filename_work = "__N" + stN + "-" + wt + "--finding basis.txt" fp = open(filename_work, "write") fp.write("starting to find basis") fp.close() if (silent > 0): print "Forcing precision:", force_prec set_silence_level(0) if (bl <> None): dim = len(bl) l = bl else: if (set_dim <> None and set_dim > 0): dim = set_dim else: dim = dimension_jac_cusp_forms(int(weight + 0.5), N, -1) l = list_of_basis(N, weight, prec, tol, sv_min, sv_max, set_dim=dim) j = 0 for [D, r] in l.values(): for [Dp, rp] in l.values(): # Recall that the gram matrix is symmetric. We need only compute the upper diagonal if (v.values().count([Dp, rp, D, r]) == 0): v[j] = [D, r, Dp, rp] j = j + 1 # now v is a list we can get into computing coefficients # first we print the "gram data" (list of indices) to the file s = str(N) + ": (AI[" + str(N) + "],[" indices = dict() for j in range(len(l)): Delta = l[j][0] r = l[j][1] diff = (r * r - Delta) % (4 * N) if (diff <> 0): raise ValueError, "ERROR r^2=%s not congruent to Delta=%s mod %s!" % ( r * r, Delta, 4 * N) s = s + "(" + str(Delta) + "," + str(r) + ")" indices[j] = [Delta, r] if (j < len(l) - 1): s = s + "," else: s = s + "])," s = s + "\n" if (silent > 0): print s + "\n" filename2 = "PS_Gramdata" + stN + "-" + wt + ".txt" fp = open(filename2, "write") fp.write(s) fp.close() try: os.remove(filename_work) except os.error: print "Could not remove file:", filename_work pass filename_work = "__N" + stN + "-" + wt + "--computing_gram_matrix.txt" fp = open(filename_work, "write") fp.write("") fp.close() #print "tol=",tol #set_silence_level(2) #print "force_prec(gram_mat)=",force_prec res = ps_coefficients_holomorphic_vec(N, weight, v, tol, prec, force_prec=force_prec) set_silence_level(0) res['indices'] = indices maxerr = 0.0 for j in res['errs'].keys(): tmperr = abs(res['errs'][j]) #print "err(",j,")=",tmperr if (tmperr > maxerr): maxerr = tmperr # switch format for easier vewing res['errs'][j] = RR(tmperr) if (silent > 0): print "maxerr=", RR(maxerr) res['maxerr'] = maxerr wt_phalf = '%.4f' % (weight + 0.5) filename3 = "PS_Gramerr" + stN + "-" + wt + ".txt" fp = open(filename3, "write") wt s = "MAXERR[" + wt_phalf + "][" + stN + "]=" + str(RR(maxerr)) fp.write(s) fp.close() if (res['ok']): Cps = res['data'] else: print "Failed to compute Fourier coefficients!" return 0 RF = RealField(prec) A = matrix(RF, dim) kappa = weight fourpi = RF(4.0) * pi.n(prec) one = RF(1.0) N4 = RF(4 * N) C = dict() if (silent > 1): print "v=", v print "dim=", dim lastix = 0 # First set the upper right part of A for j in range(dim): ddim = dim - j if (silent > 1): print "j=", j, "ddim=", ddim, " lastix=", lastix for k in range(0, ddim): # need to scale with |D|^(k+0.5) if (silent > 1): print "k=", k print "lastix+k=", lastix + k mm = RF(abs(v[lastix + k][0])) / N4 tmp = RF(mm**(weight - one)) if (silent > 1): print "ddim+k=", ddim + k A[j, j + k] = Cps[lastix + k] * tmp C[v[lastix + k][0], v[lastix + k][1]] = Cps[lastix + k] lastix = lastix + k + 1 # And add the lower triangular part to mak the matrix symmetric for j in range(dim): for k in range(0, j): A[j, k] = A[k, j] # And print the gram matrix res['matrix'] = A dold = mpmath.mp.dps mpmath.mp.dps = int(prec / 3.3) AInt = mpmath.matrix(int(A.nrows()), int(A.ncols())) AMp = mpmath.matrix(int(A.nrows()), int(A.ncols())) for ir in range(A.nrows()): for ik in range(A.ncols()): AInt[ir, ik] = mpmath.mpi(A[ir, ik] - tol, A[ir, ik] + tol) AMp[ir, ik] = mpmath.mpf(A[ir, ik]) d = mpmath.det(AMp) if (silent > 1): print "det(A-as-mpmath)=", d di = mpmath.det(AInt) if (silent > 1): print "det(A-as-interval)=", di res['det'] = (RF(di.a), RF(di.b)) filename = "PS_Gram" + stN + "-" + wt + ".txt" if (silent > 1): print "printing to file: " + filename print_matrix_to_file(A, filename, 'A[' + str(N) + ']') if (silent > 1): print "A-A.transpose()=", norm(A - A.transpose()) B = A ^ -1 #[d,B]=mat_inverse(A) if (silent > 1): print "A=", A.n(100) print "det(A)=", di print "Done making inverse!" #res['det']=d res['inv'] = B mpmath.mp.dps = dold filename = "PS_Gram-inv" + stN + "-" + wt + ".txt" print_matrix_to_file(B, filename, ' AI[' + str(N) + ']') # first make the filename s = '%.1e' % tol filename3 = "PS_Coeffs" + stN + "-" + wt + "-" + s + ".sobj" # If the file already exist we load it and append the new data if (silent > 0): print "saving data to ", filename3 try: f = open(filename3, "read") except IOError: if (silent > 0): print "no file before!" # do nothing else: if (silent > 0): print "file: " + filename3 + " exists!" f.close() Cold = load(filename3) for key in Cold.keys(): # print"key:",key if (not C.has_key(key)): # then we addd it print "key:", key, " does not exist in the new version!" C[key] = Cold[key] save(C, filename3) ## Save the whole thing filename = "PS_all_gram" + stN + "-" + wt + ".sobj" save(res, filename) ## our work is comleted and we can remove the file try: os.remove(filename_work) except os.error: print "Could not remove file:", filename_work pass return res
def mpi(self): n = mpf(self.n)/mpf(self.d) return mpi(n, n)
# coding: utf-8 # In[2]: from mpmath import mpi # In[3]: a = mpi([0, 1]) # In[4]: def f0(x): return x**2 - x # In[5]: def f1(x): return x * (x - 1) # In[6]: def f2(x): return 1 / 4 - (x - 1 / 2)**2