# Lisapluginate loomine

&kst; pakub lihtsat ja standardset liidest, mis hõlbustab lisapluginate loomist. Järgnevalt kirjeldame nii pluginatele esitatavaid põhinõudeid kui ka selgitame, kuidas kasutada juba olemasolevaid päisefaile teatud laadi pluginate loomiseks.

## Plugina loomise põhitõed

&kst; plugin koosneb kahest failist — XML-fail ja ühisobjektifail.

### XML-fail

XML-fail annab plugina kohta infot ja kirjeldab selle sisendeid ning väljundeid. Allpool on &kst; plugina XML-faili näidis:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE Module SYSTEM "file:/Repository/Level2/Soft/ProC/moduledef.dtd">

    <module>

    <intro>
    <modulename name="testplugin"/>    <!-- The name of the module -->
    <author name="Rick Chern"/> <!-- The name of the author -->
    <description text="A test plugin for me"/> <!-- A description of the module -->
    <version minor="1" major="0"/>  <!-- The version number of the module -->
    <state devstate="release"/>     <!-- The development state of the module (optional)-->
    </intro>

    <interface>

    <!--inputs here-->
    <input>
    <table type="float" name="Input Vector 1" descr="The first input vector" />
    </input>

    <input>
    <float name="Input Scalar 1" descr="The first input scalar" />
    </input>

    <!--outputs here-->
    <output>
    <table type="float" name="Output Vector 1" descr="The first output vector" />
    </output>

    <output>
    <float name="Output Scalar 1" descr="The first output scalar" />
    </output>

    </interface>

    </module>

Üldiselt võib ka toodud näidet mallina kasutada ja muuta sektsioonid enda vajadustele sobivaks. Nagu näha, sisaldab XML-fail sõlme `module`. Sõlmel `module` on omakorda sõlmed `intro` ja `interface`. Sõlme `intro` võib muuta vastavalt vajadustele, pidades silmas eeltoodud XML-failis leiduvaid kommentaare. Oluline on see, et `modulename` atribuut `name` oleks täpselt sama kasutatava ühisobjektifaili nimega.

Sõlm `interface` kirjeldab plugina sisendeid ja väljundeid. Iga sisendit kirjeldab sõlm `input` ja iga väljundit sõlm `output`. Igal sisendil peab olema järglasest sõlm `table` või `float`. Sõlme `table` atribuut `type` peab olema väärtusega `"float"`. Pane tähele, et oluline on ka sisendite ja väljundite järjekord — seda kasutatakse objektifaili iga sisend- ja väljundmassiivi indeksiväärtuste määramiseks ning selles järjekorras esitatakse sisend- ja väljundväljad ka &kst; pluginaliideses.

Kui oled XML-failiga ühele poole saanud, salvesta see kujul `[moodulinimi].xml`, kus `[moodulinimi]` on sõlme `modulename` atribuudi `name` väärtus.

### Ühisobjektifail

Ühisobjektifail sisaldab plugina tegelikke funktsioone. See tähendab, et just see määrab, kuidas antud sisendist saada vajalik väljund. Toome siinkohal ära ühisobjektifailile esitatavad nõuded:

- Objekt peab eksportima järgmise C linkimissümboli:

      int symbol(const double *const inArrays[],
                 const int inArrayLens[],
                 const double inScalars[],
                 double *outArrays[],
                 int outArrayLens[],
                 double outScalars[])

  kus symbol peab olema XML-faili sõlme `modulename` atribuudi `name` väärtus. See on ainus funktsioon, mille &kst; välja kutsub (kuigi neid funktsioone võib olla ka rohkem). Järgnevalt kirjeldame funktsiooni kõiki argumente:

  `const double *const inArrays[]`

    Sisendmassiivide massiiv. Iga sisendmassiiv vastab sisendvektorile. Massiivid on samas järjekorras, nagu XML-failis loetletud vektorid, nii et `inArrays[0]` tähistab esimesele sisendvektorile vastavat massiivi, `inArrays[1]` teisele sisendvektorile vastavat massiivi ja nii edasi.

  `const int inArraysLens[]`

    Iga sisendmassiivi massiivipikkusi sisaldav massiiv. Pikkused on samas järekorras, nagu massiivid argumendis `inArrays[]` (nt. `inArrayLens[0]` on `inArrays[0]` pikkus).

  `const double inScalars[]`

    Sisendskalaaride massiiv. Skalaarid on samas järjekorras, nagu nad on ära toodud XML-failis.

  `double *outArrays[]`

    Väljundmassiivide massiiv. Iga väljundmassiiv vastab väljundvektorile ja massiivid peavad olema samas järjekorras, nagu esinevad väljundvektorid XML-failis.

  `int outArrayLens[]`

    Väljundmassiivide pikkusi sisaldav massiiv. Pikkused peavad olema samas järjekorras, nagu on massiivid argumendis `outArrays[]`.

  `double outScalars[]`

    Väljundskalaaride massiiv. Skalaarid peavad olema samas järjekorras, nagu nad on ära toodud XML-failis.

