예제 #1
0
def main():
    for i in range(100000,10000000):
        startTime = time.time()
        gcd.gcd(i,magNum)
        stopTime = time.time()
        if stopTime-startTime > 0.01:
            print(i,' takes ',stopTime-startTime,'s')
예제 #2
0
 def testPrimes(self):
     for x in self.primes:
         for y in self.primes:
             if x != y:
                 self.assertEqual(gcd.gcd(x, y), 1)
             else:
                 self.assertEqual(gcd.gcd(x, y), x)
def extended_euclidean(a, b):
    if a < b:
        tmp = a
        a = b
        b = tmp

    r = [a, b]
    s = [1, 0]
    t = [0, 1]
    q = [0, 0]
    i = 2
    while r[i - 1] > 0:
        q.append(r[i - 2] // r[i - 1])
        r.append(r[i - 2] - q[i] * r[i - 1])
        s.append(s[i - 2] - q[i] * s[i - 1])
        t.append(t[i - 2] - q[i] * t[i - 1])
        #print i," : ",q[i],r[i],s[i],t[i]
        i += 1
    x = s[i - 2]
    y = t[i - 2]
    if x * a + b * y != gcd(a, b):
        print "gcd ", gcd(a, b)
        print "ans ", x * a + b * y
        raise Exception("ans not accept")
    return (x, y)
예제 #4
0
def findfactor(n):
	if n&1==0: return 2
	y,c,m = random.randint(1,n-1),random.randint(1,n-1),random.randint(1,n-1)
	g,r,q=1,1,1
	while g==1:
		x=y
		for i in xrange(r):
			y = ((y*y)%n+c)%n
		
		k=0
		while (k<r and g==1):
			ys = y
			for i in xrange(min(m,r-k)):
				y = ((y*y)%n+c)%n
				q = q*(abs(x-y))%n
			g=gcd(q,n)
			k=k+m
		r<<=1
	if g==n:
		while True:
			ys = ((ys*ys)%n+c)%n
			g = gcd(abs(x-ys),n)
			if g>1:
				break
	
	return g
예제 #5
0
 def testBigNum(self):
     #two big prime numbers
     p = 100000000000657
     q = 1000000000000783
     self.assertEqual(gcd.gcd(p, q), 1)
     a = p * q * 41 * 31
     b = p * 1009 * 31
     self.assertEqual(gcd.gcd(a, b), p * 31)
def factional_sequen(N,div):
    while(N!=1):
	N,div=N-1,div+1
	if gcd.gcd(N,div)!=1:
	    tmp=gcd.gcd(N,div)
	    N,div=N/tmp,div/tmp
	    #factional_sequen(N,div)
	    N,div=N-1,div+1
    return div
예제 #7
0
 def test_gsd_in_param(self):
     self.assertEqual(gcd.gcd(0, 7), 7)
     self.assertEqual(gcd.gcd(7, 0), 7)
     self.assertEqual(gcd.gcd(7, 7), 7)
     self.assertEqual(gcd.gcd(1, 8), 1)
     self.assertEqual(gcd.gcd(4, 6), 2)
     self.assertEqual(gcd.gcd(10, 15), 5)
     self.assertEqual(gcd.gcd(15, 10), 5)
     self.assertEqual(gcd.gcd(5, 25), 5)
     self.assertEqual(gcd.gcd(15, 45), 15)
예제 #8
0
def factor(n, x1):
    x = x1
    x0 = f(x) % n
    p = gcd(abs(x - x0), n)
    i = 1
    while p == 1:
        x = f(x) % n
        x0 = f(x0) % n
        x0 = f(x0) % n
        p = gcd(abs(x - x0), n)
        i += 1

    if p == n:
        return "failure"
    return (p, i)
예제 #9
0
 def __init__(self, n=1, d=1): #n:分子,d:分母
     self.n = n
     self.d = d
     g = gcd.gcd(self.n,self.d)
     if g != 1:
         self.n = int(self.n/g)
         self.d = int(self.d/g)
예제 #10
0
def decrypt(c: int, sk: Tuple[List[int], int, int]) -> BitString:
    result = ''
    w = sk[0]
    q = sk[1]
    r = sk[2]

    if gcd.gcd(q, r) != 1:
        raise ValueError("decrypt(): q and r not coprime")

    c_real = (c * gcd.get_modular_inverse(r, q)) % q

    for w_i in reversed(w):
        if c_real >= w_i:
            c_real -= w_i
            result += '1'
        else:
            result += '0'

        if c_real < 0:
            raise ValueError("decrypt(): decrypt error")

    if c_real != 0:
        raise ValueError("decrypt(): decrypt error")

    return BitString(result)
예제 #11
0
 def test_out_int(self):
     for n in range(20):
         for m in range(20):
             result = gcd.gcd(n, m)
             if result!=0:
                 result = result/int(result)
                 self.assertEqual(result, 1)
예제 #12
0
def lcm(a, b):
    '''
	Computes LCM of two numbers
	'''

    g = gcd.gcd(a, b)
    return (a / g) * b
예제 #13
0
    def __public_key_generator(self):
        """ Generate the public key. """
        e = randint(1, self.totient)
        while gcd(e, self.totient) != 1:
            e = randint(1, self.totient)

        self.public_key = (e, self.n)
예제 #14
0
def naiveeulerphi(n):
    count = 0
    # n itself is excluded in this loop, since gcd(n,n) = n
    for k in range(1,n):
        if gcd(n,k) == 1:
            count = count + 1
    return count
예제 #15
0
 def gsd_out_check_int(self):
     for x in range(0, self.n_max_test):
         for y in range(0, self.n_max_test):
             result = gcd.gcd(x, y)
             if result != 0:
                 result = result / int(result)
                 self.assertEqual(result, 1)
예제 #16
0
def generarE(fn):
	menor = 11
	mayor = 99999
	e = random.randrange(menor, mayor) #rango en el que quiero que este el valor de e
	while gcd(e, fn) != 1: #un do-while improvisado, parece que python no lo implementa por su cuenta
		e = random.randrange(menor, mayor)
	return e
예제 #17
0
def numbers_gcd(request, num1,num2):
    num1 = int(num1)
    num2 = int (num2)
    flag = False
    for tmp in Request.objects.all():
        if (tmp.f == int(num1) and tmp.to == int(num2)):
            flag = True

    if (flag == False):
        my_req = Request(f = num1 , to = num2)
        my_req.save()
        for i in xrange(int(num1),int(num2)+1):
            for j in xrange(int(num1),int(num2)+1):
                        gcd_mod = GCD(
                            ch1 = i,
                            ch2 = j,
                            answ = gcd(i,j),
                            request = my_req
                        )
                        gcd_mod.save()
    else:
        my_req = Request.objects.filter(f=num1 ,to=num2 )
    my_set = GCD.objects.filter(request = my_req)
    print my_set
    return render(request, 'GCD/index2.html', {"ans" : my_set} )
예제 #18
0
    def __init__(self, n, d):
        """ Construct a Frac from integers n and d.
		    Needs error message if d = 0!
		"""

        hcf = gcd.gcd(n, d)
        self.num, self.den = n / hcf, d / hcf
예제 #19
0
def linear_congruence(a, b, n):
    d = gcd(a, n)
    if b % d != 0:
        return []

    if a < n:
        s, r = extended_euclidean(a, n)
    else:
        r, s = extended_euclidean(a, n)

    x0 = r * b / d
    c = n / d
    while x0 < 0:
        x0 += c

    if x0 >= n:
        while x0 > 0:
            x0 -= c
        x0 += c

    x = []
    while x0 < n:
        x.append(x0)
        x0 += c

    return x
예제 #20
0
파일: rsa_demo.py 프로젝트: MotoLee/DPV
def relative_prime(x):
    e = 3
    for i in range(e, x):
        g = gcd(i, x)
        if g == 1:
            e = i
            break
    return e
예제 #21
0
    def homogeneous(self):
        A = self.A
        B = self.B
        C = self.C
        D = self.D
        E = self.E
        F = self.F
        eq = []
        k = math.sqrt(B*B - 4*A*C)
        if F ==0:
            eq.append(parametric_eq([0],[0]))
            if k == int(k):
                eq.extend(diophantine_Eq([0,0,0,2*A,B+int(k),0]).solve())
                eq.extend(diophantine_Eq([0,0,0,2*A,B-int(k),0]).solve())
            else:
                return eq
        else:
            if cond == int(cond):

                fac = factoring(-4*A*F,True)
                eq = []
                for u in fac:
                    y = (u + (4*A*F)*(1.0)/u) / (2*k)
                    x = (u - (B+k)*y*(1.0)) / (2*A)
                    if int(x) == x and int(y)==y:
                        eq.append( parametric_eq([int(x)],[int(y)]) )
                return eq
            else:
                g = gcd(gcd(A,B),C)
                if F%g !=0:
                    return []
                A = A/g
                B = B/g
                C = C/g
                D = D/g
                E = D/g
                F = F/g

                if 4*F*F < B*B - 4*A*C:
                    # convergents of the continued fraction of the roots of the equation At2 + Bt + C = 0
                    print "next"
                else:
                    


        return eq
def phi(N):
    """docstring for phi"""
    import gcd
    count=0
    for i in range(1,N):
        if gcd.gcd(N,i)==1:
            count+=1
    return count
예제 #23
0
    def optimize(self):
        _gcd = gcd(self.a, self.divisor)

        if _gcd > 1:
            self.a //= _gcd
            self.divisor //= _gcd

            return _gcd
예제 #24
0
파일: shor.py 프로젝트: JzMaple/MyShor
    def shor(self, n):
        if miller_robin.miller_robin(n):
            return (1, n)
        else:
            tmp = power.power(n)
            if tmp != -1:
                return (tmp, n // tmp)
            else:
                if (n % 2 == 0):
                    return (2, n // 2)
                while True:
                    # Parrel computing for some random x
                    xlist = random.sample(range(3, n - 1), self.Thread_Num)
                    g = [gcd.gcd(x, n) for x in xlist]
                    for idx, g in enumerate(g):
                        if (g != 1):
                            # ======= For debug ===========
                            # while gcd.gcd(xlist[idx], n) != 1:
                            #     newx = random.randint(3, n - 1)
                            #     xlist[idx] = newx
                            # ======= In Real Quantum Computer =========
                            return (g, n // g)

                    print("======== Order Finding Started ========")
                    threadPool = ThreadPool(processes=self.Thread_Num)
                    results = []
                    for x in xlist:
                        results.append(
                            threadPool.apply_async(self.order_finding,
                                                   args=(x, n)))
                    threadPool.close()
                    threadPool.join()
                    results = [r.get() for r in results]

                    for r in results:
                        if r == -1:
                            continue
                        if (r % 2 == 0):
                            s = fastPow.fastPow(x, r // 2, n)
                            if (s != 1 and s != n - 1):
                                g1 = gcd.gcd(s + 1, n)
                                g2 = gcd.gcd(s - 1, n)
                                if (g1 != 1):
                                    return (g1, n // g1)
                                elif (g2 != 1):
                                    return (g2, n // g2)
예제 #25
0
파일: rsa_demo.py 프로젝트: zamiljitu/DPV
def relative_prime(x):
    e = 3
    for i in range(e, x):
        g = gcd(i, x)
        if g == 1:
            e = i
            break
    return e
예제 #26
0
def main():
    ''' main '''
    parser = argparse.ArgumentParser(description='calculate Greatest Common Divisor')
    parser.add_argument("n1", type=int, nargs='?', default=1024)
    parser.add_argument("n2", type=int, nargs='?', default=768)
    args = parser.parse_args()

    r = gcd(args.n1, args.n2)
    print(f'gcd({args.n1}, {args.n2}) = {r}')
예제 #27
0
 def __init__(self, numerator=0, denominator=1):
   if denominator == 0:                   # fraction is undefined
     self._numer = 0
     self._denom = 0
   else:
     factor = gcd( abs(numerator), abs(denominator) )
     if denominator < 0:                  # want to divide through by negated factor
       factor = -factor
     self._numer = numerator // factor
     self._denom = denominator // factor
예제 #28
0
def triples( max ) :
    """Generate a list of all prime pythagorean triples in range.

    MAX is the largest value of the hypotenuse to allow.
    """
    for i in range( 1, max ) :
        for j in range ( i+1, max ) :
            k = hypot( i, j )
            if k < max and k == int( k ) and 1 == gcd( i, j ):
                yield ( i, j, int(k) )
예제 #29
0
 def mulr(self, a, b): #掛け算
     x = Rational()
     x.n = a.n*b.n
     x.d = a.d*b.d
     g = gcd.gcd(x.n, x.d)
     if g != 1:
         x.n = int(x.n/g)
         x.d = int(x.d/g)
     
     return x 
예제 #30
0
 def test_zero(self):
     a = 0
     b = random.randint(1, 100)
     ans = _(
         "Test zero - The greatest common divisor between {} and {} is {} and you returned {}."
     )
     stu_ans = gcd.gcd(a, b)
     corr_ans = corr.gcd(a, b)
     self.assertEqual(corr_ans, stu_ans, ans.format(a, b, corr_ans,
                                                    stu_ans))
 def __init__(self, numerator=0, denominator=1):
     if denominator == 0:  # fraction is undefined
         self._numer = 0
         self._denom = 0
     else:
         factor = gcd(abs(numerator), abs(denominator))
         if denominator < 0:  # want to divide through by negated factor
             factor = -factor
         self._numer = numerator // factor
         self._denom = denominator // factor
def get_public_exponent(m):
    n = m-1

    while n > 0:
        if gcd(n, m) == 1 and is_prime(n):
            return n

        n -= 1

    return -1
예제 #33
0
 def subr(self, a, b): #引き算
     x = Rational()
     x.n = a.n*b.d - b.n*a.d
     x.d = a.d*b.d
     g = gcd.gcd(x.n,x.d)
     if g != 1:
         x.n = int(x.n/g)
         x.d = int(x.d/g)
     
     return x
예제 #34
0
 def divr(self, a, b): #割り算
     x = Rational()
     x.n = a.n*b.d
     x.d = a.d*b.n
     g = gcd.gcd(x.n,x.d)
     if g != 1:
         x.n = int(x.n/g)
         x.d = int(x.d/g)
     
     return x
예제 #35
0
 def addr(self, a, b): #足し算
     x = Rational()
     x.n = a.n*b.d + b.n*a.d
     x.d = a.d*b.d
     g = gcd.gcd(x.n,x.d)
     if g != 1:
         x.n = int(x.n/g)
         x.d = int(x.d/g)
     
     return x
예제 #36
0
def triples(max):
    """Generate a list of all prime pythagorean triples in range.

    MAX is the largest value of the hypotenuse to allow.
    """
    for i in range(1, max):
        for j in range(i + 1, max):
            k = hypot(i, j)
            if k < max and k == int(k) and 1 == gcd(i, j):
                yield (i, j, int(k))
예제 #37
0
def triples( max ) :
    """Generate a list of all prime pythagorean triples in range.

    MAX is the largest value of the hypotenuse to allow.
    """
    for k in range( 1, 1+max ) :
        imax = int( floor( sqrt( k*k/2.0 ) ) )
        for i in range( 1, 1+imax ) :
            j = sqrt( k*k - i*i )
            if abs( floor( j ) - j ) < 0.000001 and 1 == gcd( i, int( j ) ) :
                yield ( i, int( j ), k )
예제 #38
0
파일: rat.py 프로젝트: NicolasSimard/numth
 def __init__(self, num, denom = 1):
     if not isinstance(num,Rat) and not isinstance(denom,Rat):
         num, denom = int(num),int(denom)
         d = gcd.gcd(abs(num), abs(denom))
         # The sign is always in the numerator
         self.num = sign(num*denom)*abs(num)//d
         self.denom = abs(denom)//d
     else:
         fraction = num/denom
         self.num = fraction.num
         self.denom = fraction.denom
예제 #39
0
 def test_gcd(self):
     a = [random.randint(1, 100) for _ in range(5)]
     b = [random.randint(1, 100) for _ in range(5)]
     ans = _(
         "The greatest common divisor between {} and {} is {} and you returned {}."
     )
     for i in range(len(a)):
         stu_ans = gcd.gcd(a[i], b[i])
         corr_ans = corr.gcd(a[i], b[i])
         self.assertEqual(corr_ans, stu_ans,
                          ans.format(a[i], b[i], corr_ans, stu_ans))
예제 #40
0
def pollard_rho(n):
    x, y, d = 2, 2, 1
    g = lambda i: (i**2 + 1)%n

    while d == 1:
        x = g(x)
        y = g(g(y))
        d = gcd(abs(x-y), n)
    
    if d == n: return 0
    else: return d
예제 #41
0
def triples(max):
    """Generate a list of all prime pythagorean triples in range.

    MAX is the largest value of the hypotenuse to allow.
    """
    for k in range(1, 1 + max):
        imax = int(floor(sqrt(k * k / 2.0)))
        for i in range(1, 1 + imax):
            j = sqrt(k * k - i * i)
            if abs(floor(j) - j) < 0.000001 and 1 == gcd(i, int(j)):
                yield (i, int(j), k)
예제 #42
0
파일: rat.py 프로젝트: vochong/numth
 def __init__(self, num, denom=1):
     if not isinstance(num, Rat) and not isinstance(denom, Rat):
         num, denom = int(num), int(denom)
         d = gcd.gcd(abs(num), abs(denom))
         # The sign is always in the numerator
         self.num = sign(num * denom) * abs(num) // d
         self.denom = abs(denom) // d
     else:
         fraction = num / denom
         self.num = fraction.num
         self.denom = fraction.denom
예제 #43
0
def generarN():
	#generar n y fn, regresa una tupla de ambos
	p = generarprimo()
	q = 1
	gcd_bool = True
	while (p is not q) and gcd_bool:
		q = generarprimo()
		auxiliar = gcd(p - 1, q - 1)
		if auxiliar < 10:
			gcd_bool = False
	n = p * q
	fn = (p - 1) * (q - 1)
	nfn = (n, fn)
	return nfn
예제 #44
0
def inverse_modulo(x, n):
    a, b = x, n
    if n > x:
        a, b = b, a
    result = gcd(a, b)
    if result != 1:
        # print ("As gcd(%d, %d) != 1, the inverse does not exists" % (x, n))
        return None

    ans = extended_euclid(x, n)
    if ans[0] > 0:
        return ans[0]
    else:
        return (ans[0] + n)
예제 #45
0
def add(x, y):
    xtp, xnum, xdenom = x
    ytp, ynum, ydenom = y
    ndenom = xdenom * ydenom
    nnum = xnum * ydenom + xdenom * ynum
    if xtp == 'basic':
        return 'basic', nnum, ndenom
    elif xtp == 'auto_simpl':
        cur_gcd = gcd(nnum, ndenom)
        return ('auto_simpl', 
                 nnum / cur_gcd, 
                 ndenom / cur_gcd)
    assert False, "Unsupported  rational type" + \
                  " for add" + xtp
예제 #46
0
def pythagoreanIterator(limit) :
	sq_limit = int((limit + 1) ** 0.5)
	for i in range(1, sq_limit) :
		print >> sys.stderr, i, "\r",
		for j in range(i+1, sq_limit) :
			i_sq, j_sq = i**2, j**2
			a = j_sq - i_sq
			b = 2*i*j
			c = i_sq + j_sq
			p = a+b+c
			if p > limit : break
			if not triangleTest(a,b,c) : break
			if (i&1 == 0 or j&1 == 0) and gcd.gcd(i,j) == 1 :
				yield sorted( (a,b,c) )
	return
예제 #47
0
 def __init__(self, top, bottom):
     # #5 solution for exercise 5 from 1.7 module - chap-1
     if not isinstance(top, int):
         valErr = ValueError("{} is not integer".format(top))
         raise valErr
     if not isinstance(bottom, int):
         valErr = ValueError("{} is not integer".format(bottom))
         raise valErr
     # #6 solution for exercise 6 from 1.7 module - chap-1
     if top < 0 and bottom < 0:
         top = abs(top)
         bottom = abs(bottom)
     elif bottom < 0:
         top = -top
         bottom = abs(bottom)
     common = gcd(abs(top), abs(bottom))
     self.num = top // common
     self.den = bottom // common
예제 #48
0
def primitive_triples(limit):
    """Return a list of pythagorean primitive triples.

    Returns all primitive pythagorean primitive triples
    (a,b,c) where c^2 <= limit.   The results are unsorted,
    a is always odd, and b is always even.

    The pythagorean triples are integers (a,b,c) such that
    a*a + b*b = c*c.  Primitive triples are triples such that
    a, b, and c are relatively prime.

    To generate the triples, we look at all positive integers
    m and n, with n < m.  If m and n are coprime, and m-n is odd,
    then we can calculate a, b, and c as follows:

    a = m^2 - n^2, b = 2mn, c = m^2 + n^2

    http://en.wikipedia.org/wiki/Pythagorean_triple

    """

    result = []
    m, m2 = 1, 1
    while m2 <= limit:
        # Check each n less than m.  We only need to check the odd
        # n if m is even and vice versa.  Also, we can stop checking
        # if we get to a case where c is greater than limit.  Inside
        # this loop, c is always increasing.
        for n in xrange((m % 2) + 1, m, 2):
            n2 = n*n
            c = n2 + m2
            # stop if c is too big for this n.  
            if c > limit:
                break
            
            if gcd.gcd(n,m) == 1:
                # m and n are coprime.  found a result!
                result.append((m2-n2, 2*m*n, m2+n2))

        m = m + 1
        m2 = m * m
                
    return result
예제 #49
0
def returnList():
	# incorporate x, y, z symmetries

    indices = []
    sizes = []

    for h in range(1,40):
        for k in range(0,40):
            for l in range(0,40):
                if (abs(gcd(gcd(h,k),gcd(k,l)))==1) or (abs(gcd(gcd(h,k),gcd(k,l)))==0) and not h+k+l==0:
                    new_index = [h,k,l]
                    indices.append(new_index)
                    surf=makeSurface('Pt','fcc', new_index,size=(1,1,5))
                    volume = abs(np.dot(np.cross(surf.get_cell()[0],surf.get_cell()[1]),surf.get_cell()[2]))
                    sizes.append(volume)
                else:
                    break

    return indices, sizes 
예제 #50
0
 def __truediv__(self, other):
     num = self.num * other.den
     den = self.den * other.num
     common = gcd(abs(num), abs(den))
     return Fraction(num // common, den // common)
예제 #51
0
 def __init__(self, numerator, denominator=1):
   """ create a fraction from a numerator and denominator """
   g = gcd(numerator, denominator)
   self.numerator = numerator / g
   self.denominator = denominator / g
예제 #52
0
def solution(N, M):
    d = gcd(N, M)
    return N / d
예제 #53
0
 def __sub__(self, other):
     num = (self.num * other.den) - (self.den * other.num)
     den = self.den * other.den
     common = gcd(abs(num), abs(den))
     return Fraction(num // common, den // common)
예제 #54
0
파일: test_gcd.py 프로젝트: 03013323/sees
 def test_gcd(self):
     for case in self.test_cases:
         a = case[0]
         b = case[1]
         g = case[2]
         self.assertEqual(gcd.gcd(a, b), g)
예제 #55
0
def __euler_loop(n):
    coprimes = [1]
    for i in xrange(2, n):
        if gcd(i, n) == 1:
            coprimes.append(i)
    return len(coprimes)
예제 #56
0
파일: rational.py 프로젝트: arante/pyloc
    def simplify(self):
        """Simplifies a rational number"""

        common = gcd.gcd(self.numerator, self.denominator)
        self.numerator = self.numerator / common
        self.denominator = self.denominator / common
예제 #57
0
def lcm(a,b):
    return a * b / gcd(a,b)
예제 #58
0
from gcd import gcd
from gcd_fast import gcd as gcd_fast

for i in range(1, 100):
    for j in range(1, 100):
        print('testing for ', i, j)
        assert (gcd(i, j) == gcd_fast(i, j))
예제 #59
0
def problem005(argument = range(1, 21)):
    """Return the lcm of 1 through 20."""
    return reduce(lambda a, b: a * b / gcd(a, b), argument)
예제 #60
0
def makeSurface(symbol,structure,indices,size=(1,1,1),tol=1e-10,lattice_const=None):
    """
    this function makes the surface and also identical bulk structure with atoms
    symbol: what type of atom, in a string
    structure: currently supported fcc, bcc, hcp, diamond
    indices: miller index of the surface
    size: tuple of (s_x,s_y,s_z) to use for the box
    the lattice constant in ASE database may not be accurate, make your own...
    """

    #if isinstance(structure, str):
    #lattice = bulk(structure, cubic=True)

    # first decide which function we want to use to build the structure
    if structure=='fcc':
        atoms_fn = getattr(ase.lattice.cubic,'FaceCenteredCubic')
    elif structure=='bcc':
        atoms_fn = getattr(ase.lattice.cubic,'BodyCenteredCubic')
    elif structure=='hcp':
        atoms_fn = getattr(ase.lattice.hexagonal, 'HexagonalClosedPacked')
    elif structure=='diamond':
        atoms_fn = getattr(ase.lattice.cubic,'Diamond')
    elif structure=='sc':
        atoms_fn = getattr(ase.lattice.cubic, 'SimpleCubic')
    else:
        print "structure defined not supported"
        raise Exception

    h , k , l = indices
    miller = [None,None,[h,k,l]] # put in this argument as internal check
    lattice = atoms_fn(symbol)
    if lattice_const:
        lattice = atoms_fn(symbol,latticeconstant = lattice_const)
    # problem, should specify miller at the same time as directions

    # now calculate the vectors to put along x,y,z directions

    a1, a2, a3 = lattice.cell

    h0, k0, l0 = (h == 0,k==0,l==0)
    if h0 and k0 or h0 and l0 or k0 and l0:  # if two indices are zero
        if not h0:
            c1, c2, c3 = [(0, 1, 0), (0, 0, 1), (1, 0, 0)]
        if not k0:
            c1, c2, c3 = [(1, 0, 0), (0, 0, 1), (0, 1, 0)]
        if not l0:
            c1, c2, c3 = [(1, 0, 0), (0, 1, 0), (0, 0, 1)]
    else:
        p, q = ext_gcd(k, l)
        a1, a2, a3 = lattice.cell # this is the lattice constants

        # constants describing the dot product of basis c1 and c2:
        # dot(c1,c2) = k1+i*k2, i in Z
        k1 = np.dot(p * (k * a1 - h * a2) + q * (l * a1 - h * a3), l * a2 - k * a3)
        k2 = np.dot(l * (k * a1 - h * a2) - k * (l * a1 - h * a3), l * a2 - k * a3)
        if abs(k2) > tol:
            i = -int(round(k1 / k2))  # i corresponding to the optimal basis
            p, q = p + i * l, q - i * k

        a, b = ext_gcd(p * k + q * l, h)

        c1 = (p * k + q * l, -p * h, -q * h)
        c2 = np.array((0, l, -k)) // abs(gcd(l, k))
        c3 = (b, a * p, a * q)

    # layers wanted in surface direction
    # along each surface direction, the number of atoms are different
    # have to first determine that


    layers=size[2]
    d_v3 = max(int(1.0*layers/(np.dot(np.array(c3),indices/norm(indices)))),1)
    #print d_v3

    size_to_build = (size[0],size[1],d_v3)
    #size_to_build = (size[0],size[1],size[2])

    surface = build(lattice, np.array([c1,c2,c3]),size_to_build,tol)

    return surface