<appendix id="creatingplugins">
<title
>Lisapluginate loomine</title>
<para
>&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. </para>

<sect1 id="creatingbasicplugin">
<title
>Plugina loomise põhitõed</title>
<para
>&kst; plugin koosneb kahest failist &mdash; XML-fail ja ühisobjektifail. </para>

<sect2 id="creatingbasicpluginxmlfile">
<title
>XML-fail</title>
<para
>XML-fail annab plugina kohta infot ja kirjeldab selle sisendeid ning väljundeid. Allpool on &kst; plugina XML-faili näidis: </para>

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

&lt;module&gt;

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

&lt;interface&gt;

&lt;!--inputs here--&gt;
&lt;input&gt;
&lt;table type="float" name="Input Vector 1" descr="The first input vector" /&gt;
&lt;/input&gt;

&lt;input&gt;
&lt;float name="Input Scalar 1" descr="The first input scalar" /&gt;
&lt;/input&gt;

&lt;!--outputs here--&gt;
&lt;output&gt;
&lt;table type="float" name="Output Vector 1" descr="The first output vector" /&gt;
&lt;/output&gt;

&lt;output&gt;
&lt;float name="Output Scalar 1" descr="The first output scalar" /&gt;
&lt;/output&gt;

&lt;/interface&gt;

&lt;/module&gt;
</screen>
</informalexample>

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

<para
>Sõlm <literal
>interface</literal
> kirjeldab plugina sisendeid ja väljundeid. Iga sisendit kirjeldab sõlm <literal
>input</literal
> ja iga väljundit sõlm <literal
>output</literal
>. Igal sisendil peab olema järglasest sõlm <literal
>table</literal
> või <literal
>float</literal
>. Sõlme <literal
>table</literal
> atribuut <literal
>type</literal
> peab olema väärtusega <literal
>&quot;float&quot;</literal
>. Pane tähele, et oluline on ka sisendite ja väljundite järjekord &mdash; 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. </para>

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

</sect2>

<sect2 id="creatingbasicpluginobjectfile">
<title
>Ühisobjektifail</title>
<para
>Ü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: </para>

<itemizedlist>

<listitem>
<para
>Objekt peab eksportima järgmise C linkimissümboli: <literallayout
><function
><returnvalue
>int</returnvalue
> symbol(const double *const <parameter
>inArrays[]</parameter
>,
           const int <parameter
>inArrayLens[]</parameter
>,
           const double <parameter
>inScalars[]</parameter
>,
           double *<parameter
>outArrays[]</parameter
>,
           int <parameter
>outArrayLens[]</parameter
>,
           double <parameter
>outScalars[]</parameter
>)</function
></literallayout>
</para>
<para
>kus <replaceable
>symbol</replaceable
> peab olema XML-faili sõlme <literal
>modulename</literal
> atribuudi <literal
>name</literal
> 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: </para>

<variablelist>
<varlistentry>
<term
><varname
>const double *const inArrays[]</varname
></term>
<listitem>
<para
>Sisendmassiivide massiiv. Iga sisendmassiiv vastab sisendvektorile. Massiivid on samas järjekorras, nagu XML-failis loetletud vektorid, nii et <literal
>inArrays[0]</literal
> tähistab esimesele sisendvektorile vastavat massiivi, <literal
>inArrays[1]</literal
> teisele sisendvektorile vastavat massiivi ja nii edasi. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>const int inArraysLens[]</varname
></term>
<listitem>
<para
>Iga sisendmassiivi massiivipikkusi sisaldav massiiv. Pikkused on samas järekorras, nagu massiivid argumendis <literal
>inArrays[]</literal
> (nt. <literal
>inArrayLens[0]</literal
> on <literal
>inArrays[0]</literal
> pikkus). </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>const double inScalars[]</varname
></term>
<listitem>
<para
>Sisendskalaaride massiiv. Skalaarid on samas järjekorras, nagu nad on ära toodud XML-failis. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>double *outArrays[]</varname
></term>
<listitem>
<para
>Väljundmassiivide massiiv. Iga väljundmassiiv vastab väljundvektorile ja massiivid peavad olema samas järjekorras, nagu esinevad väljundvektorid XML-failis. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>int outArrayLens[]</varname
></term>
<listitem>
<para
>Väljundmassiivide pikkusi sisaldav massiiv. Pikkused peavad olema samas järjekorras, nagu on massiivid argumendis <literal
>outArrays[]</literal
>. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>double outScalars[]</varname
></term>
<listitem>
<para
>Väljundskalaaride massiiv. Skalaarid peavad olema samas järjekorras, nagu nad on ära toodud XML-failis. </para>
</listitem>
</varlistentry>
</variablelist>