- Funktsioon peab tagastama `0`, kui see täideti edukalt, ja `-1`, kui see nii ei olnud.

- Objektifaili kood peab suutma käsitleda ootamatut sisendit, näiteks tühja sisendmassiivi (enamasti peaks selliste olukordade puhul olema piisav tagastada väärtus `-1`).

- Väljundite arv ja tüüp peab täpselt vastama XML-failis antule.

- Tõenäoliselt on vajalik muuta `outArrays[]` massiivide suurust. Selleks kasuta funktsiooni `realloc()`. Nt.

      outArrays[0]=(double*)realloc(outArrays[0], 5*sizeof(double));

  eraldab ruumi viiele `outArrays[0]` double'ile. Ära kasuta mingit muud mälueraldajat kui `realloc()`.

- Sisendargumendid peavad olema konstandid. Need ei tohi olla mittekonstandi tüübiga.

Järgnev kujutab endast lihtsa plugina ühisobjektifaili näidislähtekoodi:

    #include <stdlib.h>

    extern "C" int testplugin(const double *const inArrays[], const int inArrayLens[],
                    const double is[],
                    double *outArrays[], int outArrayLens[],
                    double outScalars[]);

    int testplugin(const double *const inArrays[], const int inArrayLens[],
                    const double is[],
                    double *outArrays[], int outArrayLens[],
                    double outScalars[])

    //Accept 1 vector and 1 scalar. Multiply all elements of the vector by the
    //scalar, and output the resulting vector. Also output the original scalar.
    {
            //Set the outputs
            outArrayLens[0]=inArrayLens[0];

            //resize the output arrays
            outArrays[0]=(double*)realloc(outArrays[0], inArrayLens[0]*sizeof(double));

            //multiply each element of the input vector
            //by the scalar
            for (int i=0; i<inArrayLens[0]; i++)
            {
                    outArrays[0][i]=inArrays[0][i] * is[0];
            }

            //now set the output scalar
            outScalars[0]=is[0];

            return 0;
    }

### Plugina kompileerimine

Kui kasutad plugina kompileerimiseks &gcc;-d, kompileeri lihtsalt objektifail:

    cc -Wall -c -o minuplugin.o minuplugin.c -fPIC -DPIC

ja loo seejärel ühisteek:

    ld -o minuplugin.so -shared minuplugin.o

Saadavad failid `*.so` ja `*.xml` peavad asuma samas kataloogis. Kui kasutad XML-faili laadimiseks &kst; pluginahaldurit, otsib see automaatselt ühisobjektifaili samast kataloogist.

## Lineaarjaotuse pluginate loomine

Lineaarjaotuse plugina loomiseks tleb teostada oma jaotusalgoritmid ja luua vastavad vektorid. Kuid &kst; pakub juba ka omalt poolt päisefaile, mis muudavad vähimruutude lineaarjaotuse plugina teostamise päris lihtsaks, nõudes sinu käeset vaid mõnd funktsiooni. Selles osas kirjeldamegi, kuidas neid faile ära kasutada.

### Päisefailid

Lineaarjaotuse tarbeks on kaks päisefaili: `linear.h` (kaalumata lineaarjaotus) ja `linear_weighted.h` (kaalutud lineaarjaotus). Mõlemad asuvad &kst; lähtepaketi kataloogis `kst/plugins/fits/`. Nende kasutamiseks kaasa üks ja ainult üks neist oma plugina lähtekoodi:

    #include <../linear.h>

või

    #include <../linear_weighted.h>

(mugavuse mõttes asetame plugina lähtekoodi ühe kataloogi võrra hierarhias päisefailidest allapoole).

### Nõutavate funktsioonide teostamine

Üldise lineaarmudeli korral:

