2019 Sprawozdanie nr 2 APROKSYMACJA ŚREDNIOKWADRATOWA PRZEDMIOT: ALGORYTMY NUMERYCZNE ALGEBRY PROWADZĄCY: MGR KAMIL JODŹ PRZYGOTOWAŁ: MATEUSZ KRÓL 6555 TOMASZ DUDEK 6532 1 Spis treści 1. Wstęp teoretyczny ................................ ................................ ................................ .............. 2 2. Aproksymacja wielomianu drugiego stopnia ................................ ................................ ...... 5 3. Aproksymacja średniokwadratowa ................................ ................................ .................... 6 4. Metoda najmniejszych kwadratów ................................ ................................ ..................... 8 5. Omówienie wyników ................................ ................................ ................................ ........ 10 2 1. Wstęp teoretyczny Do wykonania mieliśmy dwa zadania: a) Napisać program do obliczania współczynników aproksymacji średniokwadratowej dla funkcji liniowej 𝑓 ( 𝑥 ) = 𝑎 1 𝑥 + 𝑎 0 dla zbioru n punktów { 𝑋 , 𝑌 } = { ( 𝑥 1 , 𝑦 1 ) , ( 𝑥 2 , 𝑦 2 ) , , ( 𝑥 𝑛 , 𝑦 𝑛 ) } b ) Napisać program do obliczania współczynników wielomianów stopnia p: 𝑓 ( 𝑥 ) = 𝑎 0 + 𝑎 1 𝑥 + 𝑎 2 𝑥 2 + + 𝑎 𝑝 𝑥 𝑝 z aproksymacji średniokwadratowej dla zbioru n punktów { 𝑋 , 𝑌 } = { ( 𝑥 1 , 𝑦 1 ) , ( 𝑥 2 , 𝑦 2 ) , , ( 𝑥 𝑛 , 𝑦 𝑛 ) } Dla danych znajdujących się w tabeli: 𝒙 𝒊 1,00 1,25 1,50 1,75 2,00 2,25 2,50 𝒚 𝒊 0,160 0,990 3,095 4,485 3,075 1,010 0,145 • dokonać aproks y macji średniokwadratowej za pomocą wielomianu stopnia 2, • wyznaczyć parametry funkcji 𝑓 ( 𝑥 ) = 𝑒 − ( 𝑎 0 + 𝑎 1 𝑥 + 𝑎 2 𝑥 2 ) , która w sensie metody najmniejszych kwadratów aproksymuje te dane. Programy przygot owane w sprawozdaniu zostały wykonane w środowisku Python. Wykorzystane biblioteki w celu wykonania zadań: • matplotlib.pyplot • numpy • sympy Chcąc wykonać zadania musieliśmy zaznajomić się z pojęciem aproksymacji. Czym w ogóle ona jest? Aproksymacją nazywamy procedurę zastępowania jednej funkcji (funkcja aproksymowana) inną funkcją (funkcja aproksymująca) w taki sposób, aby funkcje te niewiele się różniły w sensie określonej normy. Celem jest wyznaczenie funkcj i, która będzie przebiegała w pobliżu danych punktów. W szczególnym przypadku funkcja aproksymująca może przebiegać przez niektóre z tych punktów. 3 Przyczyny stosowania aproksymacji: - zastąpienie funkcji niedogodnej do obliczeń numerycznych inną, dogodniejszą funkcją, która będzie niewiele odbiegać od funkcji wyjściowej; z twierdzenia Weierstrassa wynika, że taką funkcją może być odpowiednio dobrany wielomian. - wyznaczenie wartości f unkcji danej dyskretnie (na skończonej liczbie punktów) w innym punkcie obszaru; - konieczność znalezienia dostatecznie gładkiej funkcji ciągłej przechodzącej w pobliżu zadanych punktów; Aproksymacja liniowa funkcji f(x) (przybliżanej) polega na wyznaczeni u współczynników 𝑎 0 , 𝑎 1 , 𝑎 2 , , 𝑎 𝑚 funkcji aproksymującej: 𝐹 ( 𝑥 ) = 𝑎 0 𝜑 0 ( 𝑥 ) + 𝑎 1 𝜑 1 ( 𝑥 ) + + 𝑎 𝑚 𝜑 𝑚 ( 𝑥 ) Gdzie: 𝜑 𝑖 ( 𝑥 ) – są funkcjami bazowymi (m+1) wymiarowej podprzestrzeni liniowej 𝑋 𝑚 + 1 ( 𝑋 𝑚 + 1 𝜖 𝑋 ) Oznaczamy: 𝐻 ( 𝑎 0 , 𝑎 1 , , 𝑎 𝑛 ) = ∑ 𝑤 ( 𝑥 ) [ 𝑓 ( 𝑥 𝑗 − ∑ 𝑎 𝑖 𝜑 𝑖 ( 𝑥 ) 𝑚 𝑖 = 0 ] 2 = ∑ 𝑤 ( 𝑥 ) 𝑅 𝑗 2 𝑛 𝑗 = 0 Gdzie: w(x) – ustalona z góry funkcja bazowa taka, że w(x) ≥ 0 dla każdego i = 0,1,2,...,n 𝑅 𝑗 − 𝑜𝑑𝑐 ℎ 𝑦𝑙𝑒𝑛𝑖𝑒 𝑤 𝑝𝑢𝑛𝑘𝑐𝑖𝑒 𝑥 𝑗 W celu znalezienia takich współczynników 𝑎 𝑘 dla których funkcja H osiąga m inimum obliczamy pochodne cząstkowe względem zmiennych 𝑎 𝑘 i przyrównujemy je do 0. 𝜑𝐻 𝜑 𝑎 𝑘 = 0 dla k = 0,1,2,...,n Otrzymujemy układ n+1 równań z n+1 niewiadomymi 𝑎 𝑘 , k = 0,1,...,n 𝜑𝐻 𝜑 𝑎 𝑘 = − 2 ∑ 𝑤 ( 𝑥 𝑗 ) [ 𝑓 ( 𝑥 𝑗 ) − ∑ 𝑎 𝑖 𝜑 𝑖 ( 𝑥 𝑖 ) 𝑛 𝑖 = 1 ] 𝜑 𝑘 ( 𝑥 𝑗 ) = 0 𝑛 𝑖 = 0 [ 1 ] Nazywamy układem normalnym. Funkcje 𝜑 𝑖 ( 𝑥 ) tworzą bazę przestrzeni 𝑋 𝑛 , zatem wyznacznik [1] jest różny od zera, co oznacza, że układ ma jednoznaczne rozwiązanie. W zapisie macierzowym układ ma postać : 𝐷 𝑇 𝐷𝐴 = 𝐷 𝑇 𝑓 [ 2 ] 4 Gdzie: 𝐷 = [ 𝜑 0 ( 𝑥 0 ) 𝜑 1 ( 𝑥 0 ) 𝜑 0 ( 𝑥 1 ) 𝜑 1 ( 𝑥 1 ) ⋯ 𝜑 𝑚 ( 𝑥 0 ) ⋯ 𝜑 𝑚 ( 𝑥 1 ) ⋮ ⋮ 𝜑 0 ( 𝑥 𝑛 ) 𝜑 1 ( 𝑥 𝑛 ) ⋱ ⋮ ⋯ 𝜑 𝑚 ( 𝑥 𝑛 ) ] 𝐴 = [ 𝑎 0 𝑎 1 ⋮ 𝑎 𝑛 ] 𝑓 = [ 𝑓 ( 𝑥 0 ) 𝑓 ( 𝑥 1 ) ⋮ 𝑓 ( 𝑥 𝑛 ) ] Macierz współczynników układu [2] jest macierzą symetryczną dodatnio określoną, co zapewnia jednoznaczność rozwiązania. Żąda m y ab y funkcja F(x) spełniała warunek ‖ 𝐹 ( 𝑥 ) − 𝑓 ( 𝑥 ) ‖ = 𝑚𝑖𝑛𝑖𝑚𝑢𝑚 Aproksymacja średniokwadratowa W aproksymacji średniokwadratowej dla funkcji f(x) określonej w przedziale <a,b> poszukujemy minimum całki: ‖ 𝐹 ( 𝑥 ) − 𝑓 ( 𝑥 ) ‖ = ∫ 𝑤 ( 𝑥 ) [ 𝑓 ( 𝑥 ) − 𝐹 ( 𝑥 ) ] 2 𝑑𝑥 𝑏 𝑎 Lub na zbiorze dyskretnym zamiast całki poszukujemy minimum sumy: ‖ 𝐹 ( 𝑥 ) − 𝑓 ( 𝑥 ) ‖ = ∑ 𝑤 ( 𝑥 𝑖 ) [ 𝑓 ( 𝑥 𝑖 ) − 𝐹 ( 𝑥 𝑖 ) ] 2 𝑛 𝑖 = 1 5 2. Aproksymacja wielomianu drugiego stopnia Dużo zależności, które spotykamy nie ma charakteru liniowego. Musimy więc znaleźć wielomian odpowiedniego stopnia, który przebiegałby moż liwie blisko wszystkich punktów, które chcemy przybliżyć. Załóżmy, że mamy wielomian drugiego stopnia 𝑝 ( 𝑥 ) = 𝑎 0 + 𝑎 1 𝑥 + 𝑎 2 𝑥 2 = 𝑦 ( 𝑥 ) Funkcja H( 𝑎 0 , 𝑎 1 , 𝑎 2 ) 𝑑𝑙𝑎 { [ ( 𝑥 𝑖 , 𝑦 𝑖 ) [ 𝑖 = 1 , 2 , , 𝑛 ] } danych ma teraz posta ć : 𝐻 ( 𝑎 0 , 𝑎 1 , 𝑎 2 ) = ∑ ( 𝑦 𝑖 − 𝑎 0 − 𝑎 1 𝑥 𝑖 − 𝑎 2 𝑥 𝑖 2 ) 2 𝑛 𝑖 = 1 A układ równań normalnych wygląda następująco: S ( 𝑎 0 , 𝑎 1 , 𝑎 2 ) 𝑎 0 = 2 ∑ ( 𝑦 𝑖 − 𝑎 0 − 𝑎 1 𝑥 𝑖 − 𝑎 2 𝑥 𝑖 2 ) ( − 1 ) = 0 𝑛 𝑖 = 1 S ( 𝑎 0 , 𝑎 1 , 𝑎 2 ) 𝑎 1 = 2 ∑ ( 𝑦 𝑖 − 𝑎 0 − 𝑎 1 𝑥 𝑖 − 𝑎 2 𝑥 𝑖 2 ) ( − 𝑥 𝑖 ) = 0 𝑛 𝑖 = 1 S ( 𝑎 0 , 𝑎 1 , 𝑎 2 ) 𝑎 2 = 2 ∑ ( 𝑦 𝑖 − 𝑎 0 − 𝑎 1 𝑥 𝑖 − 𝑎 2 𝑥 𝑖 2 ) ( − 𝑥 𝑖 2 ) = 0 𝑛 𝑖 = 1 Po uporządkowaniu otrzymamy: 𝑎 0 𝑛 + 𝑎 1 ∑ 𝑥 𝑖 𝑛 𝑖 = 1 + 𝑎 2 ∑ 𝑥 𝑖 2 𝑛 𝑖 = 1 = ∑ 𝑦 𝑖 𝑛 𝑖 = 1 𝑎 0 ∑ 𝑥 𝑖 𝑛 𝑖 = 1 + 𝑎 1 ∑ 𝑥 𝑖 2 𝑛 𝑖 = 1 + 𝑎 2 ∑ 𝑥 𝑖 3 𝑛 𝑖 = 1 = ∑ 𝑥 𝑖 𝑦 𝑖 𝑛 𝑖 = 1 𝑎 0 ∑ 𝑥 𝑖 2 𝑛 𝑖 = 1 + 𝑎 1 ∑ 𝑥 𝑖 3 𝑛 𝑖 = 1 + 𝑎 2 ∑ 𝑥 𝑖 4 𝑛 𝑖 = 1 = ∑ 𝑥 𝑖 2 𝑦 𝑖 𝑛 𝑖 = 1 Układy równań normalnych odpowiadające wielomianom aproksymacyjnym wyższych stopni rozbudowuje się w sposób analogiczny. Układy równań normalnych są układami równań liniowych, w których niewiadomymi są 𝑎 0 , 𝑎 1 , 𝑎 2 , , 𝑎 sumy różnych potęg 𝑥 𝑖 𝑘 oraz i loczynów 𝑥 𝑖 𝑘 𝑦 𝑖 grają rolę wolnych wyrazów oraz współczynników przy niewiadomych. 6 3. Aproksymacja średniokwadratowa W implementacji wykorzystano bibliotekę sympy, która umożliwia wykonywanie podstawowych operacji na macierzach, takich jak: dodawanie , odejmowanie, mnożenie, dołączenie wiersza lub kolumny, zamiana wierszy oraz obliczenie macierzy odwrotnej. Z biblioteki numpy skorzystano z funkcji zwracającej zbiór punktów, na podstawie którego rysowany będzie wykres przedstawiający przybliżaną funkcję Kolejną biblioteką jest matplotlib. Odpowiada ona za rysowanie punktów pomiarowych oraz wykresu funkcji. W programie wykorzystano układ równań macierzowych w celu wyznaczenia parametrów macierzy A. Wynikiem jego działania jest wykres funkcji wielomianu d rugiego stopnia wraz z naniesionymi pomiarami. Funkcja func() odpowiada za równanie funkcji, czyli wielomian drugiego stopnia. Jest wykorzystywana w celu wyznaczenia wartości funkcji odpowiadającym im punktom. Funkcja matrix_method() wyznacza parametry A W funkcji wykorzystano zmienną x_squared , która przechowuje poszczególne pomiary podniesione do drugiej potęgi. Następnie tworzona jest macierz współczynników D , dla wielomianu drugiego stopnia. Następnie w oparciu o macierz D , wyznaczany jest wektor param etrów A . Ostatnim krokiem jest obliczenie punktów na podstawie, których rysowany będzie wykres funkcji aproksymującej. Tabela 1 Kod źródłowy aproksymacji średniokwadratowej import matplotlib.pyplot as plt import random import numpy as np from sympy import Matrix, pprint, zeros, ones def func(A, x): return A[ 0 ] + A[ 1 ]*x + A[ 2 ]*x** 2 def matrix_method(): x = [ 1 ., 1.25 , 1.5 , 1.75 , 2 ., 2.25 , 2.5 ] x_squared = [elem ** 2 for elem in x] f = Matrix([ 0.16 , 0.99 , 3.095 , 4.485 , 3.075 , 1.01 , 0.145 ]) D = Matrix([ [ 1 , x[ 0 ], x_squared[ 0 ]], [ 1 , x[ 1 ], x_squared[ 1 ]], [ 1 , x[ 2 ], x_squared[ 2 ]], [ 1 , x[ 3 ], x_squared[ 3 ]], [ 1 , x[ 4 ], x_squared[ 4 ]], [ 1 , x[ 5 ], x_squared[ 5 ]], [ 1 , x[ 6 ], x_squared[ 6 ]] ]) DtD = D.T * D 7 A = DtD.inv() * D.T * f pprint(A) result = [] x_result = np.linspace( 1 , 2.5 , 100 ) for elem in x_result: result.append(func(A, elem)) plt.scatter(x, f, color= 'red' ) plt.plot(x_result, result) plt.show() return x_result, result if __name__ == "__main__" : matrix_method() 8 4. Metoda najmniejszych kwadratów W implementacji wykorzystano takie same biblioteki, jak w przypadku programu dla aproksymacji średniokwadratowej. Dodatkowo w celu rozwiązania układu równań skorzystano z implementacji algorytmu Gaussa, realizowanej w poprzednim sprawozdaniu. Funkcja func () odpowiada za równanie funkcji. Jest wykorzystywana w celu wyznaczenia wartości funkcji odpowiadającym im punktom. Funkcja mnk() wyznacza parametry A , dla których funkcji aproksymującej. W implementacji wykorzystano eliminację Gaussa. Pierwszym krokiem j est obliczenie macierzy na podstawie pochodnych cząstkowych. Wynikiem tego działania jest macierz, która zostanie rozwiązana przy pomocy eliminacji Gaussa, czego skutkiem będzie macierz parametrów A Posiadając taką macierz, program rysuje wykres funkcji a proksymującej oraz nanosi punkty pomiarowe. Tabela 2 Kod źródłowy metody najmniejszych kwadratów import matplotlib.pyplot as plt import math import sys import scipy.optimize import numpy as np import apro from sympy import Matrix, zeros, pprint sys.path.insert( 1 , r 'C: \ Users \ Mateusz \ wwsis_projects \ Algebra - algorytmy \ lista_1' ) from sy_gaussian import gaussian_elimination, solve def func(x, a_0, a_1, a_2): return math.exp( - (a_0 + a_1*x + a_2*x** 2 )) def mnk(): x = Matrix([ 1 ., 1.25 , 1.5 , 1.75 , 2 ., 2.25 , 2.5 ]) y = Matrix([ 0.16 , 0.99 , 3.095 , 4.485 , 3.075 , 1.01 , 0.145 ]) m = 3 n = 4 A = zeros(m, n) for row in range(m): for col in range(n): if row == 0 and col == 0 : A[row, col] = len(x) elif col != n - 1 : A[row, col] = sum([math.pow(elem, row + col) for elem in x]) else : x_to_power = Matrix([math.pow(elem, row) for elem in x]) y_ln = Matrix([math.log(elem) for elem in y]) A [row, col] = x_to_power.dot(y_ln) 9 pprint(A) gaussian_elimination(A) A = solve(A) for row in range(m): A[row] = - A[row] plot_x = np.linspace( 1 , 2.5 , 100 ) plot_y = [] plot_apro_x, plot_apro_y = apro.matrix_method() for elem in plot_x: plot_y.append(func(elem, A[ 0 ], A[ 1 ], A[ 2 ])) plt.scatter(x, y, color= 'red' ) plt.plot(plot_x, plot_y, label= 'e^( - (a0 + a1x + a2x^2))' ) plt.plot(plot_a pro_x, plot_apro_y, color= 'green' , label= 'a0 + a1x + a2x^2' ) plt.legend(loc= 'upper left' ) plt.show() if __name__ == "__main__" : mnk() 10 5. Omówienie wyników Wektor parametrów A dla metody średniokwadratowej. 𝐴 = [ − 16 85214 23 27976 − 6 65238 ] Wektor parametrów A dla metody najmniejszych kwadratów. 𝐴 = [ − 16 85395 21 016098 − 6 652381 ] W powyższym sprawozdaniu zapoznaliśmy się z pojęciem aproksymacji i działaniem metody estymacji parametrów zwanej metodą najmniejszych kwadratów. Za jej p omocą szacuje się nieznane parametry modelu, uzyskuje się oszacowania, dla których model najlepiej opisuje zaprezentowane dane. Porównując te dwie funkcje można zauważyć, że funkcja aproksymująca wyznaczona przy pomocy metody najmniejszych kwadratów znac znie lepiej wygładza i przybliża punkty pomiarowe. Wynika to z faktu mniejszego oddalenia funkcji od danych pomiarowych, co oznacza, że błąd aproksymacji jest znacznie mniejszy. Z tych powodów znacznie lepszym przybliżeniem jest funkcja 𝑒 − ( 𝑎 0 + 𝑎 1 𝑥 + 𝑎 2 𝑥 2 )