Dr.Godfried-Willem RAES
Kursus Experimentele Muziek: Boekdeel 1: Algoritmische Kompositie
Hogeschool Gent
Departement Muziek en Drama
<Vorig hoofdstuk> (Beta funktie)
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
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