kus `y` on `n` vaatluse vektor, `X` on prognoositavate muutujate `n` korda `p` maatriks ja `c` on `p` hinnatavate parima jaotuse parameetrite vektor, võimaldavad päisefailid hinnata `c`-d antud `y` ja `X` korral. `X` pakkumiseks peab plugina lähtekoodis olema teostatud järgmine funktsioon:

    double calculate_matrix_entry( double dX, int iPos )

See funktsioon peab tagastama kirje väärtuse prognoositavate muutujate maatriksi veerus `iPos`, kasutades `x` väärtust `dX`. Funktsiooni kutsub välja linear.h või linear_weighted.h. Funktsiooni teostus sõltub mudelit, mida soovid jaotuse puhul kasutada, ning on unikaalne iga lineaarjaotuse plugina korral. Näiteks polünomiaalmudeli puhul tuleb `calculate_matrix_entry` teostada nii:

    double calculate_matrix_entry( double dX, int iPos ) {
      double dY;
      dY = pow( dX, (double)iPos );
      return dY;
    }

### Jaotusfunktsioonide väljakutsumine

Kui sobilik päisefail on kaasatud ja `calculate_matrix_entry` teostatud, kutsu päisefailist välja sobiv kaasatud jaotusfunktsioon:

    kstfit_linear_unweighted( inArrays, inArrayLens,
                              outArrays, outArrayLens,
                              outScalars, iNumParams );

või

    kstfit_linear_weighted( inArrays, inArrayLens,
                            outArrays, outArrayLens,
                            outScalars, iNumParams );

Iga funktsioon tagastab õnnestumise korral `0` ja ebaõnnestumise korral `-1`, mistõttu tasuks eksporditud C funktsiooni tagastatav väärtus määrata samaks jaotusfunktsiooni tagastatava väärtusega. Lihtsuse mõttes võib plugina kood lihtsalt edastada eksporditud C funktsioonile antud argumendid jaotusfunktsioonile. Pane aga tähele, et inArrays peab olema alljärgneva struktuuriga:

- `inArrays[0]` peab sisaldama andmepunktide X-koordinaatide massiivi

- `inArrays[1]` peab sisaldama andmepunktide Y-koordinaatide massiivi

- `inArrays[2]` on olemas ainult siis, kui kutsutakse välja `kstfit_linear_weighted` ning sisaldab sel juhul jaotuses kasutatavate kaalude massiivi.

Kõige lihtsam on inArrays korrektset struktuuri tagada vastavat sisendvektorite järjekorda plugina XML-failis kindlaks määrates.

`iNumParams` on jaotusmudelis kasutatavate parameetrite arv, mis peab olema võrdne prognoositavate muutujate maatriksi `X` veergude arvuga. `iNumParams` peab olema korrektselt määratud enne jaotusfunktsiooni väljakutsumist.

Kui `kstfit_linear_unweighted` või `kstfit_linear_weighted` on välja kutsutud, määratakse `outArrays` ja `outScalars` järgmiselt:

- `outArrays[0]` sisaldab jaotuvate Y-väärtuste massiivi.

- `outArrays[1]` sisaldab jääkide massiivi.

- `outArrays[2]` sisaldab hinnatavate parima jaotuse parameetrite massiivi.

- `outArrays[3]` sisaldab kovariantsusmaatriksit, mis tagastatakse rida realt massiivis.

- `outScalars[0]` sisaldab hii^2/nüü, kus hii^2 on jääkide ruutude kaalutud summa ja nüü on vabadusaste.

`outArrayLens` määrab korrektselt iga väljundmassiivi pikkuse.

Kontrolli, et XML-failis määratud väljundud vastaksid sellele, mida tagastab eksporditud C funktsioon (enamasti on selleks lihtsalt jaotusfunktsiooni tagastatud väljundid).

### Näide

Toome siin lineaarjaotuse plugina lähtekoodi näite.

    /*
     *  Polynomial fitting plugin for KST.
     *  Copyright 2004, The University of British Columbia
     *  Released under the terms of the GPL.
     */

    #include "../linear.h"

    double calculate_matrix_entry( double dX, int iPos ) {
      double dY;

      dY = pow( dX, (double)iPos );

      return dY;
    }

    extern "C" int kstfit_polynomial_unweighted(
      const double *const inArrays[],
      const int inArrayLens[],
      const double inScalars[],
      double *outArrays[], int outArrayLens[],
      double outScalars[]);

    int kstfit_polynomial_unweighted(
      const double *const inArrays[],
      const int inArrayLens[],
            const double inScalars[],
            double *outArrays[], int outArrayLens[],
            double outScalars[])
    {
      int iRetVal = -1;
      int iNumParams;

      iNumParams = 1 + (int)floor( inScalars[0] );
      if( iNumParams > 0 ) {
        iRetVal = kstfit_linear_unweighted( inArrays, inArrayLens,
                                            outArrays, outArrayLens,
                                            outScalars, iNumParams );
      }

      return iRetVal;
    }

