Berechnung der Entropie

13

Eingang

Eine Matrix, Mdie als zwei durch Leerzeichen getrennte Zeilen von ganzen Zahlen dargestellt wird. Jede Zeile hat die gleiche Anzahl von Ganzzahlen, und jede Ganzzahl ist entweder -1 oder 1. Die Anzahl von Ganzzahlen pro Zeile beträgt höchstens 20. MDaher wird angegeben, 2von nwon die Anzahl der ganzen Zahlen auf jedem der beiden Linien.

Ihr Code sollte ein vollständiges Programm sein. und akzeptieren Sie die Eingabe entweder über Standard in oder aus einer Datei (das ist Ihre Wahl). Sie können Eingaben von standard in, aus einer Datei oder einfach als Parameter akzeptieren. Wenn Sie jedoch Letzteres tun, geben Sie bitte ein explizites Beispiel dafür, wie Ihr Code funktionieren soll, und denken Sie daran, dass es sich um ein vollständiges Programm handeln muss und wie die Matrix Min der Eingabe dargestellt wird. Mit anderen Worten, es ist wahrscheinlich, dass Sie eine Analyse durchführen müssen.

Ausgabe

Die binäre Shannon-Entropie der Verteilung, in der M*xdie Elemente von xgleichmäßig und unabhängig voneinander aus {-1,1} ausgewählt werden. xist ein neindimensionaler Spaltenvektor.

Die Entropie einer diskreten Wahrscheinlichkeitsverteilung ist

- sum p_i log_2(p_i)

In diesem Fall p_iist die Wahrscheinlichkeit der iEindeutig keit möglich M*x.

Beispiel und hilfreiche Tipps

Als bearbeitetes Beispiel sei die Matrix Msein

-1 1
-1 -1

Schauen Sie sich nun alle 2^2möglichen Vektoren an x. Für jedes berechnen wir M*xalle Ergebnisse und fügen sie in ein Array ein (ein 4-Element-Array von 2-Komponenten-Vektoren). Obwohl für jede der 4 Vektoren die Wahrscheinlichkeit der es auftritt , ist 1/2^2 = 1/4, sind wir nur in der Anzahl der Male interessiert jeder einzigartigen resultierenden Vektors M*xauftritt, und so bis Wir fassen die einzelnen Wahrscheinlichkeiten der Konfigurationen auf die gleichen einzigartigen Vektoren führt. Mit anderen Worten, die möglichen eindeutigen M*xVektoren beschreiben die Ergebnisse der Verteilung, die wir untersuchen, und wir müssen die Wahrscheinlichkeit jedes dieser Ergebnisse bestimmen (die konstruktionsbedingt immer ein ganzzahliges Vielfaches von 1/2^2oder sein werden1/2^n im Allgemeinen sein werden) Berechnen Sie die Entropie.

nAbhängig von Mden möglichen Ergebnissen von M*xkann der Bereich im Allgemeinen von "alle unterschiedlich" (in diesem Fall haben wir nWerte von iin p_iund jeder p_iist gleich 1/2^n) bis "alle gleich" (in diesem Fall gibt es ein einzelnes mögliches) reichen Ergebnis, und p_1 = 1).

Insbesondere können wir für die obige 2x2Matrix Mdurch Multiplizieren mit den vier möglichen Konfigurationen ( [+-1; +-1]) feststellen , dass jeder resultierende Vektor unterschiedlich ist. In diesem Fall gibt es also vier Ergebnisse und folglich p_1 = p_2 = p_3 = p_4 = 1/2^2 = 1/4. Daran erinnern, dass log_2(1/4) = -2wir haben:

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

Die endgültige Ausgabe für diese Matrix ist also 2.

Testfälle

Eingang:

-1 -1 
-1 -1

Ausgabe:

1.5

Eingang:

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

Ausgabe:

2.03063906223

Eingang:

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

Ausgabe:

