Guest User

Untitled

a guest
Mar 23rd, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.15 KB | None | 0 0
  1. import Data.List (intercalate, foldl')
  2.  
  3. data Monom c a = M c [a] deriving (Eq)
  4. newtype Polynom c a = P [Monom c a] deriving (Eq)
  5.  
  6. instance (Eq c, Ord a) => Ord (Monom c a) where
  7. compare (M _ asl) (M _ asr) = compare asl asr
  8.  
  9. instance (Show a, Show c, Num a, Num c, Eq a, Eq c) => Show (Monom c a) where
  10. show (M c as) = (if c == 1 then "" else show c) ++
  11. (intercalate "∙" $ map showOne $ (filter (\(p,_) -> p /= 0) $ zip as [1..]))
  12. where showOne (p,i) = "x" ++ (show i) ++ (if p == 1 then "" else "^" ++ (show p))
  13.  
  14. instance (Show a, Show c, Num a, Num c, Eq a, Eq c) => Show (Polynom c a) where
  15. show (P ms) = intercalate " + " $ map show ms
  16.  
  17. lt :: Polynom c a -> Monom c a
  18. lt (P as) = head as
  19.  
  20. zero :: (Num c, Eq c) => Monom c a -> Bool
  21. zero (M c _) = c == 0
  22.  
  23. zeroP :: Polynom c a -> Bool
  24. zeroP (P as) = null as
  25.  
  26. similar :: (Eq a) => Monom c a -> Monom c a -> Bool
  27. similar (M _ asl) (M _ asr) = asl == asr
  28.  
  29. addSimilar :: (Num c) => Monom c a -> Monom c a -> Monom c a
  30. addSimilar (M cl as) (M cr _) = M (cl+cr) as
  31.  
  32. mulMono :: (Num a, Num c) => Monom c a -> Monom c a -> Monom c a
  33. mulMono (M cl asl) (M cr asr) = M (cl*cr) (zipWith (+) asl asr)
  34.  
  35. scale :: (Num c) => c -> Monom c a -> Monom c a
  36. scale c' (M c as) = M (c*c') as
  37.  
  38. addPoly :: (Eq a, Eq c, Num c, Ord a) => Polynom c a -> Polynom c a -> Polynom c a
  39. addPoly (P l) (P r) = P $ go l r
  40. where
  41. go [] [] = []
  42. go as [] = as
  43. go [] bs = bs
  44. go (a:as) (b:bs) =
  45. if similar a b then
  46. if (zero $ addSimilar a b) then
  47. go as bs
  48. else
  49. (addSimilar a b):(go as bs)
  50. else
  51. if a > b then
  52. a:(go as (b:bs))
  53. else
  54. b:(go (a:as) bs)
  55.  
  56. mulPM :: (Ord a, Eq c, Num a, Num c) => Polynom c a -> Monom c a -> Polynom c a
  57. mulPM(P as) m = P $ map (mulMono m) as
  58.  
  59. mulM :: (Eq c, Num c, Num a, Ord a) => Polynom c a -> Polynom c a -> Polynom c a
  60. mulM l@(P ml) r@(P mr) = foldl' addPoly (P []) $ map (mulPM r) ml
  61.  
  62. dividable :: (Ord a) => Monom c a -> Monom c a -> Bool
  63. dividable (M _ al) (M _ ar) = and $ zipWith (>=) al ar
  64.  
  65. divideM :: (Fractional c, Num a) => Monom c a -> Monom c a -> Monom c a
  66. divideM (M cl al) (M cr ar) = M (cl/cr) (zipWith (-) al ar)
  67.  
  68. reducable :: (Ord a) => Polynom c a -> Polynom c a -> Bool
  69. reducable l r = dividable (lt l) (lt r)
  70.  
  71. reduce :: (Eq c, Fractional c, Num a, Ord a) =>
  72. Polynom c a -> Polynom c a -> Polynom c a
  73. reduce l r = addPoly l r'
  74. where r' = mulPM r (scale (-1) q)
  75. q = divideM (lt l) (lt r)
  76.  
  77. reduceMany :: (Eq c, Fractional c, Num a, Ord a) =>
  78. Polynom c a -> [Polynom c a] -> Polynom c a
  79. reduceMany h fs = if reduced then reduceMany h' fs else h'
  80. where (h', reduced) = reduceStep h fs False
  81. reduceStep h (f:fs) r
  82. | zeroP h = (h, r)
  83. | otherwise = if reducable h f then
  84. (reduce h f, True)
  85. else
  86. reduceStep h fs r
  87. reduceStep h [] r = (h, r)
  88.  
  89. lcmM :: (Num c, Ord a) => Monom c a -> Monom c a -> Monom c a
  90. lcmM (M cl al) (M cr ar) = M (cl*cr) (zipWith max al ar)
  91.  
  92. makeSPoly :: (Eq c, Fractional c, Num a, Ord a) =>
  93. Polynom c a -> Polynom c a -> Polynom c a
  94. makeSPoly l r = addPoly l' r'
  95. where l' = mulPM l ra
  96. r' = mulPM r la
  97. lcm = lcmM (lt l) (lt r)
  98. ra = divideM lcm (lt l)
  99. la = scale (-1) $ divideM lcm (lt r)
  100.  
  101. checkOne :: (Eq c, Fractional c, Num a, Ord a) =>
  102. Polynom c a -> [Polynom c a] -> [Polynom c a] -> [Polynom c a]
  103. checkOne f checked@(c:cs) add = if zeroP s then
  104. checkOne f cs add
  105. else
  106. s:(checkOne f cs (add ++ [s]))
  107. where s = reduceMany (makeSPoly f c) (checked++add)
  108. checkOne _ [] _ = []
  109.  
  110. makeGroebner :: (Eq c, Fractional c, Num a, Ord a) =>
  111. [Polynom c a] -> [Polynom c a]
  112. makeGroebner (b:bs) = build [b] bs
  113. where build checked add@(a:as) = build (checked ++ [a]) (as ++ (checkOne a checked add))
  114. build checked [] = checked
Add Comment
Please, Sign In to add comment