Knihovna SciPy: interpolace a aproximace

Dnes
Doba čtení: 38 minut

Sdílet

Vědec používá ke své práci počítač a Python
Autor: Root.cz s využitím Zoner AI
Techniky interpolace a aproximace se v praxi poměrně často používají, a to v mnoha oblastech, ovšem nejlépe si je můžeme vyzkoušet v případě, že je zapotřebí proložit skupinu bodů v rovině vhodnou křivkou.

Knihovna SciPy: interpolace a aproximace

Co se dozvíte v článku
  1. Knihovna SciPy: interpolace a aproximace
  2. Aproximační křivky
  3. Metoda nejmenších čtverců
  4. Lineární regrese
  5. Praktické využití lineární regrese
  6. Aproximační parametrické křivky nejenom pro počítačovou grafiku
  7. Požadované vlastnosti parametrických křivek
  8. Aproximace nebo interpolace bodů spline křivkou
  9. Ukázka aproximace bodů spline křivkou
  10. Vliv parametru lam na tvar křivky: od aproximace k interpolaci
  11. Interpolace bodů sérií kubických spline funkcí
  12. Výpočet a zobrazení křivky složené z kubických spline
  13. Výpočet a zobrazení n-té derivace křivky složené z kubických spline
  14. Rozdíl mezi křivkou vytvořenou pomocí make_smoothing_spline a CubicSpline
  15. Aproximace kružnice spline křivkami
  16. Aproximace s využitím libovolné Pythonovské funkce
  17. Aproximace přímkou a parabolou
  18. Aproximace křivkou založenou na goniometrických funkcích
  19. Repositář s demonstračními příklady
  20. Odkazy na Internetu

Ve druhém článku o knihovně SciPy se budeme zabývat problematikou interpolace a aproximace. Tyto techniky se v praxi poměrně často používají, a to v různých oblastech, ovšem nejlépe si je můžeme vyzkoušet v případě, že je zapotřebí proložit skupinu bodů v rovině nějakou vhodnou křivkou (přičemž přímka je pochopitelně speciálním případem křivky). Podle toho, zda křivka prochází všemi zadanými body, popř. zda tyto body „pouze“ ovlivňují tvar křivky, rozeznáváme křivky interpolační a aproximační.

V případě interpolačních křivek prochází vypočtená křivka předem zadanými (uzlovými) body. Typickou křivkou reprezentovanou polynomem, která do této skupiny náleží, je křivka vytvořená Lagrangeovým polynomem. Alternativně může být tato křivka složena z více oblouků (například z několika kubických spline). Naproti tomu u aproximačních křivek platí, že křivka obecně neprochází všemi zadanými uzlovými body. Příkladem takové křivky z oblasti matematiky resp. zpracování reálných dat je aproximační polynom (ve speciálním případě přímka) určený metodou nejmenších čtverců. Ovšem do této skupiny patří i křivky používané v počítačové grafice – Bézierova křivka, Coonsův oblouk, B-spline NURBS atd. Všemi těmito křivkami se pochopitelně budeme v tomto seriálu zabývat.

Obrázek 1: Parabola (tedy kuželosečka) je popsána polynomem druhého stupně.

Dnes si popíšeme aproximaci bodů přímkou (lineární regrese) a spline křivkou. Posléze si ukážeme interpolaci, a to opět spline křivkou, resp. přesněji řečeno několika na sebe navazujícími křivkami. Ovšem nezapomeneme ani na nejzajímavější techniku – aproximaci bodů libovolnou zvolenou funkcí. Může se jednat o polynom, sinusovku či o jakoukoli jinou funkci.

Poznámka: všechny dnes ukázané příklady vykreslují grafy a proto bylo nutné do projektového souboru pyproject.toml přidat i závislost na balíčku Matplotlib:
[project]
name = "scipy-lib"
version = "0.1.0"
description = "Scipy examples"
readme = "README.md"
requires-python = "==3.11.*"
dependencies = [
    "matplotlib>=3.10.8",
    "scipy>=1.17.1",
]

Aproximační křivky

Známým typem křivek, které se využívají v mnoha oborech (zdaleka tedy nejenom v počítačové grafice), jsou aproximační křivky. Tyto křivky obecně neprochází všemi zadanými body, ovšem tyto body nějakým způsobem ovlivňují tvar výsledných křivek. Typicky se jedná o křivky zadané polynomem, a to buď explicitně ve tvaru y=f(x) (proložení křivky naměřenými body, například s využitím dále zmíněné metody nejmenších čtverců) nebo parametricky ve tvaru bodové funkce x=f1(t), y=f2(t). Nejprve si ukážeme křivky zapsané explicitně a posléze se zaměříme na parametrické křivky, které jsou používány v počítačové grafice (a zhruba milion jich můžete vidět při pročítání tohoto článku, protože i znaky ve fontech jsou popsány křivkami).

Metoda nejmenších čtverců

V technické praxi (například při zpracování naměřených dat) velmi často stojíme před problémem nalezení vhodné křivky, která sice nemusí procházet přesně zadanými (změřenými) body, ale vystihuje závislost dvou veličin, jejichž hodnoty získáme měřením (popř. jedné veličiny, která se mění v čase). Tyto křivky získáváme takzvanou metodou nejmenších čtverců a nejčastěji je hledáme právě ve tvaru polynomu (relativně nízkého stupně), v tom nejjednodušším případě ve tvaru polynomu prvního stupně, tedy přímky.

Podívejme se na ilustrační příklad, ve kterém simulujeme chyby při měření veličiny. Body by měly napodobovat průběh, který je v čase je víceméně lineární. Průběh by tedy měl odpovídat lineární funkci neboli polynomu stupně jedna:

import numpy as np
 
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
x = np.arange(0, 50)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 10 * rng.random((len(x))) - 5
 
# rozměry grafu při uložení: 640x480 pixelů
fig, ax = plt.subplots(1, figsize=(6.4, 4.8))
 
# titulek grafu
fig.suptitle("Lineární regrese: úvod", fontsize=15)
 
# vrcholy na křivce
ax.plot(x, y, "go")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("random_points.png")
 
# zobrazení grafu
plt.show()

Takto by měl vypadat výsledek po spuštění příkladu:

Pseudonáhodné body měřené veličiny, jejíž průběh v čase (nebo závislost na vstupu x) je víceméně lineární.

Obrázek 2: Pseudonáhodné body měřené veličiny, jejíž průběh v čase(nebo závislost na vstupu x) je víceméně lineární. 

Autor: tisnik, podle licence: Rights Managed

Lineární regrese

V knihovně SciPy nalezneme v balíčku scipy.stats funkci nazvanou linregress, která dokáže ze zadaných vstupních dat vypočítat přímku (resp. přesněji řečeno její sklon a posun od počátku). Pro výpočet se přitom používá metoda nejmenších čtverců. Tato metoda je založena na nalezení takové přímky, ve které je součet druhých mocnin vzdáleností od naměřených bodů nejmenší a tudíž výsledná přímka v nejlepší možné míře reprezentuje předpokládaný průběh vstupní veličiny. Výsledkem volání této funkce jsou koeficienty přímky, tj. již zmíněný sklon a posun:

Help on function linregress in module scipy.stats._stats_py:
 