3
Dorothy
quelle
7
1. Was sind die Dimensionen von x? 2. Wie wird die binäre Shannon-Entropie Mxdefiniert , um die Frage in sich geschlossen zu machen ?
Peter Taylor
4
@Peters Kommentar erklärt genau die Downvotes. Ich habe den Artikel über Entropie überflogen und kann nicht sofort herausfinden, was zu implementieren ist. Sie sollten genau angeben, mit welcher Formel / welchem ​​Algorithmus die Shannon-Entropie berechnet werden soll.
Lynn
5
Fragen sollten sowieso in sich geschlossen sein; Es ist unwahrscheinlich, dass Wikipedia plötzlich offline geschaltet wird, aber es ist ideal, wenn Sie nicht auf eine andere Seite klicken müssen, um die vollständige Beschreibung der Herausforderung zu verstehen.
Türknauf
2
Standardmäßig sind Funktionen eine gültige Alternative zu Programmen. Sie dürfen das überschreiben, aber es wird einige Sprachen sehr traurig machen, weil es viel Boilerplate braucht, um Datei- oder Stdin-Eingaben zu machen. Generell empfehle ich, bei einer mathematischen Herausforderung kein so restriktives Eingabeformat zu haben. Das Zulassen des natürlichen Listentyps der Sprache würde die Teilnahme der Menschen erleichtern.
xnor
3
@Dorothy Beachten Sie, dass es nicht so ist, dass "log_2 (0) der Einfachheit halber 0 ist", sondern "lim_ {p-> 0} p * log (p) == 0". "Log_2 (0)" ist also immer noch -inf.
Andras Deak

Antworten:

3

Mathematica, 48 68 Bytes

Bearbeiten: Vorverarbeitung wird hinzugefügt, um Zeichenfolge als Parameter zu akzeptieren.

Mit Hilfe von Tuplesund Entropyist die Implementierung übersichtlich und lesbar.

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

wo Tuples[{-1,1},n] gibt alle möglichen n-Tupeln aus {-1,1}und Entropy[2,list]gibt die Basis-2 - Informationen Entropie.

Eines der coolen Dinge ist das Mathematica tatsächlich einen genauen Ausdruck zurückgibt:

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

Das ungefähre Ergebnis kann mit einem zusätzlichen .( Entropy[2., ...) erreicht werden.

njpipeorgan
quelle
Mathematica ist lächerlich :) Ihre Antwort entspricht jedoch nicht ganz der Spezifikation. Die Eingabe ist durch Leerzeichen getrennt, sodass eine Analyse erforderlich ist. Sehen Sie sich das neueste Update an.
Dorothy
3

Perl, 160, 159 141 Bytes

Enthält +1 für das -p141-Byte-Update

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

Die Eingabe wird auf STDIN2 Zeilen bestehend aus Leerzeichen 1oder erwartet -1.
Führen Sie so perl -p 140.pl < inputfile.

Es wird keine Preise gewinnen, aber ich dachte, ich würde meine Bemühungen teilen.
Erklärt:

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

DATEN

  • update 159: speichere 1 durch entfernen ()mit **anstatt <<.
  • update 141: speichere 18 mit $.und -p.
Kenney
quelle
1
Vielen Dank! Wir haben nicht genug Perl-Antworten auf ppcg imho
dorothy
@dorothy Das liegt daran, dass Code-Golfer Perl größtenteils verabscheuen .
Addison Crump
@FlagAsSpam Aber, aber ... Perl ist unverständlich, prägnant und grenzwertig verrückt. Wie könnte es besser für Code-Golf geeignet sein?
Dorothy
@dorothy ¯ \ _ (ツ) _ / ¯ Wir meiden es wie die Pest. Keine Ahnung warum.
Addison Crump
2

Pyth, 37 Bytes

K^_B1lhJrR7.z_s*LldcRlKhMrSmms*VdkJK8

Testsuite

Dies ist etwas schwieriger, wenn Sie die Matrixmultiplikation manuell implementieren müssen.

Erläuterung:

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.
isaacg
quelle
Beeindruckend! :) Das sieht nach viel Arbeit aus. Wo sind nun die CJAM-Leute?
Dorothy
1

MATLAB, 196 194 187 184 126 154 Bytes

(Die zusätzlichen 28 Bytes von 126 bis 154 sind auf die Syntaxanalyse der Eingaben zurückzuführen. Der Code akzeptiert die Eingabe nun als zwei Zeilen mit durch Leerzeichen getrennten Zahlen.)

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

Ungolfed-Version:

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

Ich könnte mit 6 Bytes aufhören, wenn ein "ans = ... " Art von Ausgabe erlaubt wäre, da bin ich mir nie sicher.

Es tut mir leid zu sagen, dass meine originelle und sicherlich witzige Lösung im Vergleich zu meiner aktuellen Lösung viel zu ungolfed war. Dies ist auch das erste Mal, dass ich verwende accumarray. Eine Anwendung mit sechs Eingabeparametern muss allerdings noch warten :)

Ausgänge (folgend 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

Ausgaben mit der Standardeinstellung 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
Andras Deak
quelle