</listitem>

<listitem>
<para
>Funktsioon peab tagastama <literal
>0</literal
>, kui see täideti edukalt, ja <literal
>-1</literal
>, kui see nii ei olnud. </para>
</listitem>

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

<listitem>
<para
>Väljundite arv ja tüüp peab täpselt vastama XML-failis antule. </para>
</listitem>

<listitem>
<para
>Tõenäoliselt on vajalik muuta <varname
>outArrays[]</varname
> massiivide suurust. Selleks kasuta funktsiooni <function
>realloc()</function
>. Nt. </para>
<informalexample>
<screen
>outArrays[0]=(double*)realloc(outArrays[0], 5*sizeof(double));
</screen>
</informalexample>
<para
>eraldab ruumi viiele <varname
>outArrays[0]</varname
> double'ile. Ära kasuta mingit muud mälueraldajat kui <function
>realloc()</function
>. </para>
</listitem>

<listitem>
<para
>Sisendargumendid peavad olema konstandid. Need ei tohi olla mittekonstandi tüübiga. </para>
</listitem>

</itemizedlist>

<para
>Järgnev kujutab endast lihtsa plugina ühisobjektifaili näidislähtekoodi: </para>
<informalexample>
<screen
>#include &lt;stdlib.h&gt;

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&lt;inArrayLens[0]; i++)
        {
                outArrays[0][i]=inArrays[0][i] * is[0];
        }

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

        return 0;
}
</screen>
</informalexample>
</sect2>


<sect2 id="compilingplugin">
<title
>Plugina kompileerimine</title>
<para
>Kui kasutad plugina kompileerimiseks &gcc;-d, kompileeri lihtsalt objektifail: <screen
><userinput
><command
>cc -Wall -c -o minuplugin.o minuplugin.c -fPIC -DPIC</command
></userinput
></screen>
</para>
<para
>ja loo seejärel ühisteek: <screen
><userinput
><command
>ld -o minuplugin.so -shared minuplugin.o</command
></userinput
></screen>
</para>
<para
>Saadavad failid <filename
>*.so</filename
> ja <filename
>*.xml</filename
> peavad asuma samas kataloogis. Kui kasutad XML-faili laadimiseks &kst; pluginahaldurit, otsib see automaatselt ühisobjektifaili samast kataloogist. </para>

</sect2>
</sect1>

<sect1 id="creatinglinearfittingplugins">
<title
>Lineaarjaotuse pluginate loomine</title>
<para
>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. </para>

<sect2 id="headerslinearfittingplugins">
<title
>Päisefailid</title>
<para
>Lineaarjaotuse tarbeks on kaks päisefaili: <filename
>linear.h</filename
> (kaalumata lineaarjaotus) ja <filename
>linear_weighted.h</filename
> (kaalutud lineaarjaotus). Mõlemad asuvad &kst; lähtepaketi kataloogis <filename
>kst/plugins/fits/</filename
>. Nende kasutamiseks kaasa üks ja ainult üks neist oma plugina lähtekoodi: <screen>
#include &lt;../linear.h&gt;
</screen
> või <screen>
#include &lt;../linear_weighted.h&gt;
</screen
> (mugavuse mõttes asetame plugina lähtekoodi ühe kataloogi võrra hierarhias päisefailidest allapoole). </para>

</sect2>

