Closed b-mehta closed 6 years ago
It is true that norm 5 == norm (3 + 4i)
, but abs 5 /= norm (3 + 4i)
.
Ah fair point, my mistake. I still feel like this may be a valuable function in any case.
Do you have any particular use case in mind? In my personal experience such function was rarely needed.
If the unit is necessary, can't one just do
let (powers, unit) = (factorise n, signum n)
in ...
since factorise = factorise . abs
?
That approach sounds reasonable - seems like I didn't think this through well enough. Thanks both.
Even if n == abs n
, it is not guaranteed that product (map (\(p, k) -> unPrime p ^ k) (factorise n) == n
. For example, take n = 2 :: GaussianInteger
. We have factorise n = [(Prime 1+ι,2)]
, but (1+ι)^2 = 2*ι /= 2
.
@b-mehta my idea's not entirely correct, but I found the correct way to express what I meant. Let g
be some GaussianInteger
.
let g' = product . map (\(p, k) -> unPrime p ^ k) . factorise $ g
sig' = signum g'
sig = signum g
-- This is the sign you want
s = div sig sig'
Now we have that
s * g' == g
You can try running it with the test-suite by adding this to GaussianIntegersTests
:
factoriseProperty1 :: GaussianInteger -> Bool
factoriseProperty1 g = g == 0 || s * g' == g
where
sig = signum g
sig' = signum g'
s = div sig sig'
factors = factorise g
g' = product $ map (\(p, k) -> unPrime p ^ k) factors
@rockbmb Right - my initial concern had been that this approach requires actually computing the product again which could be more costly than necessary if factorise
throws away the unit information anyway.
@Bodigrim I don't have a use case in mind, it just struck me as odd that the units were thrown away, given that the statement of unique factorisation I'm used to gives something like n = u p1^k1 ... pi^ki
.
For Int
/Word
/Integer
/Natural
one can just take signum
of an argument, as pointed above by @rockbmb. It is true that things get more complicated for quadratic fields, but here tracking of units is not actually free of charge, it makes factorisation algorithm more involved. I believe that for most of applications one can spend time reconstructing the product back.
@b-mehta if the cost of multiplicating the prime factors is what you're worried about, you can instead map (signum . fst)
over factorise n
and then multiply the units produced. Much cheaper, and the unit you get ~is the same as what my previous code would have given~ can then be divided by the original one as I described above.
Is it possible to have something like
for which the second argument is the remaining unit, with the invariant
and
snd (factorise' n)
is always a unit?The invariant for
factorise
is significantly weaker, since3+4i
and5
have the same absolute value in the Gaussian integers, but ought to have different factorisations, so just checking thatseems disappointing for domains with possibly non-real parts.
In addition, it would be nice to have that
factorise'
has a right inverse, and one could reconstruct a number from its factorisation.