Ritt-Wu-0.1.0.0: src/Polynomial/Monomial.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-|
-- Module : Data.Massiv.Array
-- Copyright :
-- License : BSD3
-- Maintainer : Jose Seraquive <jose.seraquive@gmail.com>
-- Stability : experimental
-- Portability : non-portable
-}
module Polynomial.Monomial
(
-- Types
Mon(..),
Lex(..),
Revlex(..),
-- Classes
-- Functions
m,
mp,
)
where
import Data.Massiv.Array as A
import Prelude as P
import Data.Char.SScript
import Numeric.Algebra as N
import Data.Function
import Control.DeepSeq
import GHC.Generics (Generic, Generic1)
-- | A wrapper for monomials with a certain (monomial) order
newtype Mon ord = Mon (Array P Ix1 Int) deriving (Generic, NFData, Eq)
--instance NFData (Mon ord) where
-- rnf x = seq x ()
-- * Names for orderings.
-- We didn't choose to define one single type for ordering names for the extensibility.
-- | Lexicographical order
data Lex = Lex
-- | Reverse lexicographical order
data Revlex = Revlex
---multiDeg :: Mon m -> Mon m -> [Int]
-- ----------------------<< FUNCTIONS >>--------------------
-- | Monomial with terms
m :: [Int] -> Mon ord
m [] = Mon $ A.fromList (ParN 1) []
m [0] = Mon $ A.fromList (ParN 1) [] --error "A empty term should be represented as m[]"
m xs = Mon $ A.fromList (ParN 1) xs
-- Function that recive the x_i position with the corresponding exp
-- | Monomial with the term position
mp :: [Int] -> [Int] -> Mon ord
mp xs xz
| lxs /= lxz = error "The size of the position and exponent doesn't correspond"
| otherwise = m $ mpRev xs xz 1
where
lxs = length xs
lxz = length xz
mpRev :: [Int] -> [Int] -> Int -> [Int]
mpRev [] [] _ = []
mpRev (p:ps) (x:xs) n
| p == 0 = error "The initial monomial position is 1 not 0"
| n /= p = 0 : mpRev (p : ps) (x : xs) next
| otherwise = x : mpRev ps xs next
where
next = n P.+ 1
-----------------------------------------------------------------------------------------
-- lex order
-- mp' :: [Int] -> [Int] -> Mon ord
-- mp' xs xz
-- | lxs /= lxz = error "The size of the position and exponent doesn't correspond"
-- | otherwise = m $ reverse (mpRev xs xz 1)
-- where
-- lxs = length xs
-- lxz = length xz
-----------------------------------------------------------------------------------------
------- <<INSTANCES >>--------------
instance Show (Mon ord) where
show (Mon m) = formatSS $ showMon (A.toList m) 1
showMon :: (Num a, Eq a, Ord a, Show a) => [a] -> Int -> String
showMon [] _ = ""
showMon (x:xs) s
| x == 0 = printMon
| null xs = format
| otherwise = format ++ printMon
where
next = succ
format = "x_{" ++ show s ++ "}^{" ++ show x ++ "}"
printMon = showMon xs (next s)
---------------------------------------------------------------------------------------
instance Multiplicative (Mon ord) where
(*) (Mon n) (Mon n') = m (quitZero $ on aux toList n n')
aux :: [Int] -> [Int] -> [Int]
aux [] [] = []
aux (x:xs) [] = x : aux xs []
aux [] (y:yp) = y : aux [] yp
aux (x:xs) (y:yp) = x P.+ y : aux xs yp
quitZero :: [Int] -> [Int]
quitZero [] = []
quitZero xs
| last xs == 0 = quitZero $ init xs
| otherwise = xs
---------------------------------------------------------------------------------------
instance Division (Mon ord) where
(/) (Mon n) (Mon n') = m (quitZero $ on aux' (A.toList) n n')
aux' :: [Int] -> [Int] -> [Int]
aux' [] [] = []
aux' (x:xs) [] = x : aux' xs []
aux' [] (y:yp) = y : aux' [] yp
aux' (x:xs) (y:yp) = x P.- y : aux' xs yp
---------------------------------------pal mar------------------------------------------------
instance Additive (Mon ord) where
(+) (Mon m)(Mon m') = Mon $ verificationMl m m'
---------------------------------------------------------------------------------------
instance Semiring (Mon ord)
instance Abelian (Mon ord)
instance Monoidal (Mon ord) where
zero = Mon empty
instance LeftModule Integer (Mon ord) where
(.*) = undefined
instance RightModule Integer (Mon ord) where
(*.) = undefined
instance LeftModule Natural (Mon ord) where
(.*) = undefined
instance RightModule Natural (Mon ord) where
(*.) = undefined
---------------------------------------------------------------------------------------
instance Group (Mon ord) where
(-) (Mon m)(Mon m') = Mon $ verificationMl m m'
verificationMl :: Array P Ix1 Int -> Array P Ix1 Int -> Array P Ix1 Int
verificationMl xs xz
| xs == xz = xs
| otherwise = error "The monomial doesn't match "
---------------------------------------------------------------------------------------
-- sujeto a revision cunado se realize la diviision
-- polynomial, delay es el mas optimo porque no se realizan
-- operaciones "estrictas sobre los monomios"
-- si seq evalua sequencial es correcto (verificar)
-- deberia usar force?
---------------------------------------------------------------------------------------
instance Ord (Mon Lex) where
compare (Mon m)(Mon m') = on lex' A.toList m m'
(>) (Mon m)(Mon m')= on (P.>) A.toList m m'
(<) (Mon m)(Mon m')= on (P.<) A.toList m m'
lex' :: (Num a, Eq a, Ord a) => [a] -> [a] -> Ordering
lex' [] [] = EQ
lex' [] _ = LT
lex' _ [] = GT
lex' (x:xs) (y:ys)
| x == y = lex' xs ys
| x P.> y = GT
| otherwise = LT
---------------------------------------------------------------------------------------
instance Ord (Mon Revlex) where
compare (Mon m)(Mon m')= on revlex' A.toList m m'
revlex' :: (Num a, Eq a, Ord a) => [a] -> [a] -> Ordering
revlex' = on lex' P.reverse
---------------------------------------------------------------------------------------
instance Unital (Mon ord ) where
one = undefined --Mon empty