{-# LANGUAGE DataKinds, ExplicitNamespaces, GADTs, PatternSynonyms #-} {-# OPTIONS_GHC -fno-warn-unused-imports -Wno-type-defaults #-} module UnivariateSpec where import Algebra.Algorithms.Groebner import Algebra.Field.Finite import Algebra.Internal (pattern (:<), KnownNat, pattern NilL, SNat) import Algebra.Ring.Polynomial (OrderedPolynomial) import Algebra.Ring.Polynomial.Univariate import Control.Monad import qualified Data.Foldable as F import Data.List (delete) import qualified Data.Sized.Builtin as SV import Data.Type.Monomorphic import Numeric.Decidable.Zero import Numeric.Field.Fraction (Fraction) import Test.Hspec import Test.Hspec.QuickCheck import Test.QuickCheck import Utils asGenListOf :: Gen [a] -> a -> Gen [a] asGenListOf = const toOP :: Unipol Integer -> OrderedPolynomial Integer Grevlex 1 toOP = injectVars liftMult :: Unipol Integer -> Unipol Integer -> Unipol Integer liftMult f g = let (f', g') = (toOP f, toOP g) in injectVars (f' * g') spec :: Spec spec = do describe "naiveMult" $ do prop "Works as expected" $ \f g -> (f `naiveMult` g) == (f `liftMult` g) describe "karatsuba" $ do prop "Works as expected" $ \f g -> (karatsuba f g) == (f `liftMult` g) describe "divModUnipolByMult" $ do prop "remainder has degree smaller than divisor" $ \f g -> (totalDegree' f > 0 && totalDegree' g > 0) ==> let (q, r) = divModUnipolByMult f (g :: Unipol (F 5)) in totalDegree' r < totalDegree' g prop "divides correctly" $ \f g -> not (isZero g) ==> let (q, r) = divModUnipolByMult f (g :: Unipol (F 5)) in q * g + r == f it "passes regression tests" $ do mapM_ (\((a,b),(c,d)) -> divModUnipolByMult a b `shouldBe` (c, d)) divModUnipolCases describe "divModUnipol" $ do prop "remainder has degree smaller than divisor" $ \f g -> totalDegree' f > 0 && totalDegree' g > 0 ==> let (q, r) = divModUnipol f (g :: Unipol (F 5)) in totalDegree' r < totalDegree' g prop "divides correctly" $ \f g -> not (isZero g) ==> let (q, r) = divModUnipol f (g :: Unipol (F 5)) in q * g + r == f divModUnipolCases :: [((Unipol (F 5), Unipol (F 5)), (Unipol (F 5), Unipol (F 5)))] divModUnipolCases = [((3*x^57 + x^56 + x^55 + 2*x^52 + 2*x^51 + 4*x^50 + x^49 + 4*x^48 + 3*x^47 + 4*x^46 + 3*x^45 + 3*x^44 + 3*x^42 + 3*x^41 + x^40 + x^39 + 2*x^38 + 3*x^37 + x^36 + 2*x^35 + 4*x^34 + 3*x^33 + 4*x^32 + 3*x^31 + x^30 + 3*x^28 + x^26 + x^25 + 3*x^24 + x^22 + 4*x^21 + 3*x^20 + 2*x^19 + 4*x^18 + 4*x^17 + 2*x^16 + x^15 + 3*x^13 + 2*x^12 + x^11 + x^10 + 4*x^9 + 4*x^8 + 2*x^7 + x^6 + 2*x^5 + 4*x^4 + 2*x^3 + 2*x^2 + 3*x + 4, 3*x^19 +2*x^18 +4*x^17 +3*x^16 +4*x^13 +3*x^12 + x^11 +4*x^10 +2*x^8 +2*x^7 +2*x^6 +4*x^4 +2*x^3 +4*x^2 +3*x + 2),(x^38 +3*x^37 +2*x^36 +2*x^35 +3*x^34 +4*x^33 +4*x^32 +2*x^31 +2*x^30 +3*x^29 +2*x^28 +3*x^26 + x^25 + x^24 +3*x^23 +2*x^22 +2*x^20 +3*x^18 +2*x^17 +3*x^16 +4*x^15 + x^14 +4*x^13 +3*x^12 +2*x^11 +3*x^10 +2*x^9 +4*x^7 +3*x^5 +2*x^4 +3*x^3 +2*x^2 + x + 2,2*x^18 +4*x^17 +3*x^16 +2*x^15 +4*x^14 +4*x^12 +2*x^11 +4*x^10 +3*x^8 + x^6 +3*x^4 +2*x^3 +2*x^2))] where x = var 0