Calcolo dell'entropia


13

Ingresso

Una matrice Mrappresentata come due linee di numeri separati da spazi. Ogni riga avrà lo stesso numero di numeri interi e ogni numero intero sarà -1 o 1. Il numero di numeri interi per riga sarà al massimo 20. MSarà quindi 2da ndove si ntrova il numero di numeri interi su ciascuna delle due righe.

Il tuo codice dovrebbe essere un programma completo. e accetta l'input su standard in o da un file (che è la tua scelta). È possibile accettare input dallo standard in, da un file o semplicemente come parametro. Tuttavia, se fai quest'ultimo, fornisci un esempio esplicito di come dovrebbe funzionare il tuo codice e ricorda che deve essere un programma completo e come Mverrà rappresentata la matrice nell'input. In altre parole, è probabile che tu debba fare un po 'di analisi.

Produzione

La Shannon entropia binaria della distribuzione M*xdove gli elementi della xsono uniformemente e indipendentemente scelti da {-1,1}. xè un nvettore di colonna tridimensionale.

L'entropia di una distribuzione di probabilità discreta è

- sum p_i log_2(p_i)

In questo caso, p_iè la probabilità del ith unico possibile M*x.

Esempio e suggerimenti utili

Come esempio pratico, lasciare che la matrice Msia

-1 1
-1 -1

Ora guarda tutti i 2^2diversi vettori possibili x. Per ognuno calcoliamo M*xe mettiamo tutti i risultati in un array (un array a 4 elementi di vettori a 2 componenti). Sebbene per ciascuno dei 4 vettori la probabilità che si verifichi 1/2^2 = 1/4, siamo interessati solo al numero di volte in cui si verifica ciascun vettore risultante univocoM*x , e quindi riassumiamo le singole probabilità delle configurazioni che portano agli stessi vettori unici. In altre parole, i possibili M*xvettori unici descrivono i risultati della distribuzione che stiamo studiando e dobbiamo determinare la probabilità di ciascuno di questi risultati (che, per costruzione, sarà sempre un numero intero multiplo di 1/2^2, o 1/2^nin generale) per calcolare l'entropia.

Nel ncaso generale , a seconda Mdei possibili risultati di M*xpuò variare da "tutti diversi" (in questo caso abbiamo nvalori di iin p_i, e ognuno p_iè uguale a 1/2^n), a "tutti uguali" (in questo caso esiste un unico possibile risultato e p_1 = 1).

In particolare, per la 2x2matrice di Mcui sopra possiamo trovare moltiplicandola per le quattro possibili configurazioni ( [+-1; +-1]), che ogni vettore risultante è diverso. Quindi in questo caso ci sono quattro risultati, e di conseguenza p_1 = p_2 = p_3 = p_4 = 1/2^2 = 1/4. Ricordando che log_2(1/4) = -2abbiamo:

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

Quindi l'output finale per questa matrice è 2.

Casi test

Ingresso:

-1 -1 
-1 -1

Produzione:

1.5

Ingresso:

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

Produzione:

2.03063906223

Ingresso:

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

Produzione:

3

7
1. Quali sono le dimensioni di x? 2. Nell'interesse di rendere autonoma la domanda, come viene Mxdefinita l' entropia binaria di Shannon ?
Peter Taylor,

4
@ Il commento di Peter spiega esattamente i downvotes. Ho sfogliato l'articolo sull'entropia e non riesco immediatamente a scoprire cosa implementare. Dovresti specificare esattamente quale sia la formula / algoritmo per calcolare l'entropia di Shannon.
Lynn,

5
Le domande dovrebbero essere autosufficienti, comunque; è improbabile che Wikipedia diventi improvvisamente offline, ma sarebbe l'ideale non dover fare clic su un'altra pagina per essere in grado di comprendere le specifiche complete della sfida.
Maniglia della porta

2
Per impostazione predefinita, le funzioni sono una valida alternativa ai programmi. Ti è permesso di sovrascriverlo, ma renderà alcune lingue molto tristi perché ci vuole molta caldaia per accettare file o input stdin. Più in generale, sconsiglio di avere un formato di input così restrittivo in una sfida matematica. Consentire il tipo di elenco naturale della lingua renderebbe le persone più felici di partecipare.
xnor

3
@dorothy nota che non è che "log_2 (0) è 0 per comodità", ma piuttosto "lim_ {p-> 0} p * log (p) == 0". Quindi "log_2 (0)" è ancora -inf.
Andras Deak,

Risposte:


3

Mathematica, 48 68 byte

Modifica: Preprocess viene aggiunto per accettare la stringa come parametro.

Con l'aiuto di Tuplese Entropy, l'implementazione è sia concisa che leggibile.

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

dove Tuples[{-1,1},n]fornisce tutte le possibili n-tuple {-1,1}e Entropy[2,list]fornisce l'entropia delle informazioni di base-2.

Una delle cose interessanti è che Mathematica restituirà in realtà un'espressione accurata:

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

Il risultato approssimativo può essere ottenuto con un ulteriore .aggiunto ( Entropy[2., ...).


Mathematica è ridicola :) Tuttavia la tua risposta non si adatta perfettamente alle specifiche. L'input è separato dallo spazio, quindi sarà necessario un po 'di analisi. Vedi l'ultimo aggiornamento.
Dorothy,

3

Perl, 160 159 141 byte

include +1 per l' -paggiornamento da 141 byte

@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;

L'ingresso è previsto su STDIN2 righe costituite da spazio separato 1o -1.
Esegui come perl -p 140.pl < inputfile.

Non vincerà alcun premio, ma ho pensato di condividere i miei sforzi.
Ha spiegato:

    @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;

DATI

  • aggiornamento 159: salva 1 eliminando ()utilizzando **invece di <<.
  • aggiornamento 141: salva 18 usando $.e -p.

1
Grazie! Non abbiamo abbastanza risposte perl su ppcg imho
dorothy

@dorothy È perché i golfisti del codice detestano Perl, per la maggior parte.
Addison Crump

@FlagAsSpam Ma, ma .. perl è incomprensibile, succinto e borderline folle. Come potrebbe essere più adatto per il golf di codice?
Dorothy,

@dorothy ¯ \ _ (ツ) _ / ¯ Lo evitiamo come la peste. Non so perché, davvero.
Addison Crump

2

Pyth, 37 byte

K^_B1lhJrR7.z_s*LldcRlKhMrSmms*VdkJK8

Suite di test

Questo è un po 'più complicato quando devi implementare manualmente la moltiplicazione della matrice.

Spiegazione:

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.

Wow! :) Sembra molto lavoro. Ora dove sono i cjam .....?
Dorothy,

1

MATLAB, 196 194 187 184 126 154 byte

(I 28 byte extra da 126 a 154 sono dovuti all'analisi dell'input: ora il codice accetta l'input come due righe di numeri separati da spazi bianchi.)

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)))

Versione non golfata:

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

Potrei eliminare 6 byte se ans = ...fosse consentito un " " tipo di output, non ne sono mai sicuro.

Mi dispiace dire che la mia soluzione originale e sicuramente spiritosa era troppo poco rispettata rispetto alla mia attuale soluzione. Questa è anche la prima volta che sto usando accumarray. Un'applicazione con sei parametri di input deve ancora attendere, però :)

Uscite (seguenti 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

Output con il valore predefinito 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.