Dr.Godfried-Willem RAES

Kursus Experimentele Muziek: Boekdeel 1: Algoritmische Kompositie

Hogeschool Gent

Departement Muziek en Drama


<Index kursus>

<Vorig hoofdstuk> (Beta funktie)

 

1113: De Gauss-kurve uit de statistiek

De iedereen welbekende klok-kurve uit de statistiek wordt in de literatuur steeds aangeduid hetzij met de naam van haar 'uitvinder', de wiskundige Gauss, hetzij door de verwijzing naar haar toepassing in de statistiek: de normaal-verdeling uit de kansberekening.

De berekening van de kurve verloopt -in programmataal- alsvolgt:

PRINT "Normaal-verdeling:"

Pi! = 4 * ATN(1) ' konstante

e! = EXP(1) ' konstante

sigma# = 1 ' parameter voor de breedte van de klokkurve (de mate waarin de kurve afwijkt van haar topwaarde)

mu% = 0 ' parameter voor de plaats op de x-as waar de topwaarde kan worden weergevonden.

Bijvoorbeeld:

'sigma# = 1: mu% = 0: ' levert een brede klokkurve op

'sigma# = .5: 'mu% = 0:' geeft een spitse klok (hoe kleiner sigma , hoe spitser)

' mu verplaatst het centrum van de klok over de x as, waarbij mu=0 symmetisch is met maximum voor x=0 en bij positieve mu, de kurve naar rechts schuift. mu is de topwaarde voor y wanneer x=mu.

 

FOR x! = -16 TO +16

eexp# = ((x! - mu%) ^ 2#) / (2# * (sigma# ^ 2#))

ef# = e! ^ eexp#

subroot# = 2# * Pi! * ef#

root# = SQR(subroot#)

