Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up factorisation of Gaussian primes #116

Merged
merged 12 commits into from
Aug 6, 2018
Merged

Speed up factorisation of Gaussian primes #116

merged 12 commits into from
Aug 6, 2018

Conversation

Bodigrim
Copy link
Owner

This PR resolves #111.
@cfredric would you be interested to review?

asbs = map (\b' -> ((b' * c) `mod` p, b')) bs
(a, b) = head [ (a', b') | (a', b') <- asbs, a' <= k]
in a :+ b
findPrime' p = case Moduli.sqrtModMaybe (-1) (FieldCharacteristic (PrimeNat . integerToNatural $ p) 1) of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this PR, but it seems odd to have findPrime' when there is no findPrime. Is it worth renaming to findPrime, and keeping findPrime' around as a deprecated name?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Will do.


-- |Compute the prime factorisation of a Gaussian integer. This is unique up to units (+/- 1, +/- i).
-- Unit factors are not included in the result.
factorise :: GaussianInteger -> [(GaussianInteger, Int)]
factorise g = helper (Factorisation.factorise $ norm g) g
factorise g = concat $ snd $ mapAccumL go g (Factorisation.factorise $ norm g)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a source for this algorithm (that might be worth citing from the doc comment)?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to avoid repetitive complex divisions with the same divisor, because they unnecessary recalculate its norm. I'll refactor code to make it more palatable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. I think I was thrown off by the extra units that entered into the equations (to make the math work out nicer).

gcdGProperty2 :: GaussianInteger -> GaussianInteger -> GaussianInteger -> Bool
gcdGProperty2 z z1 z2
= z == 0
|| gcdG z1' z2' `remG` z == 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a bug? How can the GCD be zero? (Or am I reading this wrong?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's asking of the gcd is zero, but if the remainder of the division of that gcd by z is 0.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is convenient to set gcd 0 0 equal to 0.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I was parsing the code incorrectly.

@cfredric
Copy link
Contributor

cfredric commented Aug 6, 2018

LGTM, thanks!

@Bodigrim Bodigrim merged commit ab8603c into Bodigrim:master Aug 6, 2018
@Bodigrim Bodigrim deleted the gaussian branch August 6, 2018 19:34
@Bodigrim
Copy link
Owner Author

Bodigrim commented Aug 6, 2018

@cfredric Thanks for review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Find Gaussian prime with a given norm in effective way
3 participants