Computando a entropia


13

Entrada

Uma matriz Mrepresentada como duas linhas de números inteiros separados por espaço. Cada linha terá o mesmo número de números inteiros e cada número inteiro será -1 ou 1. O número de números inteiros por linha será no máximo 20. Mserá, portanto 2, nonde né o número de números inteiros em cada uma das duas linhas.

Seu código deve ser um programa completo. e aceite a entrada no padrão em ou a partir de um arquivo (que é sua escolha). Você pode aceitar entrada de entrada padrão, de um arquivo ou simplesmente como um parâmetro. No entanto, se você fizer o último, dê um exemplo explícito de como seu código deve funcionar e lembre-se de que ele deve ser um programa completo e como a matriz Mserá representada na entrada. Em outras palavras, é provável que você precise fazer uma análise.

Resultado

A entropia binária de Shannon da distribuição de M*xonde os elementos de xsão escolhidos de maneira uniforme e independente de {-1,1}. xé um nvetor de coluna tridimensional.

A entropia de uma distribuição de probabilidade discreta é

- sum p_i log_2(p_i)

Nesse caso, p_ié a probabilidade do ith único possível M*x.

Exemplo e dicas úteis

Como exemplo trabalhado, deixe a matriz Mser

-1 1
-1 -1

Agora observe todos os 2^2diferentes vetores possíveis x. Para cada um, calculamos M*xe colocamos todos os resultados em uma matriz (uma matriz de 4 elementos de vetores de 2 componentes). Embora para cada um dos quatro vetores a probabilidade de ocorrência seja 1/2^2 = 1/4, estamos interessados ​​apenas no número de vezes que cada vetor resultante exclusivoM*x ocorre e, portanto, resumimos as probabilidades individuais das configurações que levam aos mesmos vetores únicos. Em outras palavras, os possíveis M*xvetores exclusivos descrevem os resultados da distribuição que estamos investigando e precisamos determinar a probabilidade de cada um desses resultados (que, por construção, sempre será um múltiplo inteiro de 1/2^2, ou 1/2^nem geral) para calcular a entropia.

No ncaso geral , dependendo Mdos possíveis resultados de M*xpode variar de "todos diferentes" (neste caso, temos nvalores de iin p_ie cada um p_ié igual a 1/2^n) a "todos iguais" (neste caso, existe uma única possibilidade resultado e p_1 = 1).

Especificamente, para a 2x2matriz acima M, podemos descobrir, multiplicando-a pelas quatro configurações possíveis ( [+-1; +-1]), que cada vetor resultante é diferente. Portanto, neste caso, existem quatro resultados e, consequentemente p_1 = p_2 = p_3 = p_4 = 1/2^2 = 1/4. Lembrando que log_2(1/4) = -2temos:

- sum p_i log_2(p_i) = -(4*(-2)/4) = 2

Portanto, a saída final para esta matriz é 2.

Casos de teste

Entrada:

-1 -1 
-1 -1

Resultado:

1.5

Entrada:

-1 -1 -1 -1
-1 -1 -1 -1

Resultado:

2.03063906223

Entrada:

-1  -1  -1  1
1  -1  -1  -1

Resultado:

3

7
1. Quais são as dimensões de x? 2. No interesse de tornar a questão independente, como é Mxdefinida a entropia binária de Shannon ?
Peter Taylor

4
O comentário de @ Peter explica exatamente os votos negativos. Examinei o artigo sobre entropia e não consigo descobrir imediatamente o que implementar. Você deve especificar exatamente qual é a fórmula / algoritmo para calcular a entropia de Shannon.
30515 Lynn

5
As perguntas devem ser independentes, de qualquer maneira; é improvável que a Wikipedia fique repentinamente offline, mas seria ideal não precisar clicar em outra página para entender a especificação completa do desafio.
Maçaneta

2
Por padrão, funções são alternativas válidas para programas. Você tem permissão para anular isso, mas isso deixará alguns idiomas muito tristes, pois são necessários muitos clichês para receber arquivos ou entradas stdin. Em termos mais gerais, recomendo não ter um formato de entrada tão restritivo em um desafio matemático. Permitir o tipo de lista natural do idioma tornaria as pessoas mais felizes em participar.
Xnor

3
@dorothy note que não é que "log_2 (0) seja 0 por conveniência", mas sim "lim_ {p-> 0} p * log (p) == 0". Portanto, "log_2 (0)" ainda está -inf.
Andras Deak

Respostas:


3

Mathematica, 48 68 bytes

Editar: o pré-processo é adicionado para aceitar a string como parâmetro.

Com a ajuda de Tuplese Entropy, a implementação é concisa e legível.

