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)