linregress(x, y, alternative='two-sided', *, axis=0, nan_policy='propagate', keepdims=False)
    Calculate a linear least-squares regression for two sets of measurements.
 
    Parameters
    ----------
    x, y : array_like
        Two sets of measurements.  Both arrays should have the same length N.
    alternative : {'two-sided', 'less', 'greater'}, optional
        Defines the alternative hypothesis. Default is 'two-sided'.
        The following options are available:
 
        * 'two-sided': the slope of the regression line is nonzero
        * 'less': the slope of the regression line is less than zero
        * 'greater':  the slope of the regression line is greater than zero
 
        .. versionadded:: 1.7.0
    axis : int or None, default: 0
        If an int, the axis of the input along which to compute the statistic.
        The statistic of each axis-slice (e.g. row) of the input will appear in a
        corresponding element of the output.
        If ``None``, the input will be raveled before computing the statistic.
    nan_policy : {'propagate', 'omit', 'raise'}
        Defines how to handle input NaNs.
 
        - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
          which the  statistic is computed, the corresponding entry of the output
          will be NaN.
        - ``omit``: NaNs will be omitted when performing the calculation.
          If insufficient data remains in the axis slice along which the
          statistic is computed, the corresponding entry of the output will be
          NaN.
        - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
Poznámka: nepovinnými parametry se nyní nebudeme zabývat.

Z vypočtených koeficientů přímky vytvoříme reprezentaci funkce, a to konkrétně zavoláním konstruktoru třídy numpy.poly1d:

Help on class poly1d in module numpy:
 
class poly1d(builtins.object)
 |  poly1d(c_or_r, r=False, variable=None)
 |
 |  A one-dimensional polynomial class.
 |
 |  .. note::
 |     This forms part of the old polynomial API. Since version 1.4, the
 |     new polynomial API defined in `numpy.polynomial` is preferred.
 |     A summary of the differences can be found in the
 |     :doc:`transition guide </reference/routines.polynomials>`.
 |
 |  A convenience class, used to encapsulate "natural" operations on
 |  polynomials so that said operations may take on their customary
 |  form in code (see Examples).
 |
 |  Parameters
 |  ----------
 |  c_or_r : array_like
 |      The polynomial's coefficients, in decreasing powers, or if
 |      the value of the second parameter is True, the polynomial's
 |      roots (values where the polynomial evaluates to 0).  For example,
 |      ``poly1d([1, 2, 3])`` returns an object that represents
 |      :math:`x^2 + 2x + 3`, whereas ``poly1d([1, 2, 3], True)`` returns
 |      one that represents :math:`(x-1)(x-2)(x-3) = x^3 - 6x^2 + 11x -6`.
 |  r : bool, optional
 |      If True, `c_or_r` specifies the polynomial's roots; the default
 |      is False.
 |  variable : str, optional
 |      Changes the variable used when printing `p` from `x` to `variable`
 |      (see Examples).

Celý postup je tedy snadný:

coefficients = linregress(x, y)
 
# konstrukce lineární funkce
poly1d_fn = np.poly1d([coefficients.slope, coefficients.intercept])

Praktické využití lineární regrese

Ukažme si nyní základní způsob použití funkce scipy.stats.linregress pro proložení naměřených (resp. nasimulovaných) dat přímkou, tedy polynomem stupně jedna. Jedná se o klasickou lineární regresi používanou v mnoha technických oborech:

from scipy.stats import linregress
 
import numpy as np
 
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
x = np.arange(0, 50)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 10 * rng.random((len(x))) - 5
 
# výpočet lineární regrese
coefficients = linregress(x, y)
 
# koeficienty úsečky
print("Slope:", coefficients.slope)
print("Intercept:", coefficients.intercept)
 
# konstrukce lineární funkce
poly1d_fn = np.poly1d([coefficients.slope, coefficients.intercept])
 
# rozměry grafu při uložení: 640x480 pixelů
fig, ax = plt.subplots(1, figsize=(6.4, 4.8))
 
# titulek grafu
fig.suptitle("Lineární regrese", fontsize=15)
 
# vrcholy na křivce
ax.plot(x, y, "go")
 
# vykreslení interpolační křivky
plt.plot(poly1d_fn(np.arange(0, len(x))), "r-")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("linear_regression_1.png")
 
# zobrazení grafu
plt.show()

Vypočtené parametry přímky (směrnice a posun):

Slope: 0.9675186980866821
Intercept: 1.14811922798118

Výsledek výpočtů bude vizualizován následovně:

Lineární regrese bodů, které jsou náhodně vzdáleny od úsečky se směrnicí 1.

Obrázek 3: Lineární regrese bodů, které jsou náhodně vzdáleny od úsečky se směrnicí 1 

Autor: tisnik, podle licence: Rights Managed

V případě, že je chyba měření menší, bude výsledná přímka lépe odpovídat předpokládanému průběhu:

from scipy.stats import linregress
 
import numpy as np
 
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
x = np.arange(0, 50)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 2 * rng.random((len(x))) - 1
 
# výpočet lineární regrese
coefficients = linregress(x, y)
 
# koeficienty úsečky
print("Slope:", coefficients.slope)
print("Intercept:", coefficients.intercept)
 
# konstrukce lineární funkce
poly1d_fn = np.poly1d([coefficients.slope, coefficients.intercept])
 
# rozměry grafu při uložení: 640x480 pixelů
fig, ax = plt.subplots(1, figsize=(6.4, 4.8))
 
# titulek grafu
fig.suptitle("Lineární regrese", fontsize=15)
 
# vrcholy na křivce
ax.plot(x, y, "go")
 
# vykreslení interpolační křivky
plt.plot(poly1d_fn(np.arange(0, len(x))), "r-")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("linear_regression_2.png")
 
# zobrazení grafu
plt.show()

Výsledek výpočtů:

Menší odchylky bodů v rovině.

Obrázek 4: Menší odchylky bodů v rovině 

Autor: tisnik, podle licence: Rights Managed

Pro příliš malý počet naměřených bodů nebo pro velkou chybu měření přestává lineární regrese poskytovat dostatečně kvalitní a použitelné výsledky:

from scipy.stats import linregress
 
import numpy as np
 
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
x = np.arange(0, 10)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 20 * rng.random((len(x))) - 10
 
# výpočet lineární regrese
coefficients = linregress(x, y)
 
# koeficienty úsečky
print("Slope:", coefficients.slope)
print("Intercept:", coefficients.intercept)
 
# konstrukce lineární funkce
poly1d_fn = np.poly1d([coefficients.slope, coefficients.intercept])
 
# rozměry grafu při uložení: 640x480 pixelů
fig, ax = plt.subplots(1, figsize=(6.4, 4.8))
 
# titulek grafu
fig.suptitle("Lineární regrese", fontsize=15)
 
# vrcholy na křivce
ax.plot(x, y, "go")
 
# vykreslení interpolační křivky
plt.plot(poly1d_fn(np.arange(0, len(x))), "r-")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("linear_regression_3.png")
 
# zobrazení grafu
plt.show()

Vypočtené parametry úsečky:

Slope: 0.46940694592616
Intercept: 4.316276172615453

Výsledek výpočtů:

Pro takto "rozházené" body nemá moc smysl se pokoušet provádět lineární regresi.

Pro takto "rozházené" body nemá moc smysl se pokoušet provádět lineární regresi 

Autor: tisnik, podle licence: Rights Managed

Aproximační parametrické křivky nejenom pro počítačovou grafiku

