3. Symbolické výrazy a práce s nimi#

SageMath umožňuje uživateli pracovat i se symbolickými výrazy, tedy s digitálními analogy výrazů s kterými pracujeme i na papíře. Této funkčnosti samozřejmě intenzivně využijeme při práci s výrazy a rovnicemi obsahujícími neznámou či proměnnou, při řešení rovnic, nebo počítání limit a derivací. Touto problematikou se podrobně zabývá kapitola Symbolic calculus v dokumentaci.

3.1 Symbolické proměnné a výrazy#

Nejprve je přirozeně potřeba vytvořit proměnnou, s kterou budeme pracovat. K tomu slouží funkce var.

var('x')
x

Bez této inkantace bychom dostali chybu (na rozdíl např. od prostředí Mathematica, kde vše je symbolický výraz). Máme na mysly takovouto chybu (proměnná y nyní neexistuje).

y
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [2], line 1
----> 1 y

NameError: name 'y' is not defined

Od tohoto okamžiku můžeme s x pracovat jako s proměnnou a vytvářet různorodé výrazy (expression).

expr = x^2 + sin(x) / (x^2 + 1)

show(expr)
\(\displaystyle x^{2} + \frac{\sin\left(x\right)}{x^{2} + 1}\)

Ale třeba i rovnice obsahující tuto proměnnou.

show(exp(x) == 3)
\(\displaystyle e^{x} = 3\)

Nebo nerovnice obsahující tuto proměnnou.

show((x - 1)*(x + 2) > 0)
\(\displaystyle {\left(x + 2\right)} {\left(x - 1\right)} > 0\)

K vypisování výrazů je vhodné používat funkci show, která nám výraz zobrazí pomocí LaTeXu. Bez ní bychom dostali pouze textovou reprezentaci, která v komplikovanějších případech nemusí být příliš čitelná. Srovnejte

1 / x + exp(x^2)
1/x + e^(x^2)

s

show(1 / x + exp(x^2))
\(\displaystyle \frac{1}{x} + e^{\left(x^{2}\right)}\)

Se symbolickými objekty lze dále pracovat mnoha způsoby, podrobněji se na toto téma podíváme v další sekci. Nyní ještě poznamenejme, že pod kapotou jde o instance třídy Expression.

print(type(x + 1))
print(type(x + 1 == 1))
print(type(x + 1 > 2))
<class 'sage.symbolic.expression.Expression'>
<class 'sage.symbolic.expression.Expression'>
<class 'sage.symbolic.expression.Expression'>

Python je objektový jazyk, jakého typu je takovýto symbolický výraz? Pomocí automatického doplňování sytaxe zkuste prozkoumat jeho vlastnosti (stiskněte TAB za tečkou).

# expr.

Nejjednodušším úkonem se symbolickým výrazem je pravděpodobně dosazování za proměnnou. Symbolický výraz samozřejmě může záviset i na více proměnných. Dosazovat ("substituovat") lze několika různými způsoby.

# pomocí rovnosti
show(expr(x = pi / 2))
# pomocí slovníku
show(expr({x: pi / 2}))
\(\displaystyle \frac{1}{4} \, \pi^{2} + \frac{4}{\pi^{2} + 4}\)
\(\displaystyle \frac{1}{4} \, \pi^{2} + \frac{4}{\pi^{2} + 4}\)

Poznámka: Vedle symbolických proměnných můžeme vytvářet i symbolické funkce, použijeme k tomu funkci function. Například nechť f je jistá funkce.

function('f')
f
type(f)
<class 'sage.symbolic.function_factory.function_factory.<locals>.NewSymbolicFunction'>

Takovouto funkci pak můžeme také využít v symbolických výrazech:

show(f(x + 1))
\(\displaystyle f\left(x + 1\right)\)

3.2 Jednoduché operace s výrazy#

Se symbolickými výrazy můžeme provádět základní algebraické operace, u nichž může dojít k jistému elementárnímu zjednodušení:

# součet
show(x + x)
\(\displaystyle 2 \, x\)
# násobek
show(x * x)
\(\displaystyle x^{2}\)
# dělení
show(x / (x + 1))
\(\displaystyle \frac{x}{x + 1}\)
# mocnění (a odčítání)
show(x ^ (2 - x))
\(\displaystyle x^{-x + 2}\)

Bez problémů ale můžeme používat i známé matematické funkce:

show(sin(x + 2))
\(\displaystyle \sin\left(x + 2\right)\)
show(tan(x^2))
\(\displaystyle \tan\left(x^{2}\right)\)
show(exp(x) * log(x))
\(\displaystyle e^{x} \log\left(x\right)\)

Ale například i:

show(floor(x)) # dolní celá část
\(\displaystyle \left \lfloor x \right \rfloor\)
show(factorial(x)) # faktoriál
\(\displaystyle x!\)

Úplný seznam by byl velmi dlouhý, případně experimentujte s TAB nebo prohledejte dokumentaci.

Dejte si pozor na klasický neduh počítačových algebraických systémů, následující odpověď není v pořádku. Víte proč?

x / x
1

