Cyclotomic polynomial: Difference between revisions
Content added Content deleted
No edit summary |
(→{{header|Haskell}}: added solution) |
||
Line 1,839: | Line 1,839: | ||
</pre> |
</pre> |
||
<math>Insert formula here</math> |
<math>Insert formula here</math> |
||
=={{header|Haskell}}== |
|||
Uses synthetic polynomial division and simple memoization. |
|||
<lang haskell>import Data.List |
|||
import Data.Numbers.Primes (primeFactors) |
|||
negateVar p = zipWith (*) p $ reverse $ take (length p) $ cycle [1,-1] |
|||
lift p 1 = p |
|||
lift p n = intercalate (replicate (n-1) 0) (pure <$> p) |
|||
shortDiv :: [Integer] -> [Integer] -> [Integer] |
|||
shortDiv p1 (_:p2) = unfoldr go (length p1 - length p2, p1) |
|||
where |
|||
go (0, _) = Nothing |
|||
go (i, h:t) = Just (h, (i-1, zipWith (+) (map (h *) ker) t)) |
|||
ker = negate <$> p2 ++ repeat 0 |
|||
primePowerFactors = sortOn fst . map (\x-> (head x, length x)) . group . primeFactors |
|||
-- simple memoization |
|||
cyclotomics :: [[Integer]] |
|||
cyclotomics = cyclotomic <$> [0..] |
|||
cyclotomic :: Int -> [Integer] |
|||
cyclotomic 0 = [0] |
|||
cyclotomic 1 = [1, -1] |
|||
cyclotomic 2 = [1, 1] |
|||
cyclotomic n = case primePowerFactors n of |
|||
-- for n = 2^k |
|||
[(2,h)] -> 1 : replicate (2 ^ (h-1) - 1) 0 ++ [1] |
|||
-- for prime n |
|||
[(p,1)] -> replicate n 1 |
|||
-- for power of prime n |
|||
[(p,m)] -> lift (cyclotomics !! p) (p^(m-1)) |
|||
-- for n = 2*p and prime p |
|||
[(2,1),(p,1)] -> take (n `div` 2) $ cycle [1,-1] |
|||
-- for n = 2*m and odd m |
|||
(2,1):_ -> negateVar $ cyclotomics !! (n `div` 2) |
|||
-- general case |
|||
(p, m):ps -> let cm = cyclotomics !! (n `div` (p ^ m)) |
|||
in lift (lift cm p `shortDiv` cm) (p^(m-1))</lang> |
|||
Simple examples |
|||
<pre>λ> cyclotomic 7 |
|||
[1,1,1,1,1,1,1] |
|||
λ> cyclotomic 9 |
|||
[1,0,0,1,0,0,1] |
|||
λ> cyclotomic 16 |
|||
[1,0,0,0,0,0,0,0,1]</pre> |
|||
The task solution |
|||
<lang haskell>showPoly p = foldl showMono "" $ zip (reverse p) [0..] |
|||
where |
|||
showMono r (c, i) = r ++ case (c, i) of |
|||
(0, _) -> "" |
|||
(c, 0) -> show c |
|||
(1, i) -> " + " ++ "x^" ++ show i |
|||
(-1, i) -> " - " ++ "x^" ++ show i |
|||
(c, i) | c < 0 -> " - " ++ show (-c) ++ "*x^" ++ show i |
|||
(c, i) | c > 0 -> " + " ++ show c ++ "*x^" ++ show i |
|||
main = do |
|||
mapM_ (print . showPoly . cyclotomic) [1..30] |
|||
putStrLn $ replicate 40 '-' |
|||
mapM_ showLine $ take 4 task2 |
|||
where |
|||
showLine (j, i, l) = putStrLn $ concat [ show j |
|||
, " appears in CM(", show i |
|||
, ") of length ", show l ] |
|||
-- in order to make computations faster we leave only each 5-th polynomial |
|||
task2 = (1,1,2) : tail (search 1 $ zip [0,5..] $ skipBy 5 cyclotomics) |
|||
where |
|||
search i ((k, p):ps) = if i `notElem` (abs <$> p) |
|||
then search i ps |
|||
else (i, k, length p) : search (i+1) ((k, p):ps) |
|||
skipBy n [] = [] |
|||
skipBy n lst = let (x:_, b) = splitAt n lst in x:skipBy n b</lang> |
|||
Result |
|||
<pre>"-1 + x^1" |
|||
"1 + x^1" |
|||
"1 + x^1 + x^2" |
|||
"1 + x^2" |
|||
"1 + x^1 + x^2 + x^3 + x^4" |
|||
"1 - x^1 + x^2" |
|||
"1 + x^1 + x^2 + x^3 + x^4 + x^5 + x^6" |
|||
"1 + x^4" |
|||
"1 + x^3 + x^6" |
|||
"1 - x^1 + x^2 - x^3 + x^4" |
|||
"1 + x^1 + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10" |
|||
"1 - x^2 + x^4" |
|||
"1 + x^1 + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + x^12" |
|||
"1 - x^1 + x^2 - x^3 + x^4 - x^5 + x^6" |
|||
"1 - x^1 + x^3 - x^4 + x^5 - x^7 + x^8" |
|||
"1 + x^8" |
|||
"1 + x^1 + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + x^12 + x^13 + x^14 + x^15 + x^16" |
|||
"1 - x^3 + x^6" |
|||
"1 + x^1 + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + x^12 + x^13 + x^14 + x^15 + x^16 + x^17 + x^18" |
|||
"1 - x^2 + x^4 - x^6 + x^8" |
|||
"1 - x^1 + x^3 - x^4 + x^6 - x^8 + x^9 - x^11 + x^12" |
|||
"1 - x^1 + x^2 - x^3 + x^4 - x^5 + x^6 - x^7 + x^8 - x^9 + x^10" |
|||
"1 + x^1 + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + x^12 + x^13 + x^14 + x^15 + x^16 + x^17 + x^18 + x^19 + x^20 + x^21 + x^22" |
|||
"1 - x^4 + x^8" |
|||
"1 + x^5 + x^10 + x^15 + x^20" |
|||
"1 - x^1 + x^2 - x^3 + x^4 - x^5 + x^6 - x^7 + x^8 - x^9 + x^10 - x^11 + x^12" |
|||
"1 + x^9 + x^18" |
|||
"1 - x^2 + x^4 - x^6 + x^8 - x^10 + x^12" |
|||
"1 + x^1 + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + x^12 + x^13 + x^14 + x^15 + x^16 + x^17 + x^18 + x^19 + x^20 + x^21 + x^22 + x^23 + x^24 + x^25 + x^26 + x^27 + x^28" |
|||
"1 + x^1 - x^3 - x^4 - x^5 + x^7 + x^8" |
|||
---------------------------------------- |
|||
1 appears in CM(1) having 2 terms |
|||
2 appears in CM(105) having 49 terms |
|||
3 appears in CM(385) having 241 terms |
|||
4 appears in CM(1365) having 577 terms |
|||
5 appears in CM(1785) having 769 terms |
|||
6 appears in CM(2805) having 1281 terms |
|||
7 appears in CM(3135) having 1441 terms |
|||
8 appears in CP(6545) having 3841 terms |
|||
9 appears in CP(6545) having 3841 terms |
|||
10 appears in CP(10465) having 6337 terms</pre> |
|||
Computations take a while... |
|||
=={{header|Java}}== |
=={{header|Java}}== |