V oblasti počítačové grafiky se nejčastěji setkáme s parametrickými křivkami, tedy s křivkami, jejichž tvar je určen bodovou funkcí závislou pouze na jediném parametru t, který typicky nabývá hodnot z rozsahu 0 až 1 (ovšem může tomu být i jinak, například rozsah může být 0 až 2π atd.). Tyto křivky jsou v mnoha případech založeny na polynomech nízkých stupňů, u nichž se nevyskytují velké zákmity, lze zajistit jejich hladké napojení (jak parametrické, tak i geometrické) a navíc je jejich výpočet většinou uspokojivě rychlý. Typicky se tak setkáme s polynomy druhého a třetího stupně, neboli s kvadrikami a kubikami.

V interaktivní počítačové grafice (což je podmnožina počítačové grafiky jako celku) se nejčastěji používají polynomy třetího stupně, a to z toho důvodu, že u polynomů nižších stupňů nelze vždy zaručit podmínky napojení (C2), což však nevadí například u fontů. Kubický polynom zaručuje spojitost C1 a C2 (a samozřejmě také G1 a G2) a poskytuje tak uspokojivé modelovací možnosti. Použití polynomů vyššího stupně vede ke zvýšení časové náročnosti výpočtů, možnému vzniku numerických chyb, případně i k nežádoucím oscilacím zmíněným výše.

Jen pro připomenutí si ukažme, jakým způsobem se vlastně vykresluje parametricky zadaná křivka. Využijeme knihovnu Matplotlib:

"""Parametrická křivka: kružnice."""
 
import numpy as np
import matplotlib.pyplot as plt
 
# hodnoty parametru t
t = np.arange(0, 2*np.pi, 0.1)
 
# poloměr kružnice
r = 2.0
 
# výpočet bodů ležících na kružnici
x = r*np.cos(t)
y = r*np.sin(t)
 
# rozměry grafu při uložení: 640x480 pixelů
fig, ax = plt.subplots(1, figsize=(6.4, 4.8))
 
# titulek grafu
fig.suptitle('Kružnice', fontsize=15)
 
# určení rozsahů na obou souřadných osách
ax.set_xlim(-4, 4)
ax.set_ylim(-3, 3)
 
# vrcholy na křivce pospojované úsečkami
ax.plot(x, y, 'g-')
 
# vrcholy na křivce (každý čtvrtý)
ax.plot(x[::4], y[::4], 'ro')
 
# uložení grafu do rastrového obrázku
plt.savefig("circle.png")
 
# zobrazení grafu
plt.show()

Požadované vlastnosti parametrických křivek

Mezi často požadované vlastnosti parametrických křivek (a i pro jejich zobecnění do ploch) patří:

  1. Invariance k lineárním transformacím popř. i k perspektivní projekci. Tato vlastnost zaručuje, že lineární transformace popř. projekce aplikované na řídící body parametrické plochy má stejný výsledek, jako aplikace této transformace na každý bod vygenerované plochy. Je zřejmé, že při splnění podmínky invariance je z výkonnostního hlediska výhodnější aplikovat transformace pouze na řídící body parametrické plochy. Většina používaných aproximačních ploch podmínku invariance splňuje vzhledem k lineárním transformacím, u racionálních křivek a ploch (mezi něž patří i NURBS) je současně splněna i invariance vzhledem k perspektivní projekci. Velmi často využívané Bézierovy křivky resp. Coonsovy oblouky však nejsou invariantní vzhledem k perspektivní projekci, což ovšem v 2D grafice nevadí.
  2. Vlastnost konvexní obálky zaručuje, že všechny body vygenerované parametrické křivky či plochy leží v konvexní obálce všech svých řídících bodů. Může se použít i slabší podmínka, kde pouze část plochy leží v konvexní obálce některých řídících bodů. Pokud zaručíme tuto vlastnost, zjednoduší se velké množství algoritmů prováděných s modely těles, například test na průnik dvou těles, vytváření obalových těles nebo test průsečíku paprsku s tělesem. Bézierovy křivky i plochy leží uvnitř konvexní obálky, stejně jako Coonsovy oblouky. Totéž platí pro racionální Bézierovy plochy a křivky, ovšem za předpokladu, že jsou váhy všech řídících bodů kladné.
  3. Lokalita změn zaručuje, že se změnou polohy jednoho řídícího bodu se změní tvar jen části křivky/plochy přiléhající k tomuto řídícímu bodu, nikoli plocha celá. Tato vlastnost je důležitá především při interaktivním modelování těles pomocí parametrických ploch, protože lze dopředu odhadnout vliv editačních operací na tvar výsledné plochy. Neméně důležitá je i v interaktivní 2D grafice – proto jsou zde ostatně často nasazovány Bézierovy křivky. Tuto vlastnost nepřímo využijeme při prokládání bodů spline křivkami, což je téma navazujících kapitol.
  4. Křivka nebo plocha může procházet krajními body svého řídícího polygonu. Tuto vlastnost, která je zaručena například u Bézierových křivek a ploch, lze využít pro snadné napojování jednotlivých plátů s dodržením požadované třídy spojitosti C0, C1, G1 nebo G2. Této vlastnosti lze dosáhnout i u B-spline ploch použitím takzvaných násobných řídících bodů, tj. bodů majících stejné souřadnice v prostoru. I s touto technikou se dnes setkáme. I tuto vlastnost využijeme v demonstračních příkladech popsaných níže.

Aproximace nebo interpolace bodů spline křivkou

V knihovně SciPy nalezneme v podbalíčku scipy.interpolate velmi jednoduše použitelnou funkci nazvanou make_smoothing_spline. Tuto funkci lze použít pro výpočet koeficientů (parametrické) spline křivky, jejíž tvar bude ovlivněn vstupními body. Nutno ovšem podotknout, že křivka nemusí těmito body procházet a proto se nejedná o interpolaci, ale o aproximaci (název balíčku může být v tomto případě poněkud matoucí):

Help on function make_smoothing_spline in module scipy.interpolate._bsplines:
 
make_smoothing_spline(x, y, w=None, lam=None, *, axis=0)
    Create a smoothing B-spline satisfying the Generalized Cross Validation (GCV) criterion.
 
    Compute the (coefficients of) smoothing cubic spline function using
    ``lam`` to control the tradeoff between the amount of smoothness of the
    curve and its proximity to the data. In case ``lam`` is None, using the
    GCV criteria [1] to find it.
 
    A smoothing spline is found as a solution to the regularized weighted
    linear regression problem:
 
    .. math::
 
        \sum\limits_{i=1}^n w_i\lvert y_i - f(x_i) \rvert^2 +
        \lambda\int\limits_{x_1}^{x_n} (f^{(2)}(u))^2 d u
 
    where :math:`f` is a spline function, :math:`w` is a vector of weights and
    :math:`\lambda` is a regularization parameter.
 
    If ``lam`` is None, we use the GCV criteria to find an optimal
    regularization parameter, otherwise we solve the regularized weighted
    linear regression problem with given parameter. The parameter controls
    the tradeoff in the following way: the larger the parameter becomes, the
    smoother the function gets.

Ukázka aproximace bodů spline křivkou

V následujícím příkladu je vypočtena spline křivka aproximující vstupní body. Ovšem obecně jimi neprochází, takže se nejedná o interpolaci. Tvar křivky je pozicí bodů pouze do jisté míry ovlivněn:

