Hlavní navigace

Gnuplot: příkaz "fit"

29. 8. 2001
Doba čtení: 6 minut

Sdílet

Na konci minulého dílu jsme se podívali na to, jak jednoduše proložit body v datovém souboru křivkou. Ukázali jsme si však jen jednodušší možnost, kdy si můžeme zvolit pouze z několika křivek. Dnes se tedy podíváme, jakým způsobem data proložit libovolnou, námi zvolenou křivkou.

Jednoduché prokládání bodů křivkou umožňuje přepínač smooth příkazu plot. Ten však prokládá body „po částech“. To znamená, že zvolíme-li například metodu csplines, bude interval mezi každými dvěma body v souboru nahrazen kubickou funkcí tak, aby na sebe body plynule navazovaly a budily zdání jediné funkce. Zvolíme-li pak metodu unique, je to stejné, jako bychom kreslili pomocí plot with lines.

To může být někdy výhodné, mnohdy však potřebujeme úplně něco jiného. Řekněme, že máme navzorkován nějaký signál a víme, jaký ten signál je (jakou je popsán funkcí). No a my chceme navzorkovaná data proložit touto funkcí.

K tomu nám gnuplot dává perfektní prostředek. Disponuje funkcí fit, díky níž můžeme data v souboru proložit jakoukoliv křivkou. Data jsou proložena tak, aby odchylka od bodů udaných v datovém souboru byla minimální (hodnocení metodou nejmenších čtverců). Algoritmus je iterační, časem dokonverguje k hledanému minimu (ne vždy však globálnímu).

To by bylo asi tak všechno ohledně matematiky. Snad jsem se nedopustil chyby, matematika není tak úplně můj obor, ale pokud ano, laskavý čtenář promine :). Dále se už podíváme na praktičtější stránku věci.

Funkce fit má tento prototyp:

 fit rozsahy f(x) "data" datové_specifikátory via proměnné

Parametry rozsahy a datové_specifi­kátory se vztahují k datovému souboru. Stejným způsobem, jakým můžeme upravit nebo omezit vykreslování bodů z datového souboru, můžeme i upřesnit, které body a jak mají být zahrnuty do výpočtu křivky. Více jsme si o zpracování datového souboru řekli v minulém dílu. Jediným parametrem, který v tomto případě nemůžeme použít, je přepínač smooth (ze zcela pochopitelných důvodů).

Za parametrem via určíme, které symboly ve funkci jsou parametry k dopočítání. Jinak řečeno, to, co zde uvedeme, bude chápáno jako číslo (konstanta), které je třeba vypočítat, ostatní budou proměnné. Pro názornost si ukažme jednoduchý příklad:

Nejprve si nadefinujeme vlastní funkci, třeba:

  f(x) = a * sin(b*x) + c

A touto funkcí chceme nyní proložit body v souboru mereni.dat. Přitom jediná proměnná zde má být x, ostatní jsou parametry.

  fit f(x) "mereni.dat" via a, b, c

Po spuštění tohoto příkazu proběhne výpočet (jeho průběh je vypisován na obrazovku i do souboru, viz níže) a nakonec je vypsán výsledek. Něco jako

  After 14 iterations the fit converged.
  final sum of squares of residuals : 8.24812e-31
  abs. change during last iteration : -1.08701e-28


  Hmmmm.... Sum of squared residuals is zero. Can't compute errors.

  Final set of parameters
  =======================

  a               = 1
  b               = 1.5708
  c               = -2.04925e-21

Tímto nás gnuplot informuje, že k řešení dokonvergoval po čtrnáci cyklech výpočtu, udává, jaký je celkový součet ploch čtverců (odchylka od bodů v datovém souboru), a absolutní změnu v posledním kroku iterace. Oboje jsou v tomto případě velmi, ale opravdu velmi :) malá čísla. Proto ta následující věta o tom, že gnuplot nemůže vypočítat chybu (což je samozřejmě dobře – čím menší chyba, tím lepší aproximace – v tomto případě sedla křivka přesně na zadané body). A nakonec nám říká, k jakým hodnotám parametrů vlastně algoritmus došel.

Nyní máme hodnoty parametrů a můžeme si vykreslit body z datového souboru a křivku, abychom viděli, jak vlastně výsledek vypadá:

  plot "mereni.dat", f(x)

Definice parametrů

Parametry můžeme definovat přímo za příkazem via, jak jsme si ukázali výše. Gnuplot však umožňuje použít i tzv. parametrický soubor, který má některé nezanedbatelné výhody.

Máme-li nějaké apriorní informace o řešeném problému, můžeme je zde s úspěchem využít. Mnohdy je výhodné určit počáteční hodnoty parametrů pro výpočet. Víme-li přibližně, jakou by asi měly mít hodnotu, můžeme tím výpočet mnohonásobně urychlit.

