2017-01-15 4 views
5

私は、ガウス整数のガウス因子のシーケンスを生成する方法を書こうとしています。ガウス整数は、通常の整数または複素数のいずれかですg = a + biabは両方とも整数です。ガウス整数のガウス分周器gは、ガウス整数のdであり、g/dもガウス整数です。Python 3 - 複素数

次のコードがあります。

def is_gaussian_integer(c): 
    """ 
     Checks whether a given real or complex number is a Gaussian integer, 
     i.e. a complex number g = a + bi such that a and b are integers. 
    """ 
    if type(c) == int: 
     return True 
    return c.real.is_integer() and c.imag.is_integer() 


def gaussian_divisors(g): 
    """ 
     Generates a sequence of Gaussian divisors of a rational or Gaussian 
     integer g, i.e. a Gaussian integer d such that g/d is also a Gaussian integer. 
    """ 
    if not is_gaussian_integer(g): 
     return 
    if g == 1: 
     yield complex(g, 0) 
     return 
    g = complex(g) if type(g) == int or type(g) == float else g 
    a = b = 1 
    ubound = int(math.sqrt(abs(g))) 
    for a in range(-ubound, ubound + 1): 
     for b in range(-ubound, ubound + 1): 
      if a or b: 
       d = complex(a, b) 
       if is_gaussian_integer(g/d): 
        yield d 
    yield g 

"ほとんど"動作しているようですが、入力によっては、いくつかのガウス因子が欠落しています。 2については、-2 + 0j(これはちょうど-2)の除数を含むシーケンスが必要ですが、それはありません。なぜこれをやっているのか、ロジックにギャップがあるのか​​分かりません。

In [92]: list(gaussian_divisors(2)) 
Out[92]: [(-1-1j), (-1+0j), (-1+1j), -1j, 1j, (1-1j), (1+0j), (1+1j), (2+0j)] 
+0

Python 3では、整数除算演算子は '/'ではなく '//'です。私は複雑なオペランドで何が何であるか分かりません。 –

+0

'//'演算子は複素数には当てはまりません。 '1/1j'は期待通りに' -1j'を返しますが、 '1 // -1j'はエラーを出します:' TypeError:複素数の階数を取ることができません.'これはおそらく、整数とは異なり複素数の自然順序付けがないためです。 – srm

+0

大丈夫ですが、十分な大きさのオペランドに対して '/'が正しく動作しないため、おそらくあなた自身の除算演算子を定義したいでしょう。また、 'g = 2'、' ubound = 1'なので、ループは-1から1になります。 –

答えて

1

の代わりにあなたのループを開始し、それだけで-1をテストしますちょうど1ある= int(sqrt(2))int(math.sqrt(abs(g)))で停止するので、ちょうどあなたが0、さらに

yield -g 

yield g 

を可能性が生じます1

Alternativlyあなたは、ループ内-22を含めたい場合は、uboundまたはmath.ceilsqrt結果をインクリメントするか必要があります。