17. Funkcje elementarne i ich własności.
Treści kształcenia. Pojęcie funkcji (intuicyjne, nie jako relacji), argumenty, wartości, dziedzina, przeciwdziedzina, zbiór wartości. Funkcje monotoniczne, wypukłe, parzyste, nieparzyste, okresowe. Iniekcje, suriekcje i bijekcje. Przegląd podstawowych funkcji elementarnych (afiniczna, kwadratowa, wykładnicza, logarytmiczna (teoria obliczeń), trygonometryczne), ich wykresy i własności.
Efekty kształcenia. Student potrafi badać i określać własności podstawowych funkcji, które napotyka w informatyce.
Po zaznajomieniu się z pojęciem funkcji oraz kluczowymi pojęciami z nim związanymi, przyjrzymy się najbardziej znanym klasom funkcji oraz ich własnościom.
Na początku zdefiniujemy trzy fundamentalne własności, które dotyczą wszystkich funkcji. Następnie zdefiniujemy pojęcia odnoszące się przede wszystkim do funkcji jednej zmiennej, działającej na zbiorach liczbowych.
Iniekcja, suriekcja, bijekcja¶
Def. Niech dana będzie funkcja .
Mówimy, że funkcja jest iniekcją (różnowartościowa), jeśli dla dowolnych elementów z faktu, że , wynika, że .
Mówimy, że funkcja jest suriekcją (“na”), jeśli . Innymi słowy, dla dowolnego istnieje taki element , że .
Mówimy, że funkcja jest bijekcją, jeśli jest ona suriekcją oraz iniekcją.
Uwaga! Często w sprawdzaniu iniektywności funkcji wykorzystuje się warunek równoważny:
Jeśli funkcja jest bijekcją, to każde z równań ma dokładnie jedno rozwiązanie. W takiej sytuacji mamy wzajemnie jednoznaczną odpowiedniość między elementami zbioru i . W szczególności, jeżeli oba zbiory są skończone, to muszą mieć taką samą liczbę elementów. Możemy ponadto zmienić “kierunek przyporządkowania”, tzn. elementom przyporządkować elementy . Otrzymujemy wtedy nową funkcję zwaną funkcją odwrotną do . Argumenty i wartości obu funkcji i spełniają zależność:
Szczególnym przykładem funkcji , dla dowolnego niepustego zbioru jest funkcja identycznościowa, tj. , dla której spełniona jest zależność:
Def. Niech oraz niech . Złożeniem (superpozycją) funkcji i nazywamy funkcję określoną wzorem
Operacja składania funkcji jest łączna, ale nie jest przemienna. Jeśli jest bijekcją, to oraz .
Bijekcje o pewnych dodatkowych własnościach często pojawiają się w matematycznych teoriach, jako funkcje przenoszące własności lub jakąś dodatkową strukturę z jednego zbioru na drugi.
Sprawdzając, czy dana funkcja jest suriekcją, badamy istnienie rozwiązań równania (ze względu na ). Przypomnijmy, że jeśli takie rozwiązania istnieją dla , to nazywamy je miejscami zerowymi funkcji .
Przykład 1¶
Funkcja dana wzorem jest funkcją różnowartościową, ale nie jest suriekcją. Istotnie z faktu, iż dla pewnych naturalnych liczb i , wynika, że , skąd z kolei wynika równość .
Gdyby przeciwdziedzinę funkcji zmienić na zbiór liczb parzystych, funkcja byłaby “na”, a tym samym byłaby także bijekcją. Wtedy , dla parzystych, byłaby funkcją do niej odwrotną.Funkcja dana jest wzorem
Sprawdźmy, bazując na definicji, czy jest ona bijekcją. Zastanówmy się, czy jest suriekcją. Musimy odpowiedzieć, czy dla każdego istnieje rozwiązanie równania . Przypuśćmy najpierw, że . Wówczas
co po przekształceniach daje
Dodając obustronnie oraz wyłączając przed nawias, dostajemy
co ostatecznie daje . Jeśli , to z definicji funkcji . Zatem funkcja jest suriekcją.
Sprawdźmy zatem, czy jest także różnowartościowa. Niech oraz . Z równości mamy
Po prostych przekształceniach otrzymujemy
co implikuje . Pozostaje sprawdzić, że dla mamy . Istotnie, równanie
jest sprzeczne, a zatem jest różnowartościowa, jest zatem bijekcją.
Monotoniczność funkcji¶
Kolejne własności dotyczyć będą funkcji, które zdefiniowane są na zbiorze liczb rzeczywistych lub jego podzbiorach. Każdy typ funkcji spośród pojawiających się niżej nazywać będziemy funkcją monotoniczną.
Def. Niech . Funkcję nazywamy:
rosnącą, jeśli dla dowolnych z faktu, że , wynika, że ,
malejącą, jeśli dla dowolnych z faktu, że , wynika, że ,
niemalejącą, jeśli dla dowolnych z faktu, że , wynika, że ,
nierosnącą, jeśli dla dowolnych z faktu, że , wynika, że .
Funkcje parzyste, nieparzyste i okresowe¶
Def. Niech . Funkcję nazywamy:
parzystą, gdy
nieparzystą, gdy
okresową, gdy
Funkcja okresowa ma nieskończenie wiele okresów. Najmniejszy z nich (o ile istnieje) nazywamy okresem podstawowym.
Funkcje elementarne¶
Dokonamy teraz przeglądu tzw. funkcji elementarnych. Omówimy te funkcje pod kątem poznanych własności.
Funkcja liniowa (afiniczna)¶
Funkcję postaci , gdzie i są pewnymi (ustalonymi) liczbami rzeczywistymi, nazywamy funkcją liniową (afiniczną). Parametr nazywamy współczynnikiem kierunkowym, zaś wyrazem wolnym. Wykresem funkcji liniowej jest linia prosta. Położenie tej linii jest ściśle określone przez i , o czym za chwilę się przekonamy.
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
def affine_function(a,b):
# 100 linearly spaced numbers
x = np.linspace(-5,5,100)
# the function, which is y = x^2 here
y = a*x + b
# setting the axes at the centre
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(1, 1, 1)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# plot the function
plt.plot(x,y, 'r')
# show the plot
plt.show()
if a:
zero = -b/ a
return zero
else:
if not b:
return 'Nieskończenie wiele miejsc zerowych'
else:
return 'Brak miejsc zerowych'affine_function(1,1) #wywołujemy kilukrotnie funkcję zmieniając wartości parametrów a i b
-1.0Przykład 2.¶
Opisać w terminach współczynników i monotoniczność funkcji liniowej .
Niech , przy czym . Wówczas
Z założenia , więc
Zatem jest rosnąca dla , malejąca dla i stała, gdy .
Analizując wzrost funkcji liniowej, nietrudno zauważyć, że jest on stały dla takiego samego wzrostu argumentu. Co więcej wynosi on dokładnie , gdzie , . Zauważmy, że stosunek jest stały i równy współczynnikowi kierunkowemu. Można zauważyć również, że liczba ta odpowiada tangensowi kąta nachylenia prostej będącej wykresem funkcji do osi .
Funkcja kwadratowa oraz wielomiany¶
Kolejną z funkcji elementarnych jest funkcja kwadratowa. Funkcje liniowa i kwadratowa są szczególnym przypadkiem funkcji wielomianowych tj. funkcji postaci
Wielomiany szczegółowo omówione zostaną w dalszej części kursu, teraz w sposób szczególny przyjrzymy się tylko funkcji kwadratowej, która jest przykładem wielomianu stopnia 2 (gdy i ).
Funkcję postaci , gdzie , , nazywamy funkcją kwadratową (trójmianem kwadratowym).
Ze szkoły dobrze pamiętamy, że wykresem funkcji kwadratowej jest linia zwana parabolą.
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
def quadratic_function(a,b,c):
# 100 linearly spaced numbers
x = np.linspace(-5,5,1000)
# the function, which is y = x^2 here
y = a*x**2 + b*x + c
# setting the axes at the centre
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(1, 1, 1)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# plot the function
plt.plot(x,y, 'r')
# show the plot
plt.show()
if a:
delta = b**2 -4*a*c
if delta > 0:
x_1 = (-b + delta ** 0.5)/ (2*a)
x_2 = (-b - delta ** 0.5)/ (2*a)
return f'Dwa pierwiastki: {round(x_1,4)} i {round(x_2,4)}, Delta dodatnia'
elif delta == 0:
x_0 = -b / (2*a)
return f'Pierwiastek podwójny: {round(x_0,4)}, Delta równa 0'
else:
return f'Brak pierwiastków, Delta ujemna'
else:
return f'Funkcja liniowa'quadratic_function(1,5,2) 
'Dwa pierwiastki: -0.4384 i -4.5616, Delta dodatnia'quadratic_function(1,1,2) 
'Brak pierwiastków, Delta ujemna'quadratic_function(-1,2,-1) 
'Pierwiastek podwójny: 1.0, Delta równa 0'Wywołując kilkukrotnie funkcję generującą wykres funkcji kwadratowej, widzimy, że gdy współczynnik jest dodatni, ramiona paraboli skierowane są w górę, gdy zaś jest ujemny, wtedy ramiona paraboli skierowane są w dół.
O funkcji kwadratowej
mówimy, że jest w postaci ogólnej.
Przykład 3¶
Spróbujmy znaleźć miejsca zerowe (jeśli istnieją) funkcji . Spróbujmy jednak postąpić nieco inaczej niż w standardowej szkolnej procedurze. Wykorzystajmy tu jeden ze wzorów - na kwadrat sumy bądź kwadrat różnicy - tak, aby “dopasować” wyrażenie do dwóch pierwszych współczynników postaci ogólnej funkcji :
Po zapisaniu równania i przeniesieniu na prawą stronę stałej otrzymujemy:
Zatem lub , skąd lub .
Kluczem do rozwiązania równania było sprowadzenie funkcji z postaci ogólnej do postaci
zwanej postacią kanoniczną. Zauważmy, że wartością najmniejszą, jaką może przyjąć funkcja , jest wartość odpowiadająca argumentowi (dlaczego?), czyli . Zatem współrzędnymi wierzchołka paraboli będącej wykresem funkcji są oraz .
quadratic_function(1,-3,2)
'Dwa pierwiastki: 2.0 i 1.0, Delta dodatnia'Gdybyśmy procedurę zamiany postaci ogólnej na kanoniczną przeprowadzili dla funkcji , dostalibyśmy wzory:
postać kanoniczna: ,
pierwiastki trójmianu: , gdy .
Z poprzednich rozważań wynika, że współrzędne wierzchołka paraboli dane są wzorami , gdzie , .
Gdy , to trójmian kwadratowy ma pierwiastki (ew. pierwiastek podwójny). Możemy “rozłożyć” go na iloczyn czynników liniowych, tj. sprowadzić do następującej postaci:
zwanej postacią iloczynową.
Zauważmy dalej, że wymnażając oba nawiasy postaci iloczynowej i porównując współczynniki przy odpowiednich potęgach do współczynników postaci ogólnej, dostajemy (gdy ) następujące wzory zwane wzorami Viete’a:
,
.
Własności funkcji kwadratowej¶
Funkcja kwadratowa nie jest funkcją monotoniczną w zbiorze liczb rzeczywistych. Możemy jednak wskazać przedziały monotoniczności tej funkcji. Wynikają one bezpośrednio z wykresu lub z analizy postaci kanonicznej. Mamy zatem dwie możliwości:
Gdy , funkcja jest malejąca w przedziale oraz jest rosnąca w przedziale .
Gdy , funkcja jest rosnąca w przedziale oraz jest malejąca w przedziale .
Wykres funkcji jest symetryczny względem prostej . Zatem nie jest różnowartościowa. Ponieważ posiada wartość największą (gdy ) bądź najmniejszą (gdy ), więc nie jest też suriekcją (gdy przeciwdziedziną jest ).
Funkcja kwadratowa nie jest nieparzysta (dlaczego?). Z kolei po sprowadzeniu do postaci kanonicznej łatwo uzasadnić, że funkcja kwadratowa jest parzysta wtedy i tylko wtedy, gdy .
Funkcja wykładnicza¶
Kolejną klasą funkcji elementarnych są funkcje wykładnicze. Dla dodatniej liczby rzeczywistej funkcję wykładniczą definiujemy wzorem
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
def power_function(a):
# 100 linearly spaced numbers
x = np.linspace(-5,5,100)
# the function, which is y = a^x here
y = a ** x
# setting the axes at the centre
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(1, 1, 1)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# plot the function
plt.plot(x,y, 'r')
# show the plot
plt.show()power_function(1.4)
power_function(0.7)
Wiemy, że , zatem wykres funkcji wykładniczej zawsze (dla dowolnego ) zawiera punkt . Ponadto wiemy, że . Oznacza to, że wykresy funkcji oraz będą symetryczne względem osi . Obrazowo zachowanie funkcji wykładniczej można opisać następująco: wraz z oddalaniem się argumentów od z jednej strony osi obserwujemy szybki, nieograniczony i przyspieszający wzrost funkcji, po drugiej zaś szybki spadek do 0.
Możemy stąd także wydedukować, że funkcja wykładnicza jest rosnąca, gdy , zaś malejąca dla . W obu przypadkach funkcja wykładnicza jest różnowartościowa oraz przeprowadza zbiór liczb rzeczywistych na zbiór liczb dodatnich. Jest więc bijekcją. Analizując przy pomocy rachunku różniczkowego wzrost funkcji wykładniczej, (dla ) oraz wielomianowej, stwierdza się, że dla odpowiednio dużych funkcja wykładnicza będzie szybciej rosła niż dowolny wielomian. Ma to istotne znaczenie przy ocenie złożoności obliczeniowej algorytmów.
Własności różnowartościowości i monotoniczności wykorzystuje się m.in. do rozwiązywania równań i nierówności wykładniczych.
Przykład 4¶
Zauważmy, że jednostkowy wzrost argumentu funkcji wykładniczej powoduje, że wartość funkcji wzrasta -krotnie. Rozważmy zagadnienie odwrotne. Spróbujmy wyznaczyć wzór takiej funkcji , że -krotny wzrost argumentu powoduje wzrost wartości o 1. Przyjmijmy dla uproszczenia, że oraz . Wówczas szukana funkcja jest funkcją odwrotną do (bijektywnej) funkcji , w przypadku której wzrost argumentu o jedność powoduje -krotny wzrost wartości. Zanim w pełni odpowiemy na pytanie, wprowadzimy kolejną klasę funkcji elementarnych.
Funkcja logarytmiczna¶
Przypomnijmy, że dla i
Liczbę nazywamy logarytmem o podstawie z liczby .
Jak pamiętamy, logarytm ma kilka ciekawych własności. Niech , .
,
,
,
,
.
Dla oraz funkcją logarytmiczną nazywamy przyporządkowanie , dla .
Zauważmy, że z własności 3 (podstawić oraz ) oraz 5 wynika, że obie funkcje oraz są funkcjami odwrotnymi, bo ich złożenia dają identyczności. W szczególności funkcja logarytmiczna jest bijekcją działającą ze zbioru na zbiór .
Na komentarz zasługuje także własność 4. Jest to tzw. wzór na zmianę podstawy logarytmu. Ma on szczególne zastosowanie z punktu widzenia programisty, gdy zaimplementowane są tylko logarytmy o wybranych podstawach.
Wróćmy do przykładu 4.
Przykład 4 cd.¶
Bez trudu możemy teraz odpowiedzieć, że szukaną funkcją jest funkcja . Istotnie, , a z własności 1 dostajemy
Przykład 4 uświadamia nam, jak “dobre” są algorytmy o logarytmicznej złożoności obliczeniowej. Jeśli algorytm ma taką złożoność, to każdy -krotny wzrost danych powoduje wzrost wartości funkcji (ilość operacji) o tę samą stałą wartość.
Przeanalizujmy wykresy funkcji logarytmicznych.
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
def logaritmic_function(a):
# 100 linearly spaced numbers
x = np.linspace(0.1,16,100)
# the function, which is y = log_a x here
y = np.log2(x)/np.log2(a)
# setting the axes at the centre
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(1, 1, 1)
# plot the function
plt.plot(x,y, 'r')
# show the plot
plt.show()
return f'Podstawa logarytmu a= {a}'logaritmic_function(2)
'Podstawa logarytmu a= 2'logaritmic_function(0.5)
'Podstawa logarytmu a= 0.5'# 100 linearly spaced numbers
a = 100
x = np.linspace(0.1,16,100)
# the function, which is y = log_a x here
y = np.log2(x)/np.log2(a)
y1 = np.log2(x)/np.log2(1/a)
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(1, 1, 1)
# plot the function
plt.plot(x,y, 'r')
plt.plot(x,y1, 'b')
ax.legend(['a>1', '0<a<1'])
# show the plot
plt.show()
Funkcje odwrotne zachowują rodzaj monotoniczności. Potwierdzają nam to wykresy obu funkcji. Zatem funkcja jest rosnąca, gdy , zaś dla jest ona malejąca. Zwróćmy uwagę, że dziedziną funkcji odwrotnej do logarytmicznej (funkcji wykładniczej) jest . Zatem zbiór wartości funkcji logarytmicznej jest nieograniczony.
Funkcje trygonometryczne¶
Funkcje trygonometryczne należą do ostatniej grupy funkcji elementarnych, które omówimy. Ponieważ poświęcimy im więcej czasu w dalszej części kursu, w tym miejscu przytoczymy definicje funkcji trygonometrycznych oraz sporządzimy ich wykresy.
Przypuśćmy, że na płaszczyźnie dany jest punkt . Wówczas półprosta przechodząca przez początek układu oraz punkt wyznacza jednoznacznie kąt skierowany pomiędzy półosią dodatnią osi a . Oznaczmy miarę łukową tego kąta przez oraz niech . Wówczas:
Funkcje trygonometryczne są funkcjami okresowymi. Okresy podstawowe funkcji sinus i cosinus wynoszą . Okresy podstawowe funkcji tangens i cotangens wynoszą .
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# 100 linearly spaced numbers
x = np.linspace(-1,1,100)
y_pos = np.sqrt(1 - x**2)
y_neg = -1 * y_pos
# setting the axes at the centre
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(1, 1, 1)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# plot the function
plt.plot(x,y_pos, 'r')
plt.plot(x,y_neg, 'r')
plt.plot([0,0.71], [0,0.71], 'b')
plt.plot([0.71, 0.71], [0, 0.71], '--', 'g')
plt.plot([0.71, 0], [0.71, 0.71], '--', 'g')
plt.scatter([0.71], [0.71], label='P(x,y)')
plt.scatter([0.71], [0], label='(x,0)')
plt.scatter([0], [0.71],label='(0,y)')
ax.legend(loc='best')
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# show the plot
plt.show()
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
# 100 linearly spaced numbers
x = np.linspace(-np.pi,np.pi,100)
# the functions, which are y = sin(x) and z = cos(x) here
y = np.sin(x)
z = np.cos(x)
# setting the axes at the centre
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# plot the functions
plt.plot(x,y, 'c', label='y=sin(x)')
plt.plot(x,z, 'm', label='y=cos(x)')
plt.legend(loc='upper left')
# show the plot
plt.show()
from mpl_toolkits.axes_grid.axislines import SubplotZero
from matplotlib.transforms import BlendedGenericTransform
import matplotlib.pyplot as plt
import numpy as np
if 1:
fig = plt.figure(1)
ax = SubplotZero(fig, 111)
fig.add_subplot(ax)
ax.axhline(linewidth=1.7, color="green")
ax.axvline(linewidth=1.7, color="green")
plt.xticks([])
plt.yticks([])
ax.text(0, 1.05, 'y', transform=BlendedGenericTransform(ax.transData, ax.transAxes), ha='center')
ax.text(1.05, 0, 'x', transform=BlendedGenericTransform(ax.transAxes, ax.transData), va='center')
for direction in ["xzero", "yzero"]:
ax.axis[direction].set_visible(True)
for direction in ["left", "right", "bottom", "top"]:
ax.axis[direction].set_visible(False)
x = np.linspace(-1.5, 1.5, 10000)
ax.plot(x, np.tan(2*(x - np.pi/2)), linewidth=1.2, color="black", label='tan x')
plt.legend()
plt.ylim(-5, 5)
from mpl_toolkits.axes_grid.axislines import SubplotZero
from matplotlib.transforms import BlendedGenericTransform
import matplotlib.pyplot as plt
import numpy as np
if 1:
fig = plt.figure(1)
ax = SubplotZero(fig, 111)
fig.add_subplot(ax)
ax.axhline(linewidth=1.7, color="black")
ax.axvline(linewidth=1.7, color="black")
plt.xticks([])
plt.yticks([])
ax.text(0, 1.05, 'y', transform=BlendedGenericTransform(ax.transData, ax.transAxes), ha='center')
ax.text(1.05, 0, 'x', transform=BlendedGenericTransform(ax.transAxes, ax.transData), va='center')
for direction in ["xzero", "yzero"]:
ax.axis[direction].set_visible(True)
for direction in ["left", "right", "bottom", "top"]:
ax.axis[direction].set_visible(False)
x = np.linspace(-1.5, 1.5, 10000)
ax.plot(x, 1/np.tan(2*(x - np.pi/2)), linewidth=1.2, color="black", label='cot x')
plt.legend()
plt.ylim(-7, 7)