V tomto případě je tato úprava vypadá nevinně, ale ve složitějších výpočtech nás může nepříjemně překvapit (navíc nikdy nevíte, kde jinde ještě dojde k nějaké nelegální úpravě).

3.3 Zjednodušování a složitější operace s výrazy#

SageMath, podobně jako Mathematica, umožňuje s výrazy provádět celou řadu algebraických úprav a využívat vlastnosti funkcí ve výrazu se vyskytujících. Můžeme ho proto používat na "zjednodušování výrazů". Pozor, úloha "zjednodušení" není dobře definována. Různé tvary jednoho výrazu mohou být "jednoduché" v závislosti na úhlu pohledu.

Vyvořme si jednoduchý výraz pro testování.

expr = (x + 4)^5

show(expr)
\(\displaystyle {\left(x + 4\right)}^{5}\)

Proveďme roznásobení tohoto algebraického výrazu pomocí metody expand.

expr = expr.expand()
show(expr)
\(\displaystyle x^{5} + 20 \, x^{4} + 160 \, x^{3} + 640 \, x^{2} + 1280 \, x + 1024\)

Naopak můžeme tento polynom upravit zpět na součin kořenových činitelů pomocí metody factor, která se snaží objekt rozložit na součin více objektů.

expr = expr.factor()
show(expr)
\(\displaystyle {\left(x + 4\right)}^{5}\)

Analogicky se chová i pro celá čísla.

show(12.factor())
\(\displaystyle 2^{2} \cdot 3\)

Stejným způsobem lze pracovat třeba i s trigonometrickými funkcemi.

expr = sin(4*x)

show(expr)
\(\displaystyle \sin\left(4 \, x\right)\)

Pro rozepsání výrazu ovšem nyní musíme využít metodu trig_expand. Následující úprava je v podstatě vzorec pro sinus čtyřnásobného úhlu.

expr = expr.trig_expand()

show(expr)
\(\displaystyle 4 \, \cos\left(x\right)^{3} \sin\left(x\right) - 4 \, \cos\left(x\right) \sin\left(x\right)^{3}\)

V opačnem směru pak zabere metoda trig_reduce.

expr = expr.trig_reduce()

show(expr)
\(\displaystyle \sin\left(4 \, x\right)\)

Dále máme k dispozici výstižně pojmenované metody simplify a simplify_full, které se snaží na zadaný výraz aplikovat různé úpravy a výraz tak "zjednodušit". Podívejte se i na další podobně znějící metody (TAB). Například:

expr = (1 - x) * (1 + x + x^2)

show(expr)
\(\displaystyle -{\left(x^{2} + x + 1\right)} {\left(x - 1\right)}\)
show(expr.simplify())
\(\displaystyle -{\left(x^{2} + x + 1\right)} {\left(x - 1\right)}\)
show(expr.simplify_full())
\(\displaystyle -x^{3} + 1\)

Tip: Doporučuji tyto metody využít při kontrole správnosti vašich úprav: zjednodušte rozdíl původního a vašeho výrazu, chcete dostat nulu (velmi zjednodušený výraz).

expr1 = cos(x)^2 - sin(x)^2
expr2 = cos(2 * x)
(expr1 - expr2).simplify_full()
0

3.4 Řešení (nelineárních) rovnic#

Pro řešení lineárních rovnic, což je jednoduchá úloha, má SageMath k dispozici lineárně algebraické nástroje, do kterých zde nebudeme zabíhat. Při studiu BI-MA1 nás spíše trápí různé nelineární rovnice. V tom případě je hledání jejich řešení výrazně komplikovanější úloha. Analytické, exaktní, řešení existuje typicky jen v speciálních případech. V drtivé většině případů, které se ovšem typicky nevyskytují ve školních příkladech, je nutné využít numerických metod.

Ukažme si nejprve, jak v SageMath vyřešit jednoduchou kvadratickou rovnici. Využijeme funkci solve, které předáme rovnici (případně list rovnic) a neznámou (případně list neznámých):

solve(2*x^2 + 3*x - 2 == 0, x)
[x == -2, x == (1/2)]

V příapdě úspěchu odpověď dostáváme ve formě listu s vyjádřením proměnných. To často není úplně praktické, můžeme požádat i o slovník (s kterým se pak i lépe pracuje, nebo dosazuje).

solve(2*x^2 + 3*x - 2 == 0, x, solution_dict=True)
[{x: -2}, {x: 1/2}]

Vidíme, že rovnice má dvě reálná řešení.

SageMath by si měl poradit i s jednoduchými nerovnostmi:

solve(2*x^2 + 3*x - 2 <= 0, x)
[[x >= -2, x <= (1/2)]]

nebo

solve(x * exp(x) > 0, x)
[[0 < x]]

Pokud si SageMath s úlohou neporadí, tak nám dá tautologickou odpověď:

solve(x * exp(x) > 1, x)
[[x*e^x - 1 > 0]]

Tyto dva příklady ukazují na poměrně typickou situaci: drobounká změna zadání z jednoduchého příkladu dělá neřešitelný problém (našimi aktuálními metodami).