Entropy[2,{-1,1}~Tuples~Length@#.#]&@Thread@ImportString[#,"Table"]&

onde Tuples[{-1,1},n]fornece todos os possíveis n-tuplos de {-1,1}e Entropy[2,list]fornece a entropia de informações da base 2.

Uma das coisas legais é que o Mathematica realmente retornará uma expressão precisa:

%["-1 -1 \n -1 -1"]
(* 3/2 *)

O resultado aproximado pode ser alcançado com um acréscimo .adicional ( Entropy[2., ...).


O Mathematica é ridículo :) No entanto, sua resposta não se encaixa bem nas especificações. A entrada é separada por espaço, pelo que serão necessárias algumas análises. Veja a atualização mais recente.
precisa saber é

3

Perl, 160 159 141 bytes

inclui +1 para -puma atualização desde 141 bytes

@y=(@z=/\S+/g)x 2**@z;@{$.}=map{evals/.1/"+".$&*pop@y/egr}glob"{-1,+1}"x@z}{$H{$_.$2[$i++]}++for@1;$\-=$_*log($_/=1<<@z)/log 2 for values%H;

A entrada é esperada em STDIN2 linhas, consistindo em 1ou separado por espaço -1.
Executar como perl -p 140.pl < inputfile.

Não ganhará nenhum prêmio, mas pensei em compartilhar meu esforço.
Explicado:

    @y=                             # @y is (@z) x (1<<$n)
       (@z = /\S+/g)                # construct a matrix row from non-WS
       x 2**@z;                     # repeat @z 2^$n times
    @{$.} = map {                   # $.=$INPUT_LINE_NUMBER: set @1 or @2
      eval s/.1/"+".$&*pop@y/egr    # multiply matrix row with vector
    } glob "{-1,+1}" x @z           # produce all possible vectors

}{                                  # `-p` trick: end `while(<>)`, reset `$_`

$H{ $_ . $2[$i++] }++               # count unique M*x columns
    for @1;

$\ -= $_ * log($_/=1<<@z) / log 2   # sum entropy distribution
        for values %H;

DADOS

  • atualização 159: salve 1 eliminando ()usando em **vez de <<.
  • atualização 141: salve 18 usando $.e -p.

1
Obrigado! Não temos respostas perl suficientes sobre PPCG imho
dorothy

@dorothy É porque os jogadores de código detestam Perl, na maior parte.
precisa saber é o seguinte

@FlagAsSpam Mas, mas .. perl é incompreensível, sucinto e insano. Como poderia ser mais adequado para o código-golfe?
dorothy

@dorothy ¯ \ _ (ツ) _ / ¯ Evitamos isso como uma praga. Não sei por que, realmente.
precisa saber é o seguinte

2

Pitão, 37 bytes

K^_B1lhJrR7.z_s*LldcRlKhMrSmms*VdkJK8

Suíte de teste

Isso é um pouco mais complicado quando você precisa implementar manualmente a multiplicação de matrizes.

Explicação:

K^_B1lhJrR7.z_s*LldcRlKhMrSmms*VdkJK8
       JrR7.z                            Parse input into matrix, assign to J.
  _B1                                    [1, -1]
K^   lhJ                                 All +-1 vectors of length n, assign to K.
                           m       K     Map over K
                            m     J      Map over the rows of J
                             s*Vdk       Sum of vector product of vector and row.
                          S              Sort
                         r          8    Run length encode.
                       hM                Take just occurrence counts.
                   cRlK                  Divide by len(K) to get probabilities.
               *Lld                      Multiply each probabiliity by its log.
              s                          Sum.
             _                           Negate. Print implicitly.

Uau! :) Parece muito trabalho. Agora, onde estão as pessoas cjam .....?
dorothy

1

MATLAB, 196 194 187 184 126 154 bytes

(Os 28 bytes extras de 126 a 154 são devidos à análise de entrada: agora o código aceita a entrada como duas linhas de números separados por espaço em branco.)

f=@()str2num(input('','s'));M=[f();f()];n=size(M,2);x=(dec2bin(0:n^2-1,n)-48.5)*2*M';[~,~,c]=unique(x,'rows');p=accumarray(c,1)/2^n;disp(-sum(p.*log2(p)))

Versão não destruída:

f=@()str2num(input('','s'));        % shorthand for "read a line as vector"
M=[f();f()];                        % read matrix
n=size(M,2);                        % get lenght of vectors

x=(dec2bin(0:n^2-1,n)-48.5)*2*M';   % generate every configuration
                                    %    using binary encoding
[~,~,c]=unique(x,'rows');           % get unique rows of (Mx)^T
p=accumarray(c,1)/2^n;              % count multiplicities and normalize
disp(-sum(p.*log2(p)))              % use definition of entropy

Eu poderia eliminar 6 bytes se um " ans = ..." tipo de saída fosse permitido, nunca tenho certeza disso.

Lamento dizer que minha solução original e certamente espirituosa era muito pouco usada em comparação com a minha solução atual. Esta é também a primeira vez que estou usando accumarray. Um aplicativo de seis parâmetros de entrada ainda precisa esperar :)

Saídas (a seguir format long):

[-1 1
-1 -1]
     2

[-1 -1
-1 -1]
   1.500000000000000

[-1 -1 -1 -1
-1 -1 -1 -1]
   2.030639062229566

[-1  -1  -1  1
1  -1  -1  -1]
     3

Saídas com o padrão format short g:

[-1 1
-1 -1]
     2

[-1 -1
-1 -1]
          1.5

[-1 -1 -1 -1
-1 -1 -1 -1]
       2.0306

[-1  -1  -1  1
1  -1  -1  -1]
     3
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.