from scipy.interpolate import make_smoothing_spline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
x = np.arange(0, 50)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 10 * rng.random((len(x))) - 5
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# vytvoření spline
spline = make_smoothing_spline(x, y)
 
# vykreslení křivky
plt.plot(x, spline(x), "r-", label="Spline")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("smoothing_spline_1.png")
 
# zobrazení grafu
plt.show()

A takto by měl vypadat výsledný graf:

Aproximace bodů spline křivkou

Obrázek 6: Aproximace bodů spline křivkou. 

Autor: tisnik, podle licence: Rights Managed

Body v ploše pochopitelně mohou být ještě více náhodně rozptýleny:

from scipy.interpolate import make_smoothing_spline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
x = np.arange(0, 50)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 20 * rng.random((len(x))) - 10
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# vytvoření spline
spline = make_smoothing_spline(x, y)
 
# vykreslení křivky
plt.plot(x, spline(x), "r-", label="Spline")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("smoothing_spline_2.png")
 
# zobrazení grafu
plt.show()

Nyní bude výsledek vypadat takto:

Aproximace bodů spline křivkou

Obrázek 7: Aproximace bodů spline křivkou.

Autor: tisnik, podle licence: Rights Managed

Vliv parametru lam na tvar křivky: od aproximace k interpolaci