## Mittelineaarse jaotuse pluginate loomine

&kst; pakub päisefaile, mis lihtsustavad mittelineaarse vähimruutude jaotuspluginate loomist. Järgnevalt kirjeldame päisefailide kasutamist.

### Päisefailid ja definitsioonid

Mittelineaarse jaotuse päisefailid asuvad &kst; lähtekoodi kataloogis `kst/plugins/fits_nonlinear`. Nende nimeks on `non_linear.h` ja `non_linear_weighted.h`, vastavalt siis kaalumata ja kaalutud jaotuse jaoks. Nende kasutamiseks kaasa üks ja ainult üks neist oma plugina lähtekoodi:

    #include <../non_linear.h>

või

    #include <../non_linear_weighted.h>

(mugavuse mõttes asetame plugina lähtekoodi ühe kataloogi võrra hierarhias päisefailidest allapoole).

Mittelineaarne jaotus on kordusi kasutav protsess, mistõttu peab määrama ka korduste maksimaalse arvu. Mittelineaarse jaotuse algoritm peatub, kui vähemalt üks järgnevates tingimustest on täidetud:

- Sooritati maksimaalne lubatud arv kordusi.

- Saavutati täpsus 10-4.

Lisaks tuleb defineerida mudeli parameetrite arv, sest seda ei edastata jaotusfunktsioonile vahetult. Nende kahe väärtuse määramiseks, lisa järgnev oma lähtekoodi algusse:

    #define NUM_PARAMS [num1]
    #define MAX_NUM_ITERATIONS [num2]

pannes `[num1]` asemele mudeli parameetrite arvu ja `[num2]` asemele maksimaalse lubatud korduste arvu.

### Nõutavate funktsioonide teostamine

Mittelineaarse jaotuse päisefailide kasutamiseks tuleb anda mudelina kasutatav funktsioon, funktsiooni osatuletised iga parameetri suhtes ja parima jaotuse parameetrite alghinnang. Selleks tuleb teostada kolm funktsiooni, mida allpool kirjeldamegi.

`double function_calculate( double `dX`, double* `pdParameters` )`

  See funktsioon arvutab jaotusmudeli Y-väärtuse antud X-väärtuse `dX` korral, kasutades parameetrite massiivi `pdParameters`. Parameetrite järjekord `pdParameters`-s on suvaline, kuid see peaks olema kooskõlas kahe ülejäänud funktsioogina. Näiteks eksponentmudeli korral saab `function_calculate` teostada nii:

      double function_calculate( double dX, double* pdParameters ) {
        double dScale         = pdParameters[0];
        double dLambda = pdParameters[1];
        double dOffset = pdParameters[2];
        double dY;

        dY  = ( dScale * exp( -dLambda * dX ) ) + dOffset;

        return dY;
      }

`void function_derivative( double `dX`, double* `pdParameters`, double* `pdDerivatives` )`

  See funktsioon arvutab mudeli funktsiooni osatuletised antud X-väärtuse `dX` korral. Osatuletisi peab tagastama `pdDerivatives`. Osatuletiste järjekord massiivis `pdDerivatives` peab vastama parameetrite järjekorrale `pdParameters`-is (s.t. kui `pdParameters[0]` sisaldab eksponentmudeli lambdaparameetrit, peab `pdDerivatives[0]` sisaldama mudeli tuletist lambda suhtes).

`void function_initial_estimate( const double* `pdX`, const double* `pdY`, int `iLength`, double* `pdParameterEstimates` )`

  See funktsioon annab jaotusfunktsioonile parima jaotuse parameetrite esialgse hinnangu. Andmepunktide X- ja Y-väärtuste massiivi annavad vastavalt `pdX` ja `pdY` ning andmepunktide arvu `iLength`. Esialgse hinnangu arvutamiseks võid kasutada omal äranägemisel kõiki parameetreid, ainult mõnda või ka mitte ühtegi. Funktsioon annab arvutatud esialgse hinnangu `pdParameterEstimates`-ile, kusjuures hinnangute järjekord vastab parameetrite järjekorral funktsioonide `function_calculate` ja `function_derivative` muutujas `pdParameters`. Pea meeles, et esialgne hinnang on olulise tähtsusega määramisel, kas jaotusfunktsioon suudab üldse mingi tulemuse anda või mitte.

