huzzy 0.1.0.0 → 0.1.5.0
raw patch · 9 files changed
+184/−66 lines, 9 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Huzzy.Base.Sets: approximate' :: Double -> Double -> [Double] -> MF' Double
- Huzzy.Base.Sets: bell' :: Double -> Double -> Double -> MF' Double
- Huzzy.Base.Sets: cyl' :: Double -> Double -> MF' Double
- Huzzy.Base.Sets: discrete' :: Eq a => [(a, Double)] -> MF' a
- Huzzy.Base.Sets: extremely' :: MF' a -> MF' a
- Huzzy.Base.Sets: gaus' :: Double -> Double -> MF' Double
- Huzzy.Base.Sets: hedge' :: Double -> MF' a -> MF' a
- Huzzy.Base.Sets: lb' :: Ord a => [a] -> a
- Huzzy.Base.Sets: sig' :: Double -> Double -> MF' Double
- Huzzy.Base.Sets: singleton' :: Double -> MF' a
- Huzzy.Base.Sets: slightly' :: MF' a -> MF' a
- Huzzy.Base.Sets: somewhat' :: MF' a -> MF' a
- Huzzy.Base.Sets: support' :: [a] -> MF' a -> [a]
- Huzzy.Base.Sets: tNo :: Fuzzy a => FuzOp a -> a -> a -> a
- Huzzy.Base.Sets: trap' :: Double -> Double -> Double -> Double -> MF' Double
- Huzzy.Base.Sets: tri' :: Double -> Double -> Double -> MF' Double
- Huzzy.Base.Sets: type FuzOp a = a -> a -> a
- Huzzy.Base.Sets: type MF' a = a -> Double
- Huzzy.Base.Sets: ub' :: Ord a => [a] -> a
- Huzzy.Base.Sets: up' :: Double -> Double -> MF' Double
- Huzzy.Base.Sets: very' :: MF' a -> MF' a
- Huzzy.Base.Systems: RB :: [a] -> RuleBase a
- Huzzy.Base.Systems: aggregate :: FRule a => RuleBase a -> (a -> a -> a) -> a
- Huzzy.Base.Systems: newtype FRule a => RuleBase a
- Huzzy.TypeOne.Sets: T1S :: MF a -> [a] -> T1Set a
- Huzzy.TypeOne.Sets: dom :: T1Set a -> [a]
- Huzzy.TypeOne.Sets: mf :: T1Set a -> MF a
- Huzzy.TypeOne.Sets: trustedCont :: (Num a, Enum a) => a -> a -> a -> MF a -> T1Set a
- Huzzy.TypeOne.Sets: trustedDisc :: [a] -> MF a -> T1Set a
- Huzzy.TypeTwo.Interval.Sets: IT2S :: MF a -> MF a -> [a] -> IT2Set a
- Huzzy.TypeTwo.Interval.Sets: idom :: IT2Set a -> [a]
- Huzzy.TypeTwo.Interval.Sets: lmf :: IT2Set a -> MF a
- Huzzy.TypeTwo.Interval.Sets: umf :: IT2Set a -> MF a
- Huzzy.TypeTwo.Interval.Systems: findK :: Int -> Double -> [Double] -> Maybe Int
- Huzzy.TypeTwo.Interval.Systems: getWS :: IT2Set a -> [a] -> ([Double], [Double])
- Huzzy.TypeTwo.Interval.Systems: getWeights :: ([Double], [Double]) -> [Double]
- Huzzy.TypeTwo.Interval.Systems: getXS :: Ord a => ([a], [a]) -> [a]
- Huzzy.TypeTwo.Interval.Systems: kmr :: IT2Set Double -> (Double, Int)
- Huzzy.TypeTwo.Interval.Systems: lWeights :: [Double] -> [Double] -> Int -> [Double]
- Huzzy.TypeTwo.Interval.Systems: rWeights :: [Double] -> [Double] -> Int -> [Double]
- Huzzy.TypeTwo.Interval.Systems: weightedSum :: [Double] -> [Double] -> Double
- Huzzy.TypeTwo.ZSlices.Sets: T2ZS :: Int -> [IT2Set a] -> [a] -> T2ZSet a
- Huzzy.TypeTwo.ZSlices.Sets: t2Tri :: (Double, Double) -> (Double, Double) -> (Double, Double) -> Int -> T2ZSet Double
- Huzzy.TypeTwo.ZSlices.Sets: zLevels :: T2ZSet a -> Int
- Huzzy.TypeTwo.ZSlices.Sets: zSlices :: T2ZSet a -> [IT2Set a]
- Huzzy.TypeTwo.ZSlices.Sets: zdom :: T2ZSet a -> [a]
+ Huzzy.Base.Sets: down :: Double -> Double -> MF Double
+ Huzzy.TypeOne.Sets: (?&&) :: Fuzzy a => a -> a -> a
+ Huzzy.TypeOne.Sets: (?||) :: Fuzzy a => a -> a -> a
+ Huzzy.TypeOne.Sets: class FSet a where type family Value a type family Support a type family Returned a
+ Huzzy.TypeOne.Sets: class Fuzzy a
+ Huzzy.TypeOne.Sets: fnot :: Fuzzy a => a -> a
+ Huzzy.TypeOne.Sets: hedge :: FSet a => Double -> a -> a
+ Huzzy.TypeOne.Sets: is :: FSet a => Value a -> a -> Returned a
+ Huzzy.TypeOne.Sets: support :: FSet a => a -> Support a
+ Huzzy.TypeOne.Systems: (=*>) :: FRule a => Antecedent a -> a -> a
+ Huzzy.TypeOne.Systems: (=|>) :: FRule a => Antecedent a -> a -> a
+ Huzzy.TypeOne.Systems: centroid :: Defuzzifier a => a -> Result a
+ Huzzy.TypeOne.Systems: class FRule a => Defuzzifier a where type family Result a
+ Huzzy.TypeOne.Systems: class Fuzzy a => FRule a where type family Antecedent a
+ Huzzy.TypeOne.Systems: weight :: FRule a => a -> Double -> a
+ Huzzy.TypeTwo.Interval.Sets: (?&&) :: Fuzzy a => a -> a -> a
+ Huzzy.TypeTwo.Interval.Sets: (?||) :: Fuzzy a => a -> a -> a
+ Huzzy.TypeTwo.Interval.Sets: class FSet a where type family Value a type family Support a type family Returned a
+ Huzzy.TypeTwo.Interval.Sets: class Fuzzy a
+ Huzzy.TypeTwo.Interval.Sets: fnot :: Fuzzy a => a -> a
+ Huzzy.TypeTwo.Interval.Sets: hedge :: FSet a => Double -> a -> a
+ Huzzy.TypeTwo.Interval.Sets: is :: FSet a => Value a -> a -> Returned a
+ Huzzy.TypeTwo.Interval.Sets: support :: FSet a => a -> Support a
+ Huzzy.TypeTwo.Interval.Systems: (=*>) :: FRule a => Antecedent a -> a -> a
+ Huzzy.TypeTwo.Interval.Systems: (=|>) :: FRule a => Antecedent a -> a -> a
+ Huzzy.TypeTwo.Interval.Systems: centroid :: Defuzzifier a => a -> Result a
+ Huzzy.TypeTwo.Interval.Systems: class FRule a => Defuzzifier a where type family Result a
+ Huzzy.TypeTwo.Interval.Systems: class Fuzzy a => FRule a where type family Antecedent a
+ Huzzy.TypeTwo.Interval.Systems: weight :: FRule a => a -> Double -> a
+ Huzzy.TypeTwo.ZSlices.Sets: (?&&) :: Fuzzy a => a -> a -> a
+ Huzzy.TypeTwo.ZSlices.Sets: (?||) :: Fuzzy a => a -> a -> a
+ Huzzy.TypeTwo.ZSlices.Sets: class FSet a where type family Value a type family Support a type family Returned a
+ Huzzy.TypeTwo.ZSlices.Sets: class Fuzzy a
+ Huzzy.TypeTwo.ZSlices.Sets: fnot :: Fuzzy a => a -> a
+ Huzzy.TypeTwo.ZSlices.Sets: hedge :: FSet a => Double -> a -> a
+ Huzzy.TypeTwo.ZSlices.Sets: is :: FSet a => Value a -> a -> Returned a
+ Huzzy.TypeTwo.ZSlices.Sets: mkT2Tri :: (Double, Double) -> (Double, Double) -> (Double, Double) -> Int -> T2ZSet Double
+ Huzzy.TypeTwo.ZSlices.Sets: support :: FSet a => a -> Support a
+ Huzzy.TypeTwo.ZSlices.Systems: (=*>) :: FRule a => Antecedent a -> a -> a
+ Huzzy.TypeTwo.ZSlices.Systems: (=|>) :: FRule a => Antecedent a -> a -> a
+ Huzzy.TypeTwo.ZSlices.Systems: centroid :: Defuzzifier a => a -> Result a
+ Huzzy.TypeTwo.ZSlices.Systems: class FRule a => Defuzzifier a where type family Result a
+ Huzzy.TypeTwo.ZSlices.Systems: class Fuzzy a => FRule a where type family Antecedent a
+ Huzzy.TypeTwo.ZSlices.Systems: weight :: FRule a => a -> Double -> a
Files
- huzzy.cabal +2/−2
- src/Huzzy/Base/Sets.hs +63/−19
- src/Huzzy/Base/Systems.hs +10/−6
- src/Huzzy/TypeOne/Sets.hs +26/−15
- src/Huzzy/TypeOne/Systems.hs +8/−1
- src/Huzzy/TypeTwo/Interval/Sets.hs +22/−2
- src/Huzzy/TypeTwo/Interval/Systems.hs +8/−7
- src/Huzzy/TypeTwo/ZSlices/Sets.hs +40/−12
- src/Huzzy/TypeTwo/ZSlices/Systems.hs +5/−2
huzzy.cabal view
@@ -2,8 +2,8 @@ -- see http://haskell.org/cabal/users-guide/ name: huzzy-version: 0.1.0.0-synopsis: Fuzzy logic library with support for Type-1, Interval type-2 and zSlices enabled type-2 fuzzy sets and systems.+version: 0.1.5.0+synopsis: Fuzzy logic library with support for T1, IT2, GT2. description: Library for creating fuzzy sets and systems. There are known issues with overly precise values in Type-2 sets.
src/Huzzy/Base/Sets.hs view
@@ -1,20 +1,57 @@-module Huzzy.Base.Sets where+module Huzzy.Base.Sets+( MF(..)+, Fuzzy(..)+, FSet(..)+, tCo+, tGodel+, tProd+, tLuk+, tDras+, tNilMin+, tHam+, discrete+, singleton+, tri+, trap+, bell+, gaus+, up+, down+, sig+) where +-- | Type representing type-1 membership functions. newtype MF a = MF (a -> Double)+-- | Used internally to represent type-1 membership functions.+-- Not exported for safety reasons.+-- Library users, use the newtype. type MF' a = a -> Double +-- | FuzOp is used to denote functions expecting operators on fuzzy sets. type FuzOp a = a -> a -> a +-- | Standard operations on fuzzy sets.+-- Instantiated for each kind of fuzzy set.+-- If you want to overload with a t-norm, instantiate against a newtype or instantiated set. class Fuzzy a where+ -- | Union over fuzzy values. (?&&) :: a -> a -> a+ -- | Intersection over fuzzy values. (?||) :: a -> a -> a+ -- | Fuzzy complement. fnot :: a -> a +-- | Standard definitions for operations as defined by Zadeh (1965) instance Fuzzy Double where+ -- | Equivalent to use of the Godel t-conorm,+ -- > (?&&) = tCo tGodel (?&&) = max+ -- | Equivalent to use of the Godel t-norm,+ -- > (?||) = tGodel (?||) = min fnot x = 1 - x +-- | Fuzzy operators for membership functions. instance (Fuzzy b) => Fuzzy (a -> b) where f ?&& g = \x -> f x ?&& g x f ?|| g = \x -> f x ?|| g x@@ -25,19 +62,29 @@ (MF f) ?|| (MF g) = MF (f ?|| g) fnot (MF f) = MF (fnot f) +-- | Instance for tuple needed for interval type-2 fuzzy sets. instance (Fuzzy a, Fuzzy b) => Fuzzy (a, b) where (a, b) ?&& (c, d) = (a ?&& c, b ?&& d) (a ,b) ?|| (c, d) = (a ?|| c, b ?|| d) fnot (a, b) = (fnot a, fnot b) +-- | Specifically for fuzzy sets, as opposed to fuzzy values.+-- Support is all elements of domain for which membership is non-zero.+-- Hedge is a modifier of fuzzy sets.+-- `is` is for application of a value to a fuzzy set. class FSet a where+ -- | A single value of the domain. type Value a+ -- | A list of values from the domain for which membership is non-zero. type Support a+ -- | Degree of membership from applying a value to membership function. type Returned a support :: a -> Support a hedge :: Double -> a -> a is :: Value a -> a -> Returned a-{-++{- Old functional dependency definition, remains for+report purposes. class FSet a b c d | a -> b, a -> c, a -> d where support :: a -> [c] hedge :: Double -> a -> a@@ -47,9 +94,11 @@ tNo :: Fuzzy a => FuzOp a -> a -> a -> a tNo op = op +-- | Produces the dual t-conorm from a t-norm tCo :: (Num a, Fuzzy a) => FuzOp a -> a -> a -> a tCo tNo a b = (-) 1 $ tNo (1 - a) (1 - b) +-- | Standard t-norm used for intersection. tGodel :: (Fuzzy a, Ord a) => FuzOp a tGodel = min @@ -79,23 +128,14 @@ hedge' p f x | f x == 0 = 0 | otherwise = f x ** p -approximate' :: Double -> Double -> [Double] -> MF' Double-approximate' fuzziness n dom = tri' a b c- where hw = fuzziness * (ub' dom - lb' dom)- a = (n - hw)- b = (n+hw)- c = b-((b-a)*0.5)--ub', lb' :: Ord a => [a] -> a-ub' = maximum-lb' = maximum- very', extremely', somewhat', slightly' :: MF' a -> MF' a very' = hedge' 2 extremely' = hedge' 3 somewhat' = hedge' 0.5 slightly' = hedge' (1/3) +-- | Ensure that input list is correctly ordered for desired performance.+-- I.e. if desired property is that for a u with 2 values of z, max is chosen, order descending on right value of tuple. discrete :: Eq a => [(a, Double)] -> MF a discrete vs = MF (\x -> discrete' vs x) @@ -104,6 +144,7 @@ Just t -> t Nothing -> 0 +-- | Used for type-2 defuzzification. singleton :: Double -> MF a singleton d = MF (\x -> singleton' d x) @@ -119,6 +160,15 @@ | x < b = (x - a) / (b - a) | otherwise = 1 +down :: Double -> Double -> MF Double+down a b = MF (\x -> down' a b x)++down' :: Double -> Double -> MF' Double+down' a b x+ | x < a = 1.0+ | x < b = (x-b)/(a-b)+ | otherwise = 0.0+ tri :: Double -> Double -> Double -> MF Double tri a b c = MF (\x -> tri' a b c x) @@ -155,9 +205,3 @@ sig' :: Double -> Double -> MF' Double sig' a c x = 1/(1+exp(-a*(x-c)))---- Probably shit--cyl' :: Double -> Double -> MF' Double-cyl' a b x | sqrt (a**2 + b**2) <= x = 1- | sqrt (a**2 + b**2) > x = 0
src/Huzzy/Base/Systems.hs view
@@ -1,13 +1,19 @@-module Huzzy.Base.Systems where+module Huzzy.Base.Systems+( FRule(..)+, Defuzzifier(..)+) where import Huzzy.Base.Sets -newtype FRule a => RuleBase a = RB [a]-+-- | Allows overloading of functions used in rule definition. class Fuzzy a => FRule a where+ -- | Firing strength type Antecedent a+ -- | Scaling implication. (=*>) :: Antecedent a -> a -> a+ -- | Truncate implication. (=|>) :: Antecedent a -> a -> a+ -- | Weight a rule weight :: a -> Double -> a instance FRule Double where@@ -28,10 +34,8 @@ (=|>) a (MF f) = MF (\x -> a =|> f x) weight (MF f) b = MF (\x -> f x `weight` b) +-- | Overloaded defuzzification functions. class FRule a => Defuzzifier a where type Result a centroid :: a -> Result a --aggregate :: FRule a => RuleBase a -> (a -> a -> a) -> a-aggregate (RB rules) agg = foldr1 agg rules
src/Huzzy/TypeOne/Sets.hs view
@@ -1,21 +1,38 @@-module Huzzy.TypeOne.Sets where+module Huzzy.TypeOne.Sets+( T1Set(mf, dom)+, Fuzzy(..)+, FSet(..)+, contT1+, discT1+, unsafeMkT1+, alpha+, findCuts+)where import Data.List(sortBy, nub, elemIndex) import Data.Maybe(fromJust) import Huzzy.Base.Sets ++-- | Type-1 fuzzy sets, with associated membership function and domain. Use smart constructors to create. data T1Set a = T1S { mf :: MF a , dom :: [a] } +-- | Fuzzy operators are supported on T1Sets.+-- Applies operator to membership functions inside T1Set type. instance Fuzzy (T1Set a) where a ?&& b = a { mf = (mf a) ?&& (mf b)} a ?|| b = a { mf = (mf a) ?|| (mf b)} fnot a = a { mf = fnot (mf a)} +-- | Type-1 fuzzy sets are the most basic fuzzy set. instance FSet (T1Set a) where+ -- | Single element of the domain. type Value (T1Set a) = a+ -- | List of elements from the domain with non-zero membership. type Support (T1Set a) = [a]+ -- | Type-1 membership functions return a double, hopefully in the range 0 to 1. type Returned (T1Set a) = Double support s = filter (\x -> (x `is` s) > 0) d where@@ -45,9 +62,7 @@ (MF f) = mf s -} --- Smart Constructors--- continuous :: a -> a -> a -> MF a -> T1Set a-+-- | Smart constructor for continuous membership functions. Warning, fine resolutions will make this a very slow construction. contT1 :: (Num a, Enum a) => a -> a -> a -> MF a -> T1Set a contT1 minB maxB res (MF mf) = case check of True -> error "Truth values must be in the range [0..1]"@@ -58,6 +73,7 @@ domain = [minB, minB+res .. maxB] check = any (\x -> x > 1 || x < 0) (map mf domain) +-- | Smart constructor for discrete continuous membership functions. Avoid large domains. discT1 :: [a] -> MF a -> T1Set a discT1 dom (MF mf) = case check of True -> error "Truth values must be in the range [0..1]"@@ -67,24 +83,19 @@ where check = any (\x -> x > 1 || x < 0) (map mf dom) -trustedCont :: (Num a, Enum a) => a -> a -> a -> MF a -> T1Set a-trustedCont minB maxB res mf = T1S { mf = mf- , dom = [minB, minB+res .. maxB]- }--trustedDisc :: [a] -> MF a -> T1Set a-trustedDisc dom mf = T1S { mf = mf- , dom = dom- }-+-- | Only use this if you're sure your membership functions are safe, or your domain is huge. unsafeMkT1 :: [a] -> MF a -> T1Set a-unsafeMkT1 = trustedDisc+unsafeMkT1 dom mf = T1S { mf = mf+ , dom = dom+ } +-- | Cuts a type-1 fuzzy set at a given degree of membership. alpha :: Double -> T1Set a -> [a] alpha d s = filter (\x -> f x >= d) (dom s) where (MF f) = mf s +-- | Performs a cut and then finds the x values on the curve at point of cut. findCuts :: Ord a => T1Set a -> Double -> (a, a) findCuts s d = (l, r) where
src/Huzzy/TypeOne/Systems.hs view
@@ -1,10 +1,15 @@-module Huzzy.TypeOne.Systems where+module Huzzy.TypeOne.Systems+( FRule(..)+, Defuzzifier(..)+) where import Huzzy.Base.Sets import Huzzy.Base.Systems import Huzzy.TypeOne.Sets +-- | Simple type-1 fuzzy rule systems. instance FRule (T1Set a) where+ -- | Firing strength of Type-1 rules is just membership grade. type Antecedent (T1Set a) = Double (=*>) a t1s = t1s { mf = a =*> (mf t1s)} (=|>) a t1s = t1s { mf = a =|> (mf t1s)}@@ -12,6 +17,8 @@ instance Defuzzifier (T1Set Double) where type Result (T1Set Double) = Double+ -- | Centroid can be a computationally costly operation.+ -- Reducing resolution of the domain can reduce costs. centroid t1s = sum (zipWith (*) dom' fdom) / sum fdom where dom' = dom t1s
src/Huzzy/TypeTwo/Interval/Sets.hs view
@@ -1,21 +1,38 @@-module Huzzy.TypeTwo.Interval.Sets where+module Huzzy.TypeTwo.Interval.Sets+( IT2Set(lmf, umf, idom)+, Fuzzy(..)+, FSet(..)+, contIT2+, discIT2+, unsafeMkIT2+, cylExt+)where import Huzzy.Base.Sets import Huzzy.TypeOne.Sets +-- | Interval Type-2 Fuzzy sets.+-- Defined entirely by the footprint of uncertainty,+-- lmf and umf are the bounds of this area. data IT2Set a = IT2S { lmf :: MF a , umf :: MF a , idom :: [a] } +-- | Interval Type-2 fuzzy sets allow us to work in type-1 concepts.+-- Operators are defined through application to lower and upper membership functions. instance Fuzzy (IT2Set a) where a ?&& b = a { lmf = lmf a ?&& lmf b, umf = umf a ?&& umf b} a ?|| b = a { lmf = lmf a ?|| lmf b, umf = umf a ?|| umf b} fnot a = a { lmf = fnot (lmf a), umf = fnot (umf a)} +-- | Enables use of support, hedge and `is` on interval type-2 fuzzy sets. instance FSet (IT2Set a) where+ -- | Single value from the domain. type Value (IT2Set a) = a+ -- | List of pairs with non-zero membership to lmf and umf. type Support (IT2Set a) = [(a,a)]+ -- | Applying a value to an interval set gives an interval membership value. type Returned (IT2Set a) = (Double, Double) support s = filter (\(x,y) -> (fst $ xis x) > 0 || (snd $ xis y) > 0) d where@@ -60,6 +77,7 @@ (MF u) = umf s -} +-- | Smart constructor for continuos interval type-2 membership functions. Watch that resolution! contIT2 :: (Num a, Enum a) => a -> a -> a -> MF a -> MF a -> IT2Set a contIT2 minB maxB res (MF lmf) (MF umf) = case check of True -> error "Truth values must be in the range [0..1]"@@ -74,7 +92,7 @@ check = any (\x -> x > 1 || x < 0) (map lmf domain) check' = any (\x -> x > 1 || x < 0) (map umf domain) -+-- | Smart constructor for discrete interval type-2 membership functions. Be wary of domain size. discIT2 :: [a] -> MF a -> MF a -> IT2Set a discIT2 dom (MF lmf) (MF umf) = case check of True -> error "Truth values must be in the range [0..1]"@@ -88,10 +106,12 @@ check = any (\x -> x > 1 || x < 0) (map lmf dom) check' = any (\x -> x > 1 || x < 0) (map umf dom) +-- | Only use this if you trust your functions or have no other recourse. unsafeMkIT2 :: [a] -> MF a -> MF a -> IT2Set a unsafeMkIT2 dom lmf umf = IT2S { lmf = lmf , umf = umf , idom = dom } +-- | Used in zSlices type-2 defuzzification cylExt :: Double -> Double -> IT2Set a cylExt l u = unsafeMkIT2 [] (singleton l) (singleton u)
src/Huzzy/TypeTwo/Interval/Systems.hs view
@@ -1,4 +1,8 @@-module Huzzy.TypeTwo.Interval.Systems where+module Huzzy.TypeTwo.Interval.Systems+( FRule(..)+, Defuzzifier(..)+, km+) where import Data.List import Huzzy.Base.Sets@@ -6,6 +10,7 @@ import Huzzy.TypeTwo.Interval.Sets instance FRule (IT2Set a) where+ -- | Firing strength is membership grade of both lmf and umf. type Antecedent (IT2Set a) = (Double, Double) (=*>) (a,b) it2 = it2 { lmf = a =*> (lmf it2) , umf = b =*> (umf it2)@@ -24,12 +29,8 @@ (yl, yr, _, _) = km its -{---Karnik mendel haskell-todo dirty hack fix--}-+-- | Karnik-Mendel algorithm.+-- Currently needs a big overhaul. km :: IT2Set Double -> ( Double -- yl , Double -- yr , Int -- k l
src/Huzzy/TypeTwo/ZSlices/Sets.hs view
@@ -1,24 +1,39 @@-module Huzzy.TypeTwo.ZSlices.Sets where+module Huzzy.TypeTwo.ZSlices.Sets+( T2ZSet(zLevels, zSlices, zdom)+, Fuzzy(..)+, FSet(..)+, contZT2+, discZT2+, unsafeZT2+, cylExtT2+, mkT2Tri+, zLevelAxis+)where -import Data.Function-import Data.List+import Data.Function(on)+import Data.List(sortBy) import Huzzy.Base.Sets import Huzzy.TypeOne.Sets import Huzzy.TypeTwo.Interval.Sets +-- | A zSlices based type-2 set requires the number of z levels, and a list of zslices. data T2ZSet a = T2ZS { zLevels :: Int , zSlices :: [IT2Set a] , zdom :: [a] }-+-- | Operations on zSlices fuzzy sets are simply defined as higher order funcitons over the list of zSlices. instance Fuzzy (T2ZSet a) where a ?&& b = a { zLevels = zLevels a, zSlices = zipWith (?&&) (zSlices a) (zSlices b) } a ?|| b = a { zLevels = zLevels a, zSlices = zipWith (?||) (zSlices a) (zSlices b) } fnot a = a { zLevels = zLevels a, zSlices = map (fnot) (zSlices a) } +-- | Currently the most complex supported fuzzy set. instance FSet (T2ZSet a) where+ -- | Single value of the domain. type Value (T2ZSet a) = a+ -- | Supprt in zSlices only works on the base interval set. type Support (T2ZSet a) = [(a,a)]+ -- | Type-2 membership functions return a vertical slice, a type-1 membership function. type Returned (T2ZSet a) = MF Double support s = support (head $ zSlices s) hedge d s = s { zSlices = map (hedge d) (zSlices s)}@@ -27,7 +42,7 @@ its = zSlices s (ls, us) = unzip $ map (x`is`) its zs = zLevelAxis (length its)- -- todo dirty hack to ensure max is returned+ -- | Order the list to ensure maximum z value is returned in case of multiple z values existing for a given u. disPairs = sortBy (flip compare `on` snd ) $ zip ls zs ++ zip us zs @@ -39,6 +54,9 @@ count s 0 = [s*n'] count s z = (s*(n'-z)) : count s (z-1) ++-- | Smart constructor for continuous type-2 fuzzy membership functions.+-- Works only on the base interval set, make sure you trust your zSlices. contZT2 :: (Enum a, Num a) => a -> a -> a -> [IT2Set a] -> T2ZSet a contZT2 minB maxB res its = case check of True -> error "Truth values must be in the range [0..1]"@@ -54,6 +72,8 @@ check = any (\x -> x > 1 || x < 0) (map lf domain) check' = any (\x -> x > 1 || x < 0) (map uf domain) +-- | Smart constructor for discrete type-2 fuzzy membership functions.+-- Works only on the base interval set, make sure you trust your zSlices. discZT2 :: [a] -> [IT2Set a] -> T2ZSet a discZT2 dom its = case check of True -> error "Truth values must be in the range [0..1]"@@ -68,12 +88,14 @@ check = any (\x -> x > 1 || x < 0) (map lf dom) check' = any (\x -> x > 1 || x < 0) (map uf dom) +-- | Unsafe constructor, only use if you trust your membership functions or domain is very large. unsafeZT2 :: [a] -> [IT2Set a] -> T2ZSet a unsafeZT2 dom its = T2ZS { zLevels = length its , zSlices = its , zdom = dom } +-- | Used in defuzzification. cylExtT2 :: T1Set Double -> Int -> T2ZSet Double cylExtT2 s z = T2ZS { zLevels = z , zSlices = map (\(l, r) -> cylExt l r) lsrs@@ -83,13 +105,19 @@ zs = zLevelAxis z lsrs = map (findCuts s) zs -t2Tri :: (Double, Double) ->- (Double, Double) ->- (Double, Double) ->- Int -> T2ZSet Double-t2Tri (a,a') (b,b') (c,c') z = T2ZS { zLevels = z- , zSlices = base : rc (z-1) stepA stepC- , zdom = dom }+-- | Constructor for triangular type-2 fuzzy set.+-- Arguements are pairs of points for defining a base Interval type-2 fuzzy set.+-- The left element of each pair is for the lower membership function,+-- The right element is for the upper membership function,+-- Order is: left corner, peak, right corner.+-- Int is number of zSlices desired, the level of discretisation.+mkT2Tri :: (Double, Double) ->+ (Double, Double) ->+ (Double, Double) ->+ Int -> T2ZSet Double+mkT2Tri (a,a') (b,b') (c,c') z = T2ZS { zLevels = z+ , zSlices = base : rc (z-1) stepA stepC+ , zdom = dom } where dom = [min a a' .. max c c'] base = unsafeMkIT2 dom (tri a b c) (tri a' b' c')
src/Huzzy/TypeTwo/ZSlices/Systems.hs view
@@ -1,4 +1,7 @@-module Huzzy.TypeTwo.ZSlices.Systems where+module Huzzy.TypeTwo.ZSlices.Systems+( FRule(..)+, Defuzzifier(..)+) where import Data.Function(on) import Data.List(sortBy, nub)@@ -10,7 +13,7 @@ import Huzzy.TypeTwo.Interval.Systems import Huzzy.TypeTwo.ZSlices.Sets -+-- | In zSlices type-2 fuzzy sets, both implicators are the same. instance FRule (T2ZSet Double) where type Antecedent (T2ZSet Double) = T1Set Double (=*>) t1 t2 = (cylExtT2 t1 (zLevels t2)) ?|| t2