<sect2 id="reqfunctionsfittingplugins">
<title
>Nõutavate funktsioonide teostamine</title>
<para
>Üldise lineaarmudeli korral: </para>
<para>
<inlinemediaobject>
<imageobject>
<imagedata fileref="Formula-kst-generallinearmodel.png" format="PNG"/>
</imageobject>
</inlinemediaobject>
</para>
<para
>kus <literal
>y</literal
> on <literal
>n</literal
> vaatluse vektor, <literal
>X</literal
> on prognoositavate muutujate <literal
>n</literal
> korda <literal
>p</literal
> maatriks ja <literal
>c</literal
> on <literal
>p</literal
> hinnatavate parima jaotuse parameetrite vektor, võimaldavad päisefailid hinnata <literal
>c</literal
>-d antud <literal
>y</literal
> ja <literal
>X</literal
> korral. <literal
>X</literal
> pakkumiseks peab plugina lähtekoodis olema teostatud järgmine funktsioon: <literallayout
><function
><returnvalue
>double</returnvalue
> calculate_matrix_entry( double <parameter
>dX</parameter
>, int <parameter
>iPos</parameter
> )</function
></literallayout>
</para>
<para
>See funktsioon peab tagastama kirje väärtuse prognoositavate muutujate maatriksi veerus <literal
>iPos</literal
>, kasutades <literal
>x</literal
> väärtust <literal
>dX</literal
>. 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 <function
>calculate_matrix_entry</function
> teostada nii: <informalexample
> <screen
>double calculate_matrix_entry( double dX, int iPos ) {
  double dY;
  dY = pow( dX, (double)iPos );
  return dY;
}
</screen>
</informalexample>
</para>

</sect2>

<sect2 id="callingfittingfunctionslinearfittingplugins">
<title
>Jaotusfunktsioonide väljakutsumine</title>
<para
>Kui sobilik päisefail on kaasatud ja <function
>calculate_matrix_entry</function
> teostatud, kutsu päisefailist välja sobiv kaasatud jaotusfunktsioon: <screen>
<function
>kstfit_linear_unweighted( <parameter
>inArrays</parameter
>, <parameter
>inArrayLens</parameter
>,
                          <parameter
>outArrays</parameter
>, <parameter
>outArrayLens</parameter
>,
                          <parameter
>outScalars</parameter
>, <parameter
>iNumParams</parameter
> )</function
>;
</screen
> või <screen
><function
>kstfit_linear_weighted( <parameter
>inArrays</parameter
>, <parameter
>inArrayLens</parameter
>,
                        <parameter
>outArrays</parameter
>, <parameter
>outArrayLens</parameter
>,
                        <parameter
>outScalars</parameter
>, <parameter
>iNumParams</parameter
> )</function
>;
</screen>
</para>
<para
>Iga funktsioon tagastab õnnestumise korral <literal
>0</literal
> ja ebaõnnestumise korral <literal
>-1</literal
>, 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: </para>
<itemizedlist>
<listitem>
<para
><varname
>inArrays[0]</varname
> peab sisaldama andmepunktide X-koordinaatide massiivi </para>
</listitem>

<listitem>
<para
><varname
>inArrays[1]</varname
> peab sisaldama andmepunktide Y-koordinaatide massiivi </para>
</listitem>

<listitem>
<para
><varname
>inArrays[2]</varname
> on olemas ainult siis, kui kutsutakse välja <function
>kstfit_linear_weighted</function
> ning sisaldab sel juhul jaotuses kasutatavate kaalude massiivi. </para>
</listitem>
</itemizedlist>
<para
>Kõige lihtsam on inArrays korrektset struktuuri tagada vastavat sisendvektorite järjekorda plugina XML-failis kindlaks määrates. </para>
<para
><varname
>iNumParams</varname
> on jaotusmudelis kasutatavate parameetrite arv, mis peab olema võrdne prognoositavate muutujate maatriksi <literal
>X</literal
> veergude arvuga. <varname
>iNumParams</varname
> peab olema korrektselt määratud enne jaotusfunktsiooni väljakutsumist. </para>
<para
>Kui <function
>kstfit_linear_unweighted</function
> või <function
>kstfit_linear_weighted</function
> on välja kutsutud, määratakse <varname
>outArrays</varname
> ja <varname
>outScalars</varname
> järgmiselt: </para>
<itemizedlist>
<listitem>
<para
><varname
>outArrays[0]</varname
> sisaldab jaotuvate Y-väärtuste massiivi. </para>
</listitem>

<listitem>
<para
><varname
>outArrays[1]</varname
> sisaldab jääkide massiivi. </para>
</listitem>

<listitem>
<para
><varname
>outArrays[2]</varname
> sisaldab hinnatavate parima jaotuse parameetrite massiivi. </para>
</listitem>

<listitem>
<para
><varname
>outArrays[3]</varname
> sisaldab kovariantsusmaatriksit, mis tagastatakse rida realt massiivis. </para>
</listitem>

<listitem>
<para
><varname
>outScalars[0]</varname
> sisaldab hii^2/nüü, kus hii^2 on jääkide ruutude kaalutud summa ja nüü on vabadusaste. </para>
</listitem>
</itemizedlist>
<para
><varname
>outArrayLens</varname
> määrab korrektselt iga väljundmassiivi pikkuse. </para>

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