### Jaotusfunktsioonide väljakutsumine

Kui kõik nõutud funktsioonid on teostatud, saab kaasatud päisefailist välja kutsuda jaotusfunktsiooni:

    kstfit_nonlinear( inArrays, inArrayLens,
                      inScalars, outArrays,
                      outArrayLens, outScalars );

või

    kstfit_nonlinear_weighted( inArrays, inArrayLens,
                               inScalars, outArrays,
                               outArrayLens, outScalars );

sõltuvalt sellest, kas teostad kaalumata või kaalutud jaotust.

Funktsioon tagastab õnenstumise korral `0`, vea korral `-1`, mistõttu tasuks eksporditud C funktsiooni tagastatav väärtus määrata samaks jaotusfunktsiooni tagastatava väärtusega. Lihtsuse mõttes võib plugina kood lihtsalt edastada eksporditud C funktsioonile antud argumendid jaotusfunktsioonile. Pane aga tähele, et inArrays peab olema alljärgneva struktuuriga:

- `inArrays[0]` peab sisaldama andmepunktide X-koordinaatide massiivi

- `inArrays[1]` peab sisaldama andmepunktide Y-koordinaatide massiivi

- `inArrays[2]` on olemas ainult siis, kui kutsutakse välja `kstfit_linear_weighted` ning sisaldab sel juhul jaotuses kasutatavate kaalude massiivi.

Kõige lihtsam on inArrays korrektset struktuuri tagada vastavat sisendvektorite järjekorda plugina XML-failis kindlaks määrates.

Kui `kstfit_linear_unweighted` või `kstfit_linear_weighted` on välja kutsutud, määratakse `outArrays` ja `outScalars` järgmiselt:

- `outArrays[0]` sisaldab jaotuvate Y-väärtuste massiivi.

- `outArrays[1]` sisaldab jääkide massiivi.

- `outArrays[2]` sisaldab hinnatavate parima jaotuse parameetrite massiivi.

- `outArrays[3]` sisaldab kovariantsusmaatriksit, mis tagastatakse rida realt massiivis.

- `outScalars[0]` sisaldab hii^2/nüü, kus hii^2 on jääkide ruutude kaalutud summa ja nüü on vabadusaste.

`outArrayLens` määrab korrektselt iga väljundmassiivi pikkuse.

Kontrolli, et XML-failis määratud väljundud vastaksid sellele, mida tagastab eksporditud C funktsioon (enamasti on selleks lihtsalt jaotusfunktsiooni tagastatud väljundid).

### Näide

Järgnevalt toome näite mittelineaarse jaotuse plugina kohta, mis sooritab jaotuse eksponentmudelil.

    /*
     *  Exponential fit plugin for KST.
     *  Copyright 2004, The University of British Columbia
     *  Released under the terms of the GPL.
     */

    #define NUM_PARAMS 3
    #define MAX_NUM_ITERATIONS 500

    #include "../non_linear.h"

    void function_initial_estimate( const double* pdX, const double* pdY,
                                    int iLength, double* pdParameterEstimates ) {
      KST_UNUSED( pdX )
      KST_UNUSED( pdY )
      KST_UNUSED( iLength )

      pdParameterEstimates[0] =  1.0;
      pdParameterEstimates[1] =  0.0;
      pdParameterEstimates[2] =  0.0;
    }

    double function_calculate( double dX, double* pdParameters ) {
      double dScale         = pdParameters[0];
      double dLambda = pdParameters[1];
      double dOffset = pdParameters[2];
      double dY;

      dY  = ( dScale * exp( -dLambda * dX ) ) + dOffset;

      return dY;
    }

    void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) {
      double dScale         = pdParameters[0];
      double dLambda = pdParameters[1];
      double dExp;
      double ddScale;
      double ddLambda;
      double ddOffset;

      dExp     = exp( -dLambda * dX );
      ddScale  = dExp;
      ddLambda = -dX * dScale * dExp;
      ddOffset = 1.0;

      pdDerivatives[0] = ddScale;
      pdDerivatives[1] = ddLambda;
      pdDerivatives[2] = ddOffset;
    }

    extern "C" int kstfit_exponential(const double *const inArrays[], const int inArrayLens[],
                    const double inScalars[],
                    double *outArrays[], int outArrayLens[],
                    double outScalars[]);

    int kstfit_exponential(const double *const inArrays[], const int inArrayLens[],
                    const double inScalars[],
                    double *outArrays[], int outArrayLens[],
                    double outScalars[])
    {
      return kstfit_nonlinear( inArrays, inArrayLens,
                               inScalars, outArrays,
                               outArrayLens, outScalars );
    }