Na tvar výsledné spline má největší vliv (samozřejmě kromě samotných bodů, které křivka aproximuje nebo interpoluje) parametr nazvaný lam. Výchozí hodnota tohoto parametru je None a značí, že se dopočítá automaticky, ovšem můžeme ho zvolit i explicitně při konstrukci spline. Může se jednat o jakékoli kladné číslo, ovšem rozumné hodnoty leží v rozsahu (0, 1>:

spline1 = make_smoothing_spline(x, y, lam=0)
spline2 = make_smoothing_spline(x, y, lam=0.5)
spline3 = make_smoothing_spline(x, y, lam=10)

Podívejme se na úplný zdrojový kód tohoto příkladu:

from scipy.interpolate import make_smoothing_spline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
x = np.arange(0, 50)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 20 * rng.random((len(x))) - 10
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# vytvoření spline
spline1 = make_smoothing_spline(x, y, lam=0)
spline2 = make_smoothing_spline(x, y, lam=0.5)
spline3 = make_smoothing_spline(x, y, lam=10)
 
x = np.arange(0, 50, 0.5)
 
# vykreslení křivky
plt.plot(x, spline1(x), "r-", label="Spline 1")
plt.plot(x, spline2(x), "g-", label="Spline 2")
plt.plot(x, spline3(x), "b-", label="Spline 2")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("smoothing_spline_3.png")
 
# zobrazení grafu
plt.show()

Povšimněte si, jak se odlišuje tvar jednotlivých spline – dokonce tak, že některé spline provádí „jen“ aproximaci a jiné interpolaci:

Aproximace a interpolace bodů různými spline křivkami

Obrázek 8: Aproximace a interpolace bodů různými spline křivkami. 

Autor: tisnik, podle licence: Rights Managed

Pro lepší náhled nad rozdíly tvarů spline je vhodnější zmenšit počet (řídicích) bodů, konkrétně v našem případě z padesáti na dvacet:

from scipy.interpolate import make_smoothing_spline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
x = np.arange(0, 20)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 20 * rng.random((len(x))) - 10
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# vytvoření spline
spline1 = make_smoothing_spline(x, y, lam=0)
spline2 = make_smoothing_spline(x, y, lam=0.5)
spline3 = make_smoothing_spline(x, y, lam=10)
 
x = np.arange(0, 20, 0.25)
 
# vykreslení křivky
plt.plot(x, spline1(x), "r-", label="Spline 1")
plt.plot(x, spline2(x), "g-", label="Spline 2")
plt.plot(x, spline3(x), "b-", label="Spline 2")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("smoothing_spline_4.png")
 
# zobrazení grafu
plt.show()

A takto bude vypadat výsledek:

Aproximace a interpolace bodů různými spline křivkami

Obrázek 9: Aproximace a interpolace bodů různými spline křivkami. 

Autor: tisnik, podle licence: Rights Managed

Interpolace bodů sérií kubických spline funkcí

V knihovně SciPy, konkrétně v modulu scipy.interpolate, nalezneme i třídu nazvanou CubicSpline. Ta slouží pro vytvoření série kubických oblouků, které na sebe hladce navazují (mají C2 spojitost). Výsledná křivka složená ze spline oblouků bude interpolovat původní sadu bodů v rovině:

Help on class CubicSpline in module scipy.interpolate._cubic:
 
class CubicSpline(CubicHermiteSpline)
 |  CubicSpline(x, y, axis=0, bc_type='not-a-knot', extrapolate=None)
 |
 |  Piecewise cubic interpolator to fit values (C2 smooth).
 |
 |  Interpolate data with a piecewise cubic polynomial which is twice
 |  continuously differentiable [1]_. The result is represented as a `PPoly`
 |  instance with breakpoints matching the given data.
 |
 |  Parameters
 |  ----------
 |  x : array_like, shape (n,)
 |      1-D array containing values of the independent variable.
 |      Values must be real, finite and in strictly increasing order.
 |  y : array_like
 |      Array containing values of the dependent variable. It can have
 |      arbitrary number of dimensions, but the length along ``axis``
 |      (see below) must match the length of ``x``. Values must be finite.
 |  axis : int, optional
 |      Axis along which `y` is assumed to be varying. Meaning that for
 |      ``x[i]`` the corresponding values are ``np.take(y, i, axis=axis)``.
 |      Default is 0.
 |  bc_type : string or 2-tuple, optional
 |      Boundary condition type. Two additional equations, given by the
 |      boundary conditions, are required to determine all coefficients of
 |      polynomials on each segment [2]_.
 |
 |      If `bc_type` is a string, then the specified condition will be applied
 |      at both ends of a spline. Available conditions are:
 |
 |      * 'not-a-knot' (default): The first and second segment at a curve end
 |        are the same polynomial. It is a good default when there is no

Výpočet a zobrazení křivky složené z kubických spline

Ukažme si nyní postup, který je nutné použít, pokud budeme chtít vypočítat a zobrazit interpolační křivku složenou z kubických spline. Zkonstruujeme instanci třídy CubicSpline. Výsledkem bude objekt, který se chová jako funkce (je volatelný, protože přetěžuje speciální metodu zajišťující tuto funkcionalitu). A jakmile máme k dispozici objekt chovající se jako funkce, můžeme ho použít při vykreslení křivky:

from scipy.interpolate import CubicSpline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
x = np.arange(0, 10)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 10 * rng.random((len(x))) - 5
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# vytvoření spline
spline = CubicSpline(x, y)
 
x = np.arange(0, 10, 0.01)
 
# vykreslení křivky
plt.plot(x, spline(x), "r-", label="Spline")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("cubic_spline_1.png")
 
# zobrazení grafu
plt.show()

Výsledná křivka bude vypadat následovně:

Interpolace deseti bodů spline křivkami

Obrázek 10: Interpolace deseti bodů spline křivkami. 

Autor: tisnik, podle licence: Rights Managed

Výpočet a zobrazení n-té derivace křivky složené z kubických spline

V některých situacích může být užitečná ještě jedna vlastnost třídy CubicSpline. Pomocí nepovinného parametru nu je možné zjistit n-tou derivaci spline. A derivace mají u křivek geometrický význam (spojitost, rychlost změny atd.). Použití je snadné:

from scipy.interpolate import CubicSpline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
x = np.arange(0, 10)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 10 * rng.random((len(x))) - 5
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# vytvoření spline
spline = CubicSpline(x, y)
 
x = np.arange(0, 10, 0.01)
 
# vykreslení křivky
plt.plot(x, spline(x), "r-", label="Spline")
plt.plot(x, spline(x, nu=1), '--', label='1st derivative')
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("cubic_spline_2.png")
 
# zobrazení grafu
plt.show()

Tento příklad po svém spuštění vykreslí jak spline, tak i její první derivaci:

Interpolace deseti bodů spline křivkami. Zobrazení první derivace křivky.

Obrázek 11: Interpolace deseti bodů spline křivkami. Zobrazení první derivace křivky. 

Autor: tisnik, podle licence: Rights Managed

Pochopitelně si můžeme nechat zobrazit i vyšší derivace:

plt.plot(x, spline(x), "r-", label="Spline")
plt.plot(x, spline(x, nu=1), '--', label='1st derivative')
plt.plot(x, spline(x, nu=2), '--', label='2nd derivative')
plt.plot(x, spline(x, nu=3), '--', label='3rd derivative')

Výsledek:

Zobrazení první až třetí derivace spline.

Obrázek 12: Zobrazení první až třetí derivace spline. 

Autor: tisnik, podle licence: Rights Managed

Poznámka: v případě třetí derivace má každý oblouk jinou hodnotu, ovšem tato hodnota je pro celý oblouk konstantní.
from scipy.interpolate import CubicSpline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
x = np.arange(0, 10)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 10 * rng.random((len(x))) - 5
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# vytvoření spline
spline = CubicSpline(x, y)
 
x = np.arange(0, 10, 0.01)
 
# vykreslení křivky
plt.plot(x, spline(x), "r-", label="Spline")
plt.plot(x, spline(x, nu=1), '--', label='1st derivative')
plt.plot(x, spline(x, nu=2), '--', label='2nd derivative')
plt.plot(x, spline(x, nu=3), '--', label='3rd derivative')
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("cubic_spline_3.png")
 
# zobrazení grafu
plt.show()

A nakonec se ještě přesvědčíme, že čtvrtá derivace kubické spline je (logicky) nulová:

from scipy.interpolate import CubicSpline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
x = np.arange(0, 10)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 10 * rng.random((len(x))) - 5
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# vytvoření spline
spline = CubicSpline(x, y)
 
x = np.arange(0, 10, 0.01)
 
# vykreslení křivky
plt.plot(x, spline(x), "r-", label="Spline")
plt.plot(x, spline(x, nu=4), '--', label='4th derivative')
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("cubic_spline_4.png")
 
# zobrazení grafu
plt.show()

Výsledek:

Čtvrtá derivace kubické spline je nulová.

Obrázek 13: Čtvrtá derivace kubické spline je nulová. 

Autor: tisnik, podle licence: Rights Managed

Rozdíl mezi křivkou vytvořenou pomocí make_smoothing_spline a CubicSpline

Název „spline“ může být matoucí, protože by se mohlo zdát, že křivky vytvořené pomocí make_smoothing_spline a CubicSpline budou totožné. Ve skutečnosti tomu tak není – jedna spline má n-tý řád zatímco druhá je tvořena kubickými oblouky. Ostatně o tom, že obě křivky mají odlišný průběh, se můžeme snadno přesvědčit jejich zobrazením do jediného grafu:

from scipy.interpolate import CubicSpline
from scipy.interpolate import make_smoothing_spline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
x = np.arange(0, 10)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 10 * rng.random((len(x))) - 5
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# vytvoření spline
spline1 = CubicSpline(x, y)
spline2 = make_smoothing_spline(x, y, lam=0)
 
x = np.arange(0, 10, 0.01)
 
# vykreslení křivek
plt.plot(x, spline1(x), "r-", label="Cubic spline")
 
plt.plot(x, spline2(x), "b-", label="Smoothing spline #1")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("comparison_1.png")
 
# zobrazení grafu
plt.show()

Z výsledného obrázku je patrné, že se obě křivky skutečně odlišují:

Rozdíly mezi kubickými křivkami a křivkou vytvořenou přes make_spline.

Obrázek 14: Rozdíly mezi kubickými křivkami a křivkou vytvořenou přes make_spline. 

Autor: tisnik, podle licence: Rights Managed

Můžeme se navíc pokusit o úpravu parametru lam, ovšem ani tak nedosáhneme shody:

from scipy.interpolate import CubicSpline
from scipy.interpolate import make_smoothing_spline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
x = np.arange(0, 10)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 10 * rng.random((len(x))) - 5
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# vytvoření spline
spline1 = CubicSpline(x, y)
spline2 = make_smoothing_spline(x, y, lam=0)
spline3 = make_smoothing_spline(x, y, lam=0.5)
spline4 = make_smoothing_spline(x, y, lam=10)
 
x = np.arange(0, 10, 0.01)
 
# vykreslení křivek
plt.plot(x, spline1(x), "r-", label="Cubic spline")
 
plt.plot(x, spline2(x), "b-", label="Smoothing spline #1")
plt.plot(x, spline3(x), "g-", label="Smoothing spline #2")
plt.plot(x, spline4(x), "y-", label="Smoothing spline #3")
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("comparison_2.png")
 
# zobrazení grafu
plt.show()
Rozdíly mezi kubickými křivkami a křivkou vytvořenou přes make_spline.

Obrázek 15: Rozdíly mezi kubickými křivkami a křivkou vytvořenou přes make_spline. 

Autor: tisnik, podle licence: Rights Managed

Aproximace kružnice spline křivkami

Prozatím jsme třídu CubicSpline používali pro proložení bodů, které například vznikly měřením a jejich x-ové souřadnice se tedy odlišují o pevně daný offset. Ovšem naprosto stejným postupem můžeme namísto y-ových souřadnic předat dvojice [x, y] a nechat si tak propojit body, které jsou v rovině rozmístěny naprosto libovolným způsobem. Namísto původních x-ových souřadnic se v tomto případě předávají hodnoty parametru t – přecházíme tedy do oblasti klasických parametrických křivek.

Pokusme se aproximovat kružnici pomocí čtveřice oblouků kubické spline. Pokusíme se propojit body ležící na čtyřech místech na kružnici (sever, jih, západ, východ). Navíc bude křivka uzavřena a „periodická“:

from scipy.interpolate import CubicSpline
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
# hodnoty na x-ové ose
pts = np.array([[-1, 0],
       [0, 1],
       [1, 0],
       [0, -1],
       [-1, 0]])
 
t = np.arange(0, 5)
 
xs = np.linspace(0, 4, 100)
 
# vytvoření spline
spline = CubicSpline(t, pts, bc_type="periodic")
 
# rozměry grafu při uložení: 640x640 pixelů
fig, ax = plt.subplots(1, figsize=(6.4, 6.4))
 
# vykreslení bodů
ax.plot(pts[:, 0], pts[:, 1], 'o', label="data")
 
xs = np.linspace(0, 6.28, 100)
 
# vykreslení kružnice
ax.plot(np.cos(xs), np.sin(xs), "b-", label="circle");
 
# vykreslení křivky
ax.plot(spline(xs)[:, 0], spline(xs)[:, 1], "r-", label='spline')
 
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("cubic_spline_5.png")
 
# zobrazení grafu
plt.show()

Výsledek:

Aproximace kružnice spline křivkou.

Obrázek 16: Aproximace kružnice pomocí čtyř kubických spline oblouků. 

Autor: tisnik, podle licence: Rights Managed

Aproximace s využitím libovolné Pythonovské funkce

Poslední vlastností knihovny SciPy, kterou se dnes budeme zabývat, je technika, která se používá pro aproximaci bodů s využitím libovolné Pythonovské funkce. Může se jednat o funkci lineární, logaritmickou, goniometrickou, či o libovolný polynom. K tomuto účely slouží funkce nazvaná curve_fit, kterou ovšem nenajdeme v balíčku scipy.interpolate, ale scipy.optimize:

Help on function curve_fit in module scipy.optimize._minpack_py:
 
curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=None, bounds=(-inf, inf), method=None, jac=None, *, full_output=False, nan_policy=None, **kwargs)
    Use non-linear least squares to fit a function, f, to data.
 
    Assumes ``ydata = f(xdata, *params) + eps``.
 
    Parameters
    ----------
    f : callable
        The model function, f(x, ...). It must take the independent
        variable as the first argument and the parameters to fit as
        separate remaining arguments.
    xdata : array_like
        The independent variable where the data is measured.
        Should usually be an M-length sequence or an (k,M)-shaped array for
        functions with k predictors, and each element should be float
        convertible if it is an array like object.
    ydata : array_like
        The dependent data, a length M array - nominally ``f(xdata, ...)``.
    p0 : array_like, optional
        Initial guess for the parameters (length N). If None, then the
        initial values will all be 1 (if the number of parameters for the
        function can be determined using introspection, otherwise a
        ValueError is raised).
    sigma : None or scalar or M-length sequence or MxM array, optional
        Determines the uncertainty in `ydata`. If we define residuals as
        ``r = ydata - f(xdata, *popt)``, then the interpretation of `sigma`
        depends on its number of dimensions:

