-
Notifications
You must be signed in to change notification settings - Fork 0
/
Utils.hs
70 lines (58 loc) · 3.28 KB
/
Utils.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
module Utils (le_num, media, desvio_padrao, soma_listas, subtrai_listas, divide_listas, distancia_euclidiana, matriz_to_string, qsort, ponto_medio_lista, desvio_padrao_listas) where
import Text.Printf
{-
Modulo do primeiro trabalho computacional de Programação Funcional em Haskell responsável pelo tratamento de
entradas e escrita dos arquivos de saída e outras funções utilitárias.
-}
-- Lê um inteiro da entrada padrão
le_num :: IO Int
le_num = do num <- getLine
return (read num :: Int)
-- Soma duas listas indice por indice
soma_listas :: Num a => [a] -> [a] -> [a]
soma_listas lst1 lst2 = [ lst1!!i + lst2!!i | i <- [0.. length lst1 - 1] ]
-- Diminui duas listas indice por indice
subtrai_listas :: Num a => [a] -> [a] -> [a]
subtrai_listas lst1 lst2 = [ lst1!!i - lst2!!i | i <- [0.. length lst1 - 1] ]
-- Divide duas listas indice por indice
divide_listas :: (Fractional a) => [a] -> [a] -> [a]
divide_listas lst1 lst2 = [ lst1!!i / (lst2!!i) | i <- [0.. length lst1 - 1] ]
-- Calcula distancia euclidiana entre dois pontos de n dimensões R
distancia_euclidiana:: [Double] -> [Double] -> Double
distancia_euclidiana lst1 lst2 = sqrt $ foldr (+) 0 [ (lst1!!i - lst2!!i)**2 | i <- [0.. length lst1 - 1] ]
-- Dá uma matriz em forma de string
matriz_to_string :: [[Int]] -> [Char]
matriz_to_string matriz = foldr1 (++) linhas_matriz
where
linhas_matriz = [ linha_matriz x | x <- matriz ]
linha_matriz [x] = printf "%3d\n" x
linha_matriz (x:xs) = printf "%3d, " x ++ linha_matriz xs
-- Ordena através do método quick sort
qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (x:xs) = qsort [ a | a <- xs, a <= x ] ++ [x] ++ qsort [ a | a <- xs, a > x]
-- Calcula o ponto médio de uma lista de pontos no Rn
ponto_medio_lista :: [[Double]] -> [Double]
ponto_medio_lista lista = map (/tamanho) somatoria
where
tamanho = fromIntegral $ length lista
somatoria = foldr1 soma_listas lista
-- Calcula o desvio padrão de uma lista de pontos no Rn (é preciso fornecer a média como entrada para uso em padronização)
desvio_padrao_listas :: [Double] -> [[Double]] -> [Double]
desvio_padrao_listas media pontos = map sqrt $ map (/ tamanho) (foldr1 soma_listas quadrado_dist_media_pontos)
where
quadrado_dist_media_pontos = (map (\y -> map (**2) (subtrai_listas y media)) pontos)
tamanho = fromIntegral $ length pontos
-- Calcula a média de uma lista de números
media :: (Fractional a) => [a] -> a
media lista = somatoria/tamanho
where
tamanho = fromIntegral $ length lista
somatoria = foldr1 (+) lista
-- Calcula o desvio padrão de uma lista de números
desvio_padrao :: [Double] -> Double
desvio_padrao lista = sqrt $ (foldr1 (+) quadrado_dist_media_pontos)/tamanho
where
quadrado_dist_media_pontos = map (**2) $ map (\x -> x-media) lista
media = (foldr1 (+) lista)/tamanho
tamanho = fromIntegral $ length lista