packages feed

Probnet-0.1.0.2: Probnet.hs

-- | Probnet 0.1.0.0
-- | Usage : probnet 1 [1,2,3,5,8,13]
-- | Result : [1,2,3,5,8,13,21]

module Probnet (
   percents,
   predict1, 
   predict, 
   probnet, 
) where

import Data.List
import Data.Ratio -- for the case of inputs with Ratio or Rational list elements

-- | Element value of 'list' nearest to 'n'
nearnum :: RealFrac a => a -> [a] -> a
nearnum n = minimumBy nearer
   where
   nearer x y = compare (abs (x - n)) (abs (y - n))

-- | Ratios between consecutive elements (logarithmic differences). 
percents :: RealFrac a => [a] -> [a]
percents dat = zipWith quotient dat (tail dat)
   
   where 
   quotient y = (/ y)

-- | Get ratio element
ratio1 d f = percents d !! f

-- | This is to assume that the next ratio is close to that of the element 
-- with the closest value to the last element; in case of monotonic data 
-- (always increasing or always decreasing) it is the last ratio. 


predict1 :: RealFrac a => [a] -> a
predict1 dat  
   | l > lastper = (ratio1 (dat) (eleml+1)) * last dat 
   | otherwise = (ratio1 dat eleml) * last dat
   where
   Just eleml = elemIndex ned dat
   ned = nearnum (last dat) (init dat)
   l = last $ init dat
   lastper = last dat 


-- | Generates new prediction
predict :: (Integral b, RealFrac a) => Int -> [a] -> [b]
predict layers dat 
   | layers > 1   = predict (layers - 1) out -- execute next in the serie
   | otherwise    = fmap round out
   where
   out = [predict1 dat] 

-- | Generate new prediction with error prediction 
probnet :: (Integral b, RealFrac a) => Int -> [a] -> [b]
probnet layers dat
   | layers > 1   = probnet (layers - 1) $ map (\x-> fromIntegral (round x)) out 
   | otherwise    = fmap round out
   where
   out = dat ++ [(predict1 dat + prerr dat)]

-- | This is the next prediction for the difference between each 
-- original element and its prediction based on previous elements
prerr :: RealFrac a => [a] -> a
prerr dat 
   | last err == 0   = 0 
   | otherwise       = predict1 $ drop 2 err
   where  
   err   = zipWith subtract pred dat -- differences between elements and its predictions
   pred  = fmap predict1 $ inits dat -- 2 first inits have 0 and 1 elements, will be dropped



-- | Encode data sequence
-- convert data sequence to f = (index,frac1,frac2,frac3,longitude)
-- TODO convert data secuence to a function / symbol dictionary and replace sequence patterns for the symbol
-- example parse 1,2,3,4,5,8,16.... / output -> (.,30,1,1,1),(,,10,2,4,8) .....,,
-- the idea is convert different values in the same symbol, in decode moment replace the function symbol by the element in the index of the data sequence.
--
encode dat = (l,f2-f1,f3-f2,f4-f3)
   where
   l = length dat
   f1 = dat !! 0
   f2 = dat !! 1
   f3 = dat !! 2
   f4 = dat !! 3
   -- add split patterns function to the dictionary
   -- rewrite sequence to new function symbols
   -- rewrite base for encoding
   -- output dictionary + rewrited symbols sequence
   -- return imposible to encode if no improve in the encodening comparing bit size are detected


-- | Encode function for files + lzma
--



-- | Decode data sequence
-- convert encoded probnet function parameters to data sequence
-- TODO convert encoded data sequence to real data converting each symbol by his element in the function data secuence in the dictionary.
decode encoded = probnet (i-(length encoded-1)) [fromIntegral f1,fromIntegral f2,fromIntegral f3,fromIntegral f4]
	where
	i = encoded!!0
	f1 = encoded!!1
	f2 = encoded!!2
	f3 = encoded!!3
	f4 = encoded!!4
	-- get dictionary function
	-- replace funcion data secuence by function elements to generate the real data sequence
	-- output results
	-- return no function dictionary was found , or no functionon decoding for this sequence




-- | Decode file to a file
-- 


-- | Property of Cobalt Technologies Panamá
-- | Authors : Vicent Nos Ripolles (Main Author)
-- | Enrique Santos (Refactor Code)