Aproximace přímkou a parabolou

V dalším demonstračním příkladu se pokusíme o aproximaci sady bodů přímkou (tedy o lineární regresi). Použijeme přitom funkci, která skutečně dokáže vypočítat body na přímce se sklonem a a posunem b:

def func(x, a, b):
    return a * x + b

Příklad bude vypadat takto:

from scipy.optimize import curve_fit
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
def func(x, a, b):
    return a * x + b
 
 
# hodnoty na x-ové ose
x = np.arange(0, 50)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y = x + 10 * rng.random((len(x))) - 5
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# výpočet koeficientů a a b
popt, pcov = curve_fit(func, x, y)
 
# koeficienty úsečky
print("Slope:", popt[0])
print("Intercept:", popt[1])
 
# vykreslení křivky prokládající body
plt.plot(x, func(x, *popt), "r-", label="fit: a=%5.3f, b=%5.3f" % tuple(popt))
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("curve_fit_1.png")
 
# zobrazení grafu
plt.show()

Výsledek:

Aproximace bodů přímkou

Obrázek 17: Aproximace bodů přímkou. 

Autor: tisnik, podle licence: Rights Managed

Ovšem stejně dobře lze provést aproximaci parabolou, tedy funkcí:

def func(x, a, b, c):
    return a * x**2 + b*x + c

Upravený kód příkladu:

from scipy.optimize import curve_fit
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
def func(x, a, b, c):
    return a * x**2 + b*x + c
 
 
# hodnoty na x-ové ose
x = np.linspace(0, 4, 50)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y_orig = func(x, 1.0, -1.5, 0.5)
y_noise = 0.2 * rng.normal(size=x.size)
y = y_orig + y_noise
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# výpočet koeficientů a a b
popt, pcov = curve_fit(func, x, y)
 
# vykreslení křivky prokládající body
plt.plot(x, func(x, *popt), "r-", label="fit: a=%5.3f, b=%5.3f, c=%5.3f" % tuple(popt))
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("curve_fit_2.png")
 
# zobrazení grafu
plt.show()

Výsledek:

Školení Zabbix

Aproximace bodů parabolou

Obrázek 18: Aproximace bodů parabolou. 

Autor: tisnik, podle licence: Rights Managed

Aproximace křivkou založenou na goniometrických funkcích

Můžeme ovšem provést i složitější aproximaci, například nějakou funkcí založenou na goniometrických funkcích (a tedy popř. i na funkci periodické). Dnes již poslední demonstrační příklad je zvolený tak, aby do určité míry napodobil základní myšlenku Fourierovy transformace:

def func(x, a, b, c):
    return a * np.sin(x) + b * np.sin(2 * x) + c
from scipy.optimize import curve_fit
 
import numpy as np
 
import matplotlib.pyplot as plt
 
 
def func(x, a, b, c):
    return a * np.sin(x) + b * np.sin(2 * x) + c
 
 
# hodnoty na x-ové ose
x = np.linspace(0, 4, 50)
 
# generátor pseudonáhodných dat
rng = np.random.default_rng(seed=42)
 
# hodnoty na y-ové ose
y_orig = func(x, 1.0, -1.5, 0.5)
y_noise = 0.2 * rng.normal(size=x.size)
y = y_orig + y_noise
 
# vykreslení bodů
plt.plot(x, y, "go", label="data")
 
# výpočet koeficientů a a b
popt, pcov = curve_fit(func, x, y)
 
# vykreslení křivky prokládající body
plt.plot(x, func(x, *popt), "r-", label="fit: a=%5.3f, b=%5.3f, c=%5.3f" % tuple(popt))
 
# popis os a legenda
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
 
# uložení grafu do rastrového obrázku
plt.savefig("curve_fit_3.png")
 
# zobrazení grafu
plt.show()

Výsledek může vypadat takto:

Aproximace bodů goniometrickou funkcí

 Obrázek 19: Aproximace bodů funkcí odvozenou od goniometrických funkcí.

Autor: tisnik, podle licence: Rights Managed

Repositář s demonstračními příklady

# Příklad Stručný popis Adresa příkladu
1 pyproject.toml projektový soubor používaný všemi demonstračními příklady https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/pyproject.toml
       
2 help.py zobrazení nápovědy k celé knihovně SciPy https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/help.py
3 help_linalg.py zobrazení nápovědy k modulu linalg, který je součástí SciPy https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/help_linalg.py
       
4 determinant0.py nápověda k funkci linalg.det https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/determinant0.py
5 determinant1.py výpočet determinantu běžné regulární matice https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/determinant1.py
6 determinant2.py výpočet determinantu nulové matice https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/determinant2.py
7 determinant3.py výpočet determinantu singulární matice https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/determinant3.py
8 determinant4.py výpočet determinantu v oboru komplexních čísel https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/determinant4.py
9 determinant5.py výpočet determinantu singulární matice v oboru komplexních čísel https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/determinant5.py
       
10 inverse0.py nápověda k funkci linalg.inv https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/inverse0.py
11 inverse1.py výpočet inverzní matice https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/inverse1.py
12 inverse2.py výpočet inverzní matice k nulové matici https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/inverse2.py
13 inverse3.py výpočet inverzní matice k singulární matici https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/inverse3.py
14 inverse4.py výpočet inverzní matice v oboru komplexních čísel https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/inverse4.py
       