</sect2>

<sect2 id="examplelinearfittingplugins">
<title
>Näide</title>
<para
>Toome siin lineaarjaotuse plugina lähtekoodi näite. </para>
<informalexample>
<screen
>/*
 *  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 &gt; 0 ) {
    iRetVal = kstfit_linear_unweighted( inArrays, inArrayLens,
                                        outArrays, outArrayLens,
                                        outScalars, iNumParams );
  }

  return iRetVal;
}
</screen>
</informalexample>
</sect2>

</sect1>

<sect1 id="creatingnonlinearfitplugin">
<title
>Mittelineaarse jaotuse pluginate loomine</title>
<para
>&kst; pakub päisefaile, mis lihtsustavad mittelineaarse vähimruutude jaotuspluginate loomist. Järgnevalt kirjeldame päisefailide kasutamist. </para>

<sect2 id="headersnonlinearfittingplugins">
<title
>Päisefailid ja definitsioonid</title>
<para
>Mittelineaarse jaotuse päisefailid asuvad &kst; lähtekoodi kataloogis <filename
>kst/plugins/fits_nonlinear</filename
>. Nende nimeks on <filename
>non_linear.h</filename
> ja <filename
>non_linear_weighted.h</filename
>, vastavalt siis kaalumata ja kaalutud jaotuse jaoks. Nende kasutamiseks kaasa üks ja ainult üks neist oma plugina lähtekoodi: <screen>
#include &lt;../non_linear.h&gt;
</screen
> või <screen>
#include &lt;../non_linear_weighted.h&gt;
</screen
> (mugavuse mõttes asetame plugina lähtekoodi ühe kataloogi võrra hierarhias päisefailidest allapoole). </para>

<para
>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: </para>
<itemizedlist>
<listitem>
<para
>Sooritati maksimaalne lubatud arv kordusi. </para>
</listitem>
<listitem>
<para
>Saavutati täpsus 10<superscript
>-4</superscript
>. </para>
</listitem>
</itemizedlist>
<para
>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: </para>
<screen
>#define NUM_PARAMS [num1]
#define MAX_NUM_ITERATIONS [num2]
</screen>
<para
>pannes <literal
>[num1]</literal
> asemele mudeli parameetrite arvu ja <literal
>[num2]</literal
> asemele maksimaalse lubatud korduste arvu. </para>
</sect2>

<sect2 id="reqfunctionsnonlinearfittingplugins">
<title
>Nõutavate funktsioonide teostamine</title>
<para
>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. </para>
<variablelist>
<varlistentry>
<term
><function
><returnvalue
>double</returnvalue
> function_calculate( double <parameter
>dX</parameter
>, double* <parameter
>pdParameters</parameter
> )</function
></term>
<listitem>
<para
>See funktsioon arvutab jaotusmudeli Y-väärtuse antud X-väärtuse <literal
>dX</literal
> korral, kasutades parameetrite massiivi <varname
>pdParameters</varname
>. Parameetrite järjekord <varname
>pdParameters</varname
>-s on suvaline, kuid see peaks olema kooskõlas kahe ülejäänud funktsioogina. Näiteks eksponentmudeli korral saab <function
>function_calculate</function
> teostada nii: </para>
<informalexample>
<screen
>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;
}
</screen>
</informalexample>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
><returnvalue
>void</returnvalue
> function_derivative( double <parameter
>dX</parameter
>, double* <parameter
>pdParameters</parameter
>, double* <parameter
>pdDerivatives</parameter
> )</function
></term>
<listitem>
<para
>See funktsioon arvutab mudeli funktsiooni osatuletised antud X-väärtuse <literal
>dX</literal
> korral. Osatuletisi peab tagastama <varname
>pdDerivatives</varname
>. Osatuletiste järjekord massiivis <varname
>pdDerivatives</varname
> peab vastama parameetrite järjekorrale <varname
>pdParameters</varname
>-is (s.t. kui <varname
>pdParameters[0]</varname
> sisaldab eksponentmudeli lambdaparameetrit, peab <varname
>pdDerivatives[0]</varname
> sisaldama mudeli tuletist lambda suhtes). </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
><returnvalue
>void</returnvalue
> function_initial_estimate( const double* <parameter
>pdX</parameter
>, const double* <parameter
>pdY</parameter
>, int <parameter
>iLength</parameter
>, double* <parameter
>pdParameterEstimates</parameter
> )</function
></term>
<listitem>
<para
>See funktsioon annab jaotusfunktsioonile parima jaotuse parameetrite esialgse hinnangu. Andmepunktide X- ja Y-väärtuste massiivi annavad vastavalt <varname
>pdX</varname
> ja <varname
>pdY</varname
> ning andmepunktide arvu <varname
>iLength</varname
>. 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 <varname
>pdParameterEstimates</varname
>-ile, kusjuures hinnangute järjekord vastab parameetrite järjekorral funktsioonide <function
>function_calculate</function
> ja <function
>function_derivative</function
> muutujas <varname
>pdParameters</varname
>. Pea meeles, et esialgne hinnang on olulise tähtsusega määramisel, kas jaotusfunktsioon suudab üldse mingi tulemuse anda või mitte. </para>
</listitem>
</varlistentry>

</variablelist>

</sect2>

<sect2 id="callingnonlinearfittingplugins">
<title
>Jaotusfunktsioonide väljakutsumine</title>
<para
>Kui kõik nõutud funktsioonid on teostatud, saab kaasatud päisefailist välja kutsuda jaotusfunktsiooni: <screen>
kstfit_nonlinear( <parameter
>inArrays</parameter
>, <parameter
>inArrayLens</parameter
>,
                  <parameter
>inScalars</parameter
>, <parameter
>outArrays</parameter
>,
                  <parameter
>outArrayLens</parameter
>, <parameter
>outScalars</parameter
> );
</screen
> või <screen>
kstfit_nonlinear_weighted( <parameter
>inArrays</parameter
>, <parameter
>inArrayLens</parameter
>,
                           <parameter
>inScalars</parameter
>, <parameter
>outArrays</parameter
>,
                           <parameter
>outArrayLens</parameter
>, <parameter
>outScalars</parameter
> );
</screen
> sõltuvalt sellest, kas teostad kaalumata või kaalutud jaotust. </para>

<para
>Funktsioon tagastab õnenstumise korral <literal
>0</literal
>, vea korral <literal
>-1</literal
>, 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: </para>
<itemizedlist>
<listitem>
<para
><varname
>inArrays[0]</varname
> peab sisaldama andmepunktide X-koordinaatide massiivi </para>
</listitem>

<listitem>
<para
><varname
>inArrays[1]</varname
> peab sisaldama andmepunktide Y-koordinaatide massiivi </para>
</listitem>

<listitem>
<para
><varname
>inArrays[2]</varname
> on olemas ainult siis, kui kutsutakse välja <function
>kstfit_linear_weighted</function
> ning sisaldab sel juhul jaotuses kasutatavate kaalude massiivi. </para>
</listitem>
</itemizedlist>
<para
>Kõige lihtsam on inArrays korrektset struktuuri tagada vastavat sisendvektorite järjekorda plugina XML-failis kindlaks määrates. </para>
<para
>Kui <function
>kstfit_linear_unweighted</function
> või <function
>kstfit_linear_weighted</function
> on välja kutsutud, määratakse <varname
>outArrays</varname
> ja <varname
>outScalars</varname
> järgmiselt: </para>
<itemizedlist>
<listitem>
<para
><varname
>outArrays[0]</varname
> sisaldab jaotuvate Y-väärtuste massiivi. </para>
</listitem>

<listitem>
<para
><varname
>outArrays[1]</varname
> sisaldab jääkide massiivi. </para>
</listitem>

<listitem>
<para
><varname
>outArrays[2]</varname
> sisaldab hinnatavate parima jaotuse parameetrite massiivi. </para>
</listitem>

<listitem>
<para
><varname
>outArrays[3]</varname
> sisaldab kovariantsusmaatriksit, mis tagastatakse rida realt massiivis. </para>
</listitem>

<listitem>
<para
><varname
>outScalars[0]</varname
> sisaldab hii^2/nüü, kus hii^2 on jääkide ruutude kaalutud summa ja nüü on vabadusaste. </para>
</listitem>
</itemizedlist>
<para
><varname
>outArrayLens</varname
> määrab korrektselt iga väljundmassiivi pikkuse. </para>

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

</sect2>

<sect2 id="nonlinearfittingpluginexample">
<title
>Näide</title>
<para
>Järgnevalt toome näite mittelineaarse jaotuse plugina kohta, mis sooritab jaotuse eksponentmudelil.</para>
<informalexample>
<screen
>/*
 *  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 );
}
</screen>
</informalexample>

</sect2>
</sect1>

<sect1 id="creatingpassfilterplugins">
<title
>Läbipääsufiltripluginate loomine</title>
<para
>&kst; pakub oäisefaile läbipääsufiltrite pluginate teostamise lihtsustamiseks. Järgnevalt kirjeldatakse päisefailide kasutamist. </para>
<sect2 id="creatingpassfilterpluginsheaderfiles">
<title
>Päisefailid</title>
<para
>Läbipääsufiltri päisefail asub &kst; lähtekoodi kataloogis <filename
>kst/plugins/pass_filters</filename
>. Faili nimi on <filename
>filters.h</filename
>. Selle kasutamiseks kaasa fail oma plugina lähtekoodi: <screen>
#include &lt;../filters.h&gt;
</screen
> (mugavuse mõttes asetame plugina lähtekoodi ühe kataloogi võrra hierarhias päisefailidest allapoole). </para>
</sect2>

<sect2 id="creatingpassfilterpluginsrequirements">
<title
>Nõutavad funktsioonid</title>
<para
>Päisefail <filename
>filter.h</filename
> 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: </para>
<para
><function
><returnvalue
>double</returnvalue
> filter_calculate( double <parameter
>dFreqValue</parameter
>, const double <parameter
>inScalars[]</parameter
> )</function
></para>
<para
>See funktsioon arvutab sageduse <literal
>dFreqValue</literal
> filtreeritud amplituudi. <literal
>inScalars[]</literal
> sisaldab XML-failis määratud plugina muutmata sisendskalaare. Tõenäoliselt sisaldab <literal
>inScalars[]</literal
> lõikesagedusi või muid filtri omadusi. Näiteks Butterworthi kõrgpääsufiltri teostamiseks tuleks <function
>filter_calculate</function
> teostada nii: </para>
<informalexample>
<screen
>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;
}
</screen>
</informalexample>
</sect2>

<sect2 id="creatingpassfilterpluginscallingfunction">
<title
>Filtri funktsiooni väljakutsumine</title>
<para
>Kui nõutab <function
>filter_calculate</function
> on teostatud, saab filtri funktsiooni välja kutsuda päisefailist: </para>
<literallayout
><function
>kst_pass_filter( <parameter
>inArrays</parameter
>,
                 <parameter
>inArrayLens</parameter
>,
                 <parameter
>inScalars</parameter
>,
                 <parameter
>outArrays</parameter
>,
                 <parameter
>outArrayLens</parameter
>,
                 <parameter
>outScalars</parameter
> );</function
></literallayout>
<para
>Eksporditud C funktsioonile antud argumendid edastatakse tavaliselt funktsioonile <function
>kst_pass_filter</function
> muutmatult. Kuid argumentide juures tuleb arvestada mõne piiranguga: </para>
<itemizedlist>
<listitem>
<para
><varname
>inArrays[0]</varname
> peab sisaldama filtreeritavate andmete massiivi. </para>
</listitem>

<listitem>
<para
><varname
>inScalars</varname
> peab sisaldama filtrile spetsiifilisi parameetreid, mida kasutab funktsioon <function
>filter_calculate</function
>. </para>
</listitem>
</itemizedlist>
<para
>Pärast funktsiooni väljakutset sisaldab <varname
>outArrays[0]</varname
> filtreeritud andmemassiivi, ja vastavalt määratakse ka <varname
>outArrayLens</varname
>. Funktsioon <function
>kst_pass_filter</function
> ei kasuta muutujat <varname
>outScalars</varname
>. </para>
</sect2>

<sect2 id="creatingpassfilterpluginsexample">
<title
>Näide</title>
<para
>Järgnevalt toome Butterworthi kõrgpääsufiltrit teostava läbipääsufiltri näite. </para>
<informalexample>
<screen
>/*
 *  Butterworth low pass filter plugin for KST.
 *  Copyright 2004, The University of British Columbia
 *  Released under the terms of the GPL.
 */

#include &lt;stdlib.h&gt;
#include &lt;math.h&gt;
#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 &gt; 0.0 ) {
    dValue = 1.0 / ( 1.0 + pow( inScalars[1] / dFreqValue, 2.0 * (double)inScalars[0] ) );
  } else {
    dValue = 0.0;
  }

  return dValue;
}</screen>
</informalexample>
</sect2>

</sect1>
</appendix>