y! = 1! / (sigma# * root#)

PRINT USING "##.###"; y!; : PRINT " ";

NEXT x!

 

De waarde van y! is steeds positief en beweegt zich tussen 0 en 1, wat daarom genormaliseerd wordt genoemd, want onafhankelijk van schaalfaktoren.

De bijzondere eigenschap van deze funktie is dat de oppervlakte van het gedeelte dat onder de klok ligt, voor eender welke kombinatie van parameters, steeds 1 is.

Een belangrijk gevolg van deze eigenschap is dat de kurve symmetrisch is en dat derhalve de eerste helft van de kurve een oppervlakte heeft die precies de helft is van de tweede helft. Ook bij assymetrische normaalverdelingen blijft deze eigenschap behouden. De funktie heeft dan wel nood aan twee sigma-parameters: een stijgende en een dalende. Merk op dat we in de algoritmische berekeningswijze de formule in een aantal stapjes berekenen. Dit is niet zomaar terwille van de leesbaarheid of de beperking van de rekentechnische komplexiteit, maar vooral omdat er anders problemen zouden kunnen ontstaan bij het trekken van wortels uit negatieve getallen! Basic (itt Fortran) beschikt immers niet standaard over komplexe getallen, die we hier anders zouden kunnen gebruiken.

 Deze funktie komt vooral daar in aanmerking wanneer we de komputer getallen willen laten voortbrengen die rond een welbepaalde centrale waarde schommelen: m.a.w. een verameling getallen met een nauwkeurig vastgelegde distributie rond een door de mu-faktor bepaalde mediaan.

Door de mu-parameter te veranderen, kan een getallenbron worden gemaakt die op probabilistische wijze evolueert. Door de sigma parameter te vergroten, kan de spreiding van de getallen alsmaar kleiner worden gemaakt, tot, bvb. slechts een enkele waarde nog overblijft, met name y=mu.

De funktie kan uiteraard bij uitstek worden gebruikt voor statistische data-acquisitie. Daar dus, waar we over een reeks gegevens in numerieke vorm (een array of een real-time bron) beschikken die behept zijn met ruis (onzekerheid). Zij kan ons helpen om in de stroom gegevens een centrale waarde terug te vinden. De output van de funktie is dan een array met de telling van de frekwentie van voorkomen van waarden in de input evenals een resultaat met betrekking tot de mu-parameter en de sigma waarde. De sigma waarde vormt dan een maat voor de betrouwbaarheid (signifikantie) van de afgeleide mu-waarde.

We geven hier een voorbeeld van een dergelijke funktie:

DECLARE FUNCTION ADStat% (Kanaal%, MaxValOut%, FrameSize%)

' experimenteerkode:

Bufsize% = 256 ' aantal inputsamples (words)

resin% = 12 ' bitresolutie van de input

resout% = 4: ' bitresolutie voor de output

MaxValin% = 2 ^ resin% ' bereik van de input

MaxValOut% = 2 ^ resout% ' gewenst outputbereik

Stp% = MaxValin% / MaxValOut%: ' verhouding tussen beide (< 1)

DIM Stat%(0 TO (2 ^ resout%)) ' telling van de frekwenties

DIM Buf%(0 TO Bufsize%) ' input gegevens

DIM StNorm!(0 TO MaxValOut%) ' genormaliseerde telling

 

' dummy test: = fill buffer with dummy data:

FOR i% = 0 TO Bufsize%:

centroid! = .7: ' 0 -> 1

sig! = 1.4

teken% = SGN(RND(1) - .5): ' -1,0,+1

a! = teken% * (RND(1) ^ sig!): ' -1 -> +1

a! = (a! / 2!) + centroid!

PRINT a!;

Buf%(i%) = a! * 4096

IF Buf%(i%) < 0 THEN Buf%(i%) = 0

IF Buf%(i%) > 4095 THEN Buf%(i%) = 4095

'Buf%(i%) = 2048

NEXT i%

' experimenteer funktie:

REDIM Stat%(0 TO MaxValOut%)

FOR i% = 0 TO Bufsize% - 1

FOR j% = 0 TO MaxValOut% - 1

IF Buf%(i%) <= Stp% * j% THEN Stat%(j%) = Stat%(j%) + 1: EXIT FOR

NEXT j%

NEXT i%

 

' normalisatie naar 0-1 bereik en opzoeken van de mu-waarde

REDIM StNorm!(0 TO MaxValOut%)

Maxval! = 0: mu% = 0

FOR i% = 0 TO MaxValOut% - I

StNorm!(i%) = Stat%(i%) / Bufsize%

: ' Fn waarden uit statistiek

IF StNorm!(i%) > Maxval! THEN Maxval! = StNorm!(i%): mu% = i%

NEXT i%

' berekening van de mediaan:

i% = 0: md! = 0

DO

md! = md! + StNorm!(i%)

i% = i% + 1

LOOP UNTIL md! >= .5

mediaan% = i% - 1

Wanneer een meetwaarde de hele meting gelijk blijft is mediaan%= mu% en is het rezultaat 100% zeker. (Maxval! is dan steeds =1). Maxval! moet groter zijn dan 1/MaxValOut% zoniet is het rezultaat zonder betekenis en bevatten de gegevens slechts ruis.

' Signifikantie:

sig! = (Maxval! - (1 / MaxValOut%)) / (1 - (1 / MaxValOut%))

 

' test:

CLS

PRINT "Telling:"

FOR i% = 0 TO MaxValOut% - 1: PRINT Stat%(i%); : NEXT i%: PRINT

PRINT "Normalisatie:"

FOR i% = 0 TO MaxValOut% - 1: PRINT USING "#.##"; StNorm!(i%); : PRINT " "; : NEXT i%: PRINT

PRINT "Maxval!="; Maxval!, "mu="; mu%

PRINT "Mediaan="; mediaan%

PRINT "Signifikantie="; sig!

PRINT "ADStat-funktie="; ADStat%(0, 16, Bufsize%)

' gebruik de samenvattende funktie waarvan de kode hierna volgt

PRINT

END

 

FUNCTION ADStat% (ch%, mv%, fs%)

SHARED Buf%(), Bufsize%

' input parameters: Kanaal%, MaxValOut%, FrameSize%

' Framesize% <= Bufsize%

' MaxValout% = 2^resout%

' Buf%() must be shared!

 

IF fs% > Bufsize% THEN fs% = Bufsize%

Stp% = 4096 / mv%: ' stepsize for discrimination

' bereken de statistische verdeling voor de gevraagde waarden:

DIM Stat%(0 TO mv%)

FOR i% = Bufsize% - 1 TO Bufsize% - fs% STEP -1

FOR j% = 0 TO mv% - 1

IF Buf%(i%) <= Stp% * j% THEN Stat%(j%) = Stat%(j%) + 1: EXIT FOR

NEXT j%

NEXT i%

' opzoeken van de mu-waarde

mu% = 0

Max% = 0

FOR i% = 0 TO mv% - 1

IF Stat%(i%) > Max% THEN Max% = Stat%(i%): mu% = i%

NEXT i%

'normalisatie:

Maxval! = Max% / fs%

sig! = (Maxval! - (1! / mv%)) / (1! - (1! / mv%))

' de funktie retourneert alleen een waarde wanneer deze ook signifikant is:

IF sig! > .05 THEN ADStat% = mu% ELSE ADStat% = 0

END FUNCTION

 

Op grond van de resultaten van deze funktie uitgevoerd op de gegevens in Buf%() kunnen we nu deze gegevens vervangen door de Gauss-kurve gebruik makend van de gevonden parameters. Dit laat ons toe op zinnige wijze gegevens te extrapoleren en toe te voegen zonder de distributie van de oorspronkelijke gegevens wezenlijk te wijzigen. Uiteraard gaat dit slechts dan wanneer de gegevens zich lenen voor een aanpak via de normaaldistributie. (wanneer de spreiding van onze inputgegevens bvb. twee bulten vertoont, dan gaat dit alvast niet meer op!).

 


Filedatum: 931101 - last update: 2009-01-28

Naar inhoudstafel kursus: <Index-Kursus>

Naar Homepage dr.Godfried-Willem RAES