15 matrix_mul.py maticový součin založený na operátoru @ definovaného v NumPy https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/matrix_mul.py
16 matrix_mul_inv.py důkaz, že byla vypočtena korektní inverzní matice https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/matrix_mul_inv.py
17 matrix_mul_inv2.py důkaz, že byla vypočtena korektní inverzní matice v oboru komplexních čísel https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/matrix_mul_inv2.py
       
18 solve0.py zobrazení nápovědy k funkci linalg.solve https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/solve0.py
19 solve1.py vyřešení triviálního případu: jedna rovnice o jedné neznámé https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/solve1.py
20 solve2.py vyřešení systému dvou lineárních rovnic o dvou neznámých https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/solve2.py
21 solve3.py vyřešení systému tří lineárních rovnic o třech neznámých https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/solve3.py
22 solve4.py situace, která nastane, pokud je nějaká rovnice lineární kombinací jiných rovnic https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/solve4.py
23 solve5.py situace, která nastane, pokud je nějaká rovnice lineární kombinací jiných rovnic https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/solve5.py
       
20 vector_norm0.py zobrazení nápovědy k funkci linalg.norm https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/vector_norm0.py
21 vector_norm1.py výpočet výchozí normy vektoru (Eukleidovská vzdálenost) https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/vector_norm1.py
22 vector_norm2.py výpočet dalších norem vektoru https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/vector_norm2.py
       
23 matrix_norm1.py výpočet norem matice: maximová a minimová norma https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/matrix_norm1.py
24 matrix_norm2.py výpočet norem matice: největší a nejmenší hodnota pro Eukleidovské vzdálenosti https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/matrix_norm2.py
25 matrix_norm3.py výpočet norem matice: největší a nejmenší hodnota pro Eukleidovské vzdálenosti https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/matrix_norm3.py
26 matrix_norm4.py výpočet norem matice: Frobeniův skalární součin https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/matrix_norm4.py
       
27 random_points.py pseudonáhodně rozmístěné body v rovině https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/random_points.py
       
28 linear_regression0.py nápověda k funkci scipy.stats.linregres https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/linear_regression0.py
29 linear_regression1.py lineární regrese pro body náhodně rozmístěné okolo úsečky https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/linear_regression1.py
30 linear_regression2.py lineární regrese, ovšem s body, které jsou blíže úsečce https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/linear_regression2.py
31 linear_regression3.py lineární regrese, ovšem s body zcela náhodně rozmístěnými po ploše https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/linear_regression3.py
       
32 cubic_spline0.py nápověda ke třídě scipy.interpolate.CubicSpline https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/cubic_spline0.py
33 cubic_spline1.py konstrukce a zobrazení kubické spline křivky https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/cubic_spline1.py
34 cubic_spline2.py konstrukce a zobrazení kubické spline křivky i její první derivace https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/cubic_spline2.py
35 cubic_spline3.py konstrukce a zobrazení kubické spline křivky i její první, druhé a třetí derivace https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/cubic_spline3.py
36 cubic_spline4.py čtvrtá derivace kubické spline křivky je nulová https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/cubic_spline4.py
37 cubic_spline5.py aproximace kružnice https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/cubic_spline5.py
       
38 smoothing_spline0.py nápověda k funkci scipy.interpolate.make_smo­othing_spline https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/smoothing_spline0.py
39 smoothing_spline1.py proložení bodů křivkou https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/smoothing_spline1.py
40 smoothing_spline2.py proložení bodů křivkou, větší rozptyl bodů https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/smoothing_spline2.py
41 smoothing_spline3.py nastavení různých parametrů křivky (větší počet bodů) https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/smoothing_spline3.py
42 smoothing_spline4.py nastavení různých parametrů křivky (menší počet bodů) https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/smoothing_spline4.py
       
43 curve_fit0.py nápověda k funkci scipy.optimize.curve_fit https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/curve_fit0.py
44 curve_fit1.py proložení bodů přímkou https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/curve_fit1.py
45 curve_fit2.py proložení bodů parabolou https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/curve_fit2.py
46 curve_fit3.py proložení bodů sinusovkou https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/curve_fit3.py
       
47 comparison1.py porovnání kubické spline a „smoothing spline“ https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/comparison1.py
48 comparison2.py porovnání kubické spline a „smoothing spline“ https://github.com/tisnik/most-popular-python-libs/blob/master/scipy-lib/comparison2.py

