-- |
-- Module : Phonetic.Languages.Filters
-- Copyright : (c) OleksandrZhabenko 2020
-- License : MIT
-- Stability : Experimental
-- Maintainer : olexandr543@yahoo.com
--
-- A module allows to change the structure of the function output for the functions of
-- elements from 'RealFrac' class. At the moment only the equal intervals are supported.
-- Uses less dependencies than its former analogue package @uniqueness-periods-vector-filters@.
-- Reimports the functions from the @filters-basic@ module except the auxiliary zero2One,
-- so if you intend to use the functionality of both of them, use just this one.
module Phonetic.Languages.Filters (
-- * One interval used
intervalNRealFrac
, unsafeTransfer1I5
, transfer1IEq3
-- * Several intervals
, unsafeRearrangeIG
, unsafeRearrangeIGV
-- * Some basic usage examples
, unsafeSwapIWithMaxI
, unsafeSwapVecIWithMaxI
) where
import Data.Filters.Basic
import GHC.Arr
import Case.Hashable.Cuckoo
import Data.Hashable (Hashable(..))
-- | Makes a complex interval-based transformation moving the value from its own interval to the corresponding by the list of tuples second element of the
-- respective pair with the first element being the starting number of the interval (numeration of them begins at 1). The list argument must be sorted
-- by the first argument in the ascending order. Usually, its first elements in the tuples are from the range @[1..n]@. Number of the intervals are given as
-- the third argument and for many cases should not be greater than 10. There do exist several semantical constraints for the possible accurate arguments,
-- but they are not checked. For example, the first argument must be less than the second one; the fifth argument must be located between the first two ones;
-- the third argument must be greater than zero.
unsafeRearrangeIG
:: (RealFrac b, Integral c, Hashable c) => b
-> b
-> c
-> [(c,c)]
-> b
-> b
unsafeRearrangeIG minE maxE n xs x
| minE == maxE = x
| otherwise = x + fromIntegral (getBFstL' n0 xs n0 - n0) * (maxE - minE) / fromIntegral n
where n0 = intervalNRealFrac minE maxE n x
-- | An unzipped variant of the 'unsafeRearrangeIG' function where the list argument is internally 'zip'ped as the second argument with the @[1..n]@.
-- This allows to shorten the time of the arguments writing.
unsafeRearrangeIGV
:: (RealFrac b, Integral c, Hashable c) => b
-> b
-> c
-> [c]
-> b
-> b
unsafeRearrangeIGV minE maxE n xs = unsafeRearrangeIG minE maxE n . zip [1..n] $ xs
{-# INLINE unsafeRearrangeIGV #-}
-- | Swaps the k-th inner interval values with the maximum one's (that is the n-th one) values.
unsafeSwapIWithMaxI
:: (RealFrac b, Integral c, Hashable c) => b
-> b
-> c -- ^ It is expected to be greater than 0, though this is not checked.
-> c -- ^ It is expected to be less than the previous argument, but greater than 0, though this is not checked.
-> b -- ^ It is expected to lie between the first two arguments, though this is not checked.
-> b
unsafeSwapIWithMaxI minE maxE n k = unsafeRearrangeIGV minE maxE n . map (f k n) $ [0..n - 1]
where f k n x
| x == k - 1 = n - 1
| x == n - 1 = k - 1
| otherwise = x
{-# INLINE f #-}
{-# INLINE unsafeSwapIWithMaxI #-}
-- | Swaps the inner intervals values (given by the list of elements of the data type that has an instance of the
-- 'Integral' class that represent numbers-indices starting from 1 to n) with the maximum one's
-- (that is the n-th one) values. The list must be not empty and sorted in the ascending order, though it is not checked. Be aware that this can
-- significantly change the density of the values and break some other properties for distributions.
unsafeSwapVecIWithMaxI
:: (RealFrac b, Integral c, Hashable c) => b
-> b
-> c -- ^ It is expected to be greater than 0, though this is not checked.
-> [c] -- ^ It is expected the list to be sorted in the ascending order (indices are counted in it starting with 1 opposed to the usual behaviour for lists and are the numbers of the intervals in the range from 1 to n), and besides all the elements to be less than the previous argument, greater than 0 and to be not pairwise equal, though it is not checked.
-> b -- ^ It is expected to lie between the first two arguments, though this is not checked.
-> b
unsafeSwapVecIWithMaxI minE maxE n xs = unsafeRearrangeIGV minE maxE n (map h [0..n - 1])
where h i
| getBFstL' False (zip (map (+ (-1)) xs) . replicate (fromIntegral n) $ True) i = n - 1
| i == n - 1 = head xs
| otherwise = i
{-# INLINE unsafeSwapVecIWithMaxI #-}