Do parametrického souboru se zapisuje každý parametr na samostatnou řádku a můžeme určit jeho počáteční hodnotu, např.

  a = 1
  b = 1.5
  c = -2

Tím jsme každému parametru určili hodnotu, ze které bude algoritmus vycházet. Implicitně by každému parametru byla přiřazena jednička, takže u parametru a jsme nemuseli hodnotu uvádět a vyšlo by to nastejno.

V parametrickém souboru nejsou dovoleny žádné komentáře. Existuje jediná výjimka potvrzující pravidlo:

  a = 1   # FIXED
  b = 1.5
  c = -2

Tímto říkáme gnuplotu, že daný parametr je pevný a nemá se s ním hýbat. Musí však být zapsán přesně touto formou (tedy ne např. #fixed), jinak je ignorován a parametr je brán jako obyčejný.

Po uložení do souboru mereni.par, bychom příkaz fit použili tímto způsobem:

  fit f(x) "mereni.dat" via "mereni.par"

Po proběhnutí výpočtu, nebo jeho části, můžeme vypočtené hodnoty parametrů uložit ve formě parametrického souboru příkazem

  update "název_souboru"

Ovlivňování výpočtu

Průběh výpočtu je vypisován na obrazovku. Podrobnější výpis je ale zároveň ukládán do souboru. Jméno a umístění souboru hledá gnuplot v proměnné FIT_LOG. Standardně je tam zapsáno ./fit.log. Toto je proměnná prostředí, nastavuje se ještě před spuštěním gnuplotu. V linuxu například příkazem

  export FIT_LOG = /tmp/fit.log

Tento soubor se nikdy nepřepisuje, ale nové informace jsou vždy ukládány na jeho konec. Má to tu výhodu, že neztrácíme informace o průběhu předchozích výpočtů, ale na druhou stranu soubor neustále narůstá. Takže si dejte pozor a pokud jej nepotřebujete (jako že skoro nikdy ne :), nezapomeňte ho smazat.

Průběh výpočtu je možno kdykoli přerušit stiskem ctrl+c. Poté, co proběhne právě prováděná iterace výpočtu, máme následující možnosti:

  • ukončit výpočet a přijmout vypočtené hodnoty parametrů
  • pokračovat ve výpočtu
  • spustit příkaz gnuplotu nastavený v proměnné FIT_SCRIPT

Proměnná FIT_SCRIPT je také proměnná prostředí a neuvedeme-li jinak, použije se příkaz replot.

Gnuplotu můžeme také říct, jakou váhu mají jednotlivé body. Využitelné je to například v případě, kdy provedeme více měření na různě přesných přístrojích. Tuto váhu udáváme jako odchylku bodu třetí hodnotou (resp. čtvrtou, pokud jsme v trojrozměrném prostoru) v datovém souboru (můžeme využít přepínač using, je-li udána jinde). Pokud ji neuvedeme, mají všechny body stejnou váhu (jedna). Při trojrozměrném modelování ji ale musíme uvést vždy. Nejčastěji použijeme

  fit f(x) "data" using 1:2:3:(1.0) via a, ...

a udáme tak stejnou váhu všech bodů.

Gnuplot používá ještě další proměnné, které ovlivňují výpočet. Před jejich modifikací je však dobré blíže se seznámit s použitým algoritmem.

Tabulka č. 185
proměnná defaultní hodnota funkce
FIT_LOG ./fit.log cesta a soubor pro logování
výpočtu
FIT_SCRIPT replot příkaz, který může být spuštěn
po přerušení výpočtu
FIT_LIMIT 1e-5 rozdíl chyb dvou po sobě jdoucích
iterací pro ukončení výpočtu
FIT_MAXITER 0 maximální počet iterací výpočtu;
0 znamená neomezeně
FIT_START_LAMBDA ML-matice počáteční hodnota proměnné
lambda
FIT_LAMBDA_FACTOR 10 konstanta násobení nebo dělení
proměnné lambda

Proměnné FIT_LOG a FIT_SCRIPT jsou, jak už bylo řečeno, proměnné prostředí a jsou nastavovány před spuštěním gnuplotu. Nejsou-li v prostředí definovány, použijí se defaultní hodnoty.

Ostatní proměnné jsou proměnné algoritmu a nastavují se až v prostředí gnuplotu. Například můžeme zapsat

UX DAy - tip 2

  FIT_MAXITER = 20

U proměnných FIT_START_LAMBDA a FIT_LAMBDA_FACTOR se nastavením hodnoty na nulu obnoví defaultní nastavení.

Závěr

Prokládání bodů křivkou je poměrně složitá matematická věda. Takže nebude-li se vám dařit dosáhnout kýženého výsledku, zkuste změnit funkci, kterou jste se rozhodli použít, nebo počáteční podmínky. Algoritmus je iterační, díky čemuž lze dokonvergovat k jinému (lepšímu) nastavení parametrů.

Byl pro vás článek přínosný?