Odkazy na Internetu

  1. SciPy homepage
    https://scipy.org/
  2. SciPy (Wikipedia)
    https://en.wikipedia.org/wiki/SciPy
  3. The Hertzsprung–Russell diagram
    https://scipython.com/book2/chapter-9-data-analysis-with-pandas/problems/p92/the-hertzsprung-russell-diagram/
  4. Linear algebra (scipy.linalg)
    https://docs.scipy.org/doc/sci­py/reference/linalg.html
  5. Frequently Asked Questions – SciPy
    https://scipy.org/faq/
  6. SciPy – Introduction
    https://www.tutorialspoin­t.com/scipy/scipy_introduc­tion.htm
  7. LAPACK — Linear Algebra PACKage
    https://www.netlib.org/lapack/
  8. LAPACK (Wikipedia)
    https://en.wikipedia.org/wiki/LAPACK
  9. LAPACK na GitHubu
    https://github.com/Reference-LAPACK/lapack
  10. SciPy in Python
    https://pythonguides.com/scipy/
  11. scipy.linalg.det
    https://docs.scipy.org/doc/sci­py/reference/generated/sci­py.linalg.det.html#scipy.li­nalg.det
  12. scipy.linalg.inv
    https://docs.scipy.org/doc/sci­py/reference/generated/sci­py.linalg.inv.html#scipy.li­nalg.inv
  13. scipy.linalg.solve
    https://docs.scipy.org/doc/sci­py/reference/generated/sci­py.linalg.inv.html#scipy.li­nalg.inv
  14. Algebra
    https://cs.wikipedia.org/wiki/Algebra
  15. Lineární algebra
    https://cs.wikipedia.org/wi­ki/Line%C3%A1rn%C3%AD_alge­bra
  16. Lineární rovnice
    https://cs.wikipedia.org/wi­ki/Line%C3%A1rn%C3%AD_rov­nice
  17. Soustava lineárních rovnic
    https://cs.wikipedia.org/wi­ki/Soustava_line%C3%A1rn%C3%AD­ch_rovnic
  18. Norma matice
    https://cs.wikipedia.org/wi­ki/Norma_matice
  19. Matrix norm
    https://en.wikipedia.org/wi­ki/Matrix_norm
  20. Norma (vektoru)
    https://cs.wikipedia.org/wi­ki/Norma_(matematika)
  21. Frobeniův skalární součin
    https://cs.wikipedia.org/wi­ki/Frobeni%C5%AFv_skal%C3%A1rn%C3%AD_sou­%C4%8Din
  22. BLAS (Basic Linear Algebra Subprograms)
    https://www.netlib.org/blas/
  23. Basic Linear Algebra Subprograms (Wikipedia)
    https://en.wikipedia.org/wi­ki/Basic_Linear_Algebra_Sub­programs
  24. Operace s daty uloženými v binárních souborech v knihovnách NumPy a Pandas
    https://www.root.cz/clanky/operace-s-daty-ulozenymi-v-binarnich-souborech-v-knihovnach-numpy-a-pandas/
  25. Operace s daty uloženými v binárních souborech v knihovnách NumPy a Pandas (dokončení)
    https://www.root.cz/clanky/operace-s-daty-ulozenymi-v-binarnich-souborech-v-knihovnach-numpy-a-pandas-dokonceni/
  26. NumPy Home Page
    http://www.numpy.org/
  27. NumPy v1.10 Manual
    http://docs.scipy.org/doc/num­py/index.html
  28. NumPy (Wikipedia)
    https://en.wikipedia.org/wiki/NumPy
  29. OpenBLAS: An optimized BLAS library
    https://www.openblas.net/
  30. Integrovaná vývojová prostředí ve Fedoře: IPython a IPython Notebook
    http://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-ipython-a-ipython-notebook/
  31. Integrovaná vývojová prostředí ve Fedoře: praktické použití IPython Notebooku a knihovny Numpy
    http://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-prakticke-pouziti-ipython-notebooku-a-knihovny-numpy/
  32. Integrovaná vývojová prostředí ve Fedoře: praktické použití IPython Notebooku a knihovny Numpy (2.část)
    http://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-prakticke-pouziti-ipython-notebooku-a-knihovny-numpy-2-cast/
  33. Integrovaná vývojová prostředí ve Fedoře: vykreslování grafů s využitím knihoven Numpy a matplotlib
    http://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-vykreslovani-grafu-s-vyuzitim-knihoven-numpy-a-matplotlib/
  34. Integrovaná vývojová prostředí ve Fedoře: vykreslování grafů s využitím knihoven Numpy a matplotlib (2.část)
    http://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-vykreslovani-grafu-s-vyuzitim-knihoven-numpy-a-matplotlib-2-cast/
  35. Piecewise linear interpolation
    https://docs.scipy.org/doc//sci­py/tutorial/interpolate/1D­.html
  36. Statistical functions (scipy.stats)
    https://docs.scipy.org/doc/sci­py/reference/stats.html
  37. scipy.stats.linregress
    https://docs.scipy.org/doc/sci­py/reference/generated/sci­py.stats.linregress.html
  38. numpy.poly1d
    https://numpy.org/doc/sta­ble/reference/generated/num­py.poly1d.html
  39. scipy.optimize.curve_fit
    https://docs.scipy.org/doc/sci­py/reference/generated/sci­py.optimize.curve_fit.html#sci­py.optimize.curve_fit
  40. scipy.interpolate.make_smoothing_spline
    https://docs.scipy.org/doc/sci­py/reference/generated/sci­py.interpolate.make_smoot­hing_spline.html#scipy.in­terpolate.make_smoothing_spli­ne
  41. Famous Curves Index
    https://mathshistory.st-andrews.ac.uk/Curves/
  42. Curve (Wikipedia)
    https://en.wikipedia.org/wiki/Curve
  43. Mathematical curves
    https://www.2dcurves.com/index.html
  44. Curves (Wolfram MathWorld)
    https://mathworld.wolfram­.com/topics/Curves.html
  45. Smooth Curve (Wolfram MathWorld)
    https://mathworld.wolfram­.com/SmoothCurve.html
  46. Spirals (Wolfram MathWorld)
    https://mathworld.wolfram­.com/topics/Spirals.html
  47. An Interactive Introduction to Splines
    https://ibiblio.org/e-notes/Splines/Intro.htm
  48. Algebraic curve
    https://en.wikipedia.org/wi­ki/Algebraic_curve
  49. Transcendental curve
    https://en.wikipedia.org/wi­ki/Transcendental_curve
  50. Algebraic Curves
    https://mathworld.wolfram­.com/topics/AlgebraicCurves­.html
  51. Elliptic Curves
    https://mathworld.wolfram­.com/topics/EllipticCurves­.html
  52. Curves we (mostly) don't learn in high school (and applications)
    https://www.youtube.com/wat­ch?v=3izFMB91K_Q
  53. Catenary arch
    https://en.wikipedia.org/wi­ki/Catenary_arch
  54. Parabolic arch
    https://en.wikipedia.org/wi­ki/Parabolic_arch
  55. Wattova křivka
    https://www.geogebra.org/m/gNh4bW9r
  56. Fifty Famous Curves, Lots of Calculus Questions, And a Few Answers
    https://elepa.files.wordpres­s.com/2013/11/fifty-famous-curves.pdf
  57. Faux, I.D. a Pratt, M.J.: Computational Geometry for Design and Manufacture,
    Ellis Horwood Ltd., Wiley & Sons, 1979
  58. Wallace A.: Differential Topology,
    Benjamin/Cummings Co., Reading, Massachussetts, USA, 1968
  59. Glossary of Bridge Terminology
    http://sdrc.lib.uiowa.edu/en­g/bridges/WaddellGlossary/Glos­sC.htm
  60. Brachistochrona
    https://cs.wikipedia.org/wi­ki/Brachistochrona
  61. Missions: Cassini
    https://solarsystem.nasa.gov/mis­sions/cassini/overview/
  62. Giovanni Domenico Cassini
    https://en.wikipedia.org/wi­ki/Giovanni_Domenico_Cassi­ni
  63. Cassini Ovals
    https://mathworld.wolfram­.com/CassiniOvals.html
  64. Geocentrismus
    https://cs.wikipedia.org/wi­ki/Geocentrismus
  65. Who was Giovanni Cassini?
    https://www.universetoday­.com/130823/who-was-giovanni-cassini/
  66. Special plane curves
    http://xahlee.info/Special­PlaneCurves_dir/ConicSecti­ons_dir/conicSections.html
  67. Interpolace
    https://mathonline.fme.vut­br.cz/pg/Algoritmy/05_APROX_KRIV­KY.htm
  68. Lagrange Polynomial Interpolation
    https://pythonnumericalmet­hods.berkeley.edu/notebook­s/chapter17.04-Lagrange-Polynomial-Interpolation.html
  69. Python Program for Lagrange Interpolation Method (with Output)
    https://www.codesansar.com/numerical-methods/python-program-lagrange-interpolation-method.htm
  70. Smooth Paths Using Catmull-Rom Splines
    https://qroph.github.io/2018/07/30/smo­oth-paths-using-catmull-rom-splines.html
  71. Lecture 11: Linear Interpolation Again – Bézier Curves
    http://www.math.kent.edu/~re­ichel/courses/intr.num.com­p.1/fall09/lecture12/bez.pdf
  72. Geometrie/Úvod do křivek
    https://cs.wikibooks.org/wi­ki/Geometrie/%C3%9Avod_do_k%C5%99i­vek
  73. B-Spline Curves and Surfaces (1)
    http://www.cad.zju.edu.cn/ho­me/zhx/GM/006/00-bscs1.pdf
  74. Praktické ukázky možností aplikace Mandelbulber při tvorbě animací
    https://www.root.cz/clanky/prakticke-ukazky-moznosti-aplikace-mandelbulber-pri-tvorbe-animaci/
  75. Kochanek–Bartels spline
    https://en.wikipedia.org/wi­ki/Kochanek%E2%80%93Bartel­s_spline
  76. class KochanekBartels
    https://splines.readthedoc­s.io/en/latest/_modules/spli­nes.html#KochanekBartels

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.



Nejnovější články