Trilhas
/
Julia
Julia
/
Exercícios
/
Probabilidades problemáticas
Probabilidades problemáticas

Probabilidades problemáticas

Exercício de aprendizagem

Introdução

Rational numbers são frações com um numerador inteiro dividido por um denominador inteiro.

Por exemplo, podemos armazenar 2//3 como uma fração exata em vez do valor aproximado Float64 0.6666...

A vantagem é que (exceto no caso extremo de estouro de inteiro) um número racional permanece exato, evitando os erros de arredondamento que muitas vezes são inevitáveis com números de ponto flutuante.

Números racionais são um tipo numérico bem simples e funcionam praticamente como você espera. Como são um tipo padrão do Julia desde as primeiras versões, a maioria das funções os aceita como entrada do mesmo jeito que aceita inteiros e números de ponto flutuante.

Criando números racionais

Criar um número racional é tão simples quanto usar // entre dois inteiros.

julia> 3//4
3//4

julia> a = 3; b = 4;

julia> a//b
3//4

Os fatores comuns são removidos automaticamente, convertendo a fração para a sua "forma irredutível": os menores inteiros que representam a fração exatamente, com um denominador não negativo.

julia> 5//15
1//3

julia> 5//-15
-1//3

Aritmética com números racionais

Os arithmetic operators usuais, + - * / ^ %, funcionam com racionais, basicamente do mesmo jeito que com outros tipos numéricos.

Inteiros e outros Rationals podem ser incluídos e dão um resultado Rational. Incluir um float na expressão resulta em uma saída float, com uma consequente (possível) perda de precisão.

Se você quiser um float, basta usar a função float() para converter um número racional. É bem comum usar números racionais para preservar a precisão ao longo de um cálculo longo e depois converter para um número de ponto flutuante no final.

julia> 3//4 + 1//3  # addition
13//12

julia> 3//4 * 1//3  # multiplication
1//4

julia> 3//4 / 1//3  # division
9//4

julia> 3//4 ^ 2  # exponentiation
3//16

julia> 3//4 + 5  # rational and int => rational
23//4

julia> 3//4 + 5.3  # rational and float => float
6.05

julia> float(3//4)  # casting
0.75

Outras operações

No Julia, números racionais são apenas números. O compilador geralmente converte os tipos conforme necessário.

No entanto, cuidado: as comparações funcionam para frações com uma representação decimal finita:

julia> 3//4 == 0.75
true

julia> 3//4 < 0.74
false

Mas, fora isso, um Rational deve ser convertido para um Float para fazer comparações:

julia> 1//3 == 1/3
false

julia> float(1//3) == 1/3
true

Funções matemáticas aceitam racionais como entrada, mas podem dar um resultado de ponto flutuante:

julia> sqrt(9//16)
0.75

Instruções

Uma organização de pesquisa percebeu que alguns de seus pesquisadores júnior vêm usando métodos pouco ideais em suas análises. Um desses métodos é converter imediatamente probabilidades discretas em números de ponto flutuante (ou seja, números reais) antes de fazer mais cálculos.

Os pesquisadores sênior preferem usar números racionais nos cálculos, o que pode oferecer maior precisão, e gostariam de saber se as práticas ruins dos pesquisadores júnior afetaram os resultados dos estudos.

Foram feitos dois tipos de estudo:

  • Muitos testes foram rodados, cada um retornando uma probabilidade discreta de sucesso, e então a média dessas probabilidades foi calculada.
  • Muitos eventos independentes foram testados, e a probabilidade total de todos os eventos ocorrerem foi calculada multiplicando-os entre si.

Os pesquisadores sênior estão pedindo que você escreva funções que os ajudem a determinar se há erros de arredondamento nas análises por usar números de ponto flutuante, e pedem que você forneça um número racional preciso para o resultado, caso haja erros.

1. Dê a razão entre sucessos e tentativas

A função rationalize(successes, trials) recebe dois arrays, successes e trials. Para um índice i, successes[i] corresponde ao número de sucessos que ocorreram em trials[i] tentativas. A função retorna um array de números racionais das razões entre os sucessos e o número de tentativas, na mesma ordem dos arrays de entrada.

julia> rationalize([1, 2, 3], [4, 5, 6])
3-element Vector{Rational{Int64}}:
 1//4
 2//5
 1//2

2. Encontre as probabilidades reais associadas às razões entre sucessos e tentativas

De forma semelhante, a função probabilities(successes, trials) recebe dois arrays, successes e trials. Ela retorna um array de números de ponto flutuante das razões entre os sucessos e o número de tentativas, na mesma ordem dos arrays de entrada.

julia> probabilities([1, 2, 3], [4, 5, 6])
3-element Vector{Float64}:
 0.25
 0.4
 0.5

3. Verifique a média das probabilidades

A função checkmean(successes, trials) recebe os dois arrays, successes e trials. Ela compara a média das probabilidades reais com a média das probabilidades racionais.

  • Se as duas probabilidades forem iguais, checkmean retorna true
  • Se as duas probabilidades forem diferentes, checkmean retorna a probabilidade racional.
julia> successes, trials = [9, 4, 7, 8, 6], [22, 22, 11, 17, 12];
julia> checkmean(successes, trials)
true

julia> successes, trials = [6, 5, 9, 8, 9], [21, 19, 13, 25, 22];
julia> checkmean(successes, trials)
1873629//4754750

4. Verifique a probabilidade independente

A função checkprob(successes, trials) recebe os dois arrays, successes e trials. Ela compara a probabilidade total das probabilidades em ponto flutuante com a probabilidade total das probabilidades racionais.

  • Se as duas probabilidades forem iguais, checkprob retorna true
  • Se as duas probabilidades forem diferentes, checkprob retorna a probabilidade racional.
julia> successes, trials = [2, 9, 4, 4, 5], [15, 11, 17, 19, 15];
julia> checkprob(successes, trials)
true

julia> successes, trials = [9, 8, 5, 4, 3], [22, 14, 19, 25, 18];
julia> checkprob(sucesses, trials)
12//7315
Editar via GitHub O link abre em uma nova janela ou aba
Julia Exercism

Tudo pronto para começar Probabilidades problemáticas?

Crie sua conta no Exercism para aprender e dominar Julia com 35 conceitos128 exercícios e mentoria humana de verdade, tudo de graça.