## Läbipääsufiltripluginate loomine

&kst; pakub oäisefaile läbipääsufiltrite pluginate teostamise lihtsustamiseks. Järgnevalt kirjeldatakse päisefailide kasutamist.

### Päisefailid

Läbipääsufiltri päisefail asub &kst; lähtekoodi kataloogis `kst/plugins/pass_filters`. Faili nimi on `filters.h`. Selle kasutamiseks kaasa fail oma plugina lähtekoodi:

    #include <../filters.h>

(mugavuse mõttes asetame plugina lähtekoodi ühe kataloogi võrra hierarhias päisefailidest allapoole).

### Nõutavad funktsioonid

Päisefail `filter.h` sisaldab ühtainust funktsiooni, mis arvutab antud funktsiooni Fourier' teisenduse, rakendab Fourier' teisendusele antud filtrit ja seejärel arvutab filtreeritud Fourier' teisenduse Fourier' pöördteisenduse. Filtri andmiseks tuleb plugina lähtekoodis teostada järgmine funktsioon:

`double filter_calculate( double `dFreqValue`, const double `inScalars[]` )`

See funktsioon arvutab sageduse `dFreqValue` filtreeritud amplituudi. `inScalars[]` sisaldab XML-failis määratud plugina muutmata sisendskalaare. Tõenäoliselt sisaldab `inScalars[]` lõikesagedusi või muid filtri omadusi. Näiteks Butterworthi kõrgpääsufiltri teostamiseks tuleks `filter_calculate` teostada nii:

    double filter_calculate( double dFreqValue, const double inScalars[] ) {
      double dValue;
      if( dFreqValue
    > 0.0 ) {
        dValue = 1.0 / ( 1.0 +
                        pow( inScalars[1] / dFreqValue, 2.0 * (double)inScalars[0] ) );
      } else {
        dValue = 0.0;
      }
      return dValue;
    }

### Filtri funktsiooni väljakutsumine

Kui nõutab `filter_calculate` on teostatud, saab filtri funktsiooni välja kutsuda päisefailist:

    kst_pass_filter( inArrays,
                     inArrayLens,
                     inScalars,
                     outArrays,
                     outArrayLens,
                     outScalars );

Eksporditud C funktsioonile antud argumendid edastatakse tavaliselt funktsioonile `kst_pass_filter` muutmatult. Kuid argumentide juures tuleb arvestada mõne piiranguga:

- `inArrays[0]` peab sisaldama filtreeritavate andmete massiivi.

- `inScalars` peab sisaldama filtrile spetsiifilisi parameetreid, mida kasutab funktsioon `filter_calculate`.

Pärast funktsiooni väljakutset sisaldab `outArrays[0]` filtreeritud andmemassiivi, ja vastavalt määratakse ka `outArrayLens`. Funktsioon `kst_pass_filter` ei kasuta muutujat `outScalars`.

### Näide

Järgnevalt toome Butterworthi kõrgpääsufiltrit teostava läbipääsufiltri näite.

    /*
     *  Butterworth low pass filter plugin for KST.
     *  Copyright 2004, The University of British Columbia
     *  Released under the terms of the GPL.
     */

    #include <stdlib.h>
    #include <math.h>
    #include "../filters.h"

    extern "C" int butterworth_highpass(const double *const inArrays[], const int inArrayLens[],
                    const double inScalars[],
                    double *outArrays[], int outArrayLens[],
                    double outScalars[]);

    int butterworth_highpass(const double *const inArrays[], const int inArrayLens[],
                    const double inScalars[],
                    double *outArrays[], int outArrayLens[],
                    double outScalars[])
    {
      int iReturn;

      iReturn = kst_pass_filter( inArrays,
                                 inArrayLens,
                                 inScalars,
                                 outArrays,
                                 outArrayLens,
                                 outScalars );

      return iReturn;
    }

    double filter_calculate( double dFreqValue, const double inScalars[] ) {
      double dValue;

      if( dFreqValue > 0.0 ) {
        dValue = 1.0 / ( 1.0 + pow( inScalars[1] / dFreqValue, 2.0 * (double)inScalars[0] ) );
      } else {
        dValue = 0.0;
      }

      return dValue;
    }