12
AST416 Astronomide Sayısal Çözümleme - II 3. Python'da Interpolasyon

A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

  • Upload
    others

  • View
    13

  • Download
    0

Embed Size (px)

Citation preview

Page 1: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

AST416 Astronomide Sayısal Çözümleme - II

3. Python'da Interpolasyon

Page 2: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

scipy.Interpolate Modülü ile İnterpolasyon1 Boyutlu İnterpolasyon: interp1d

__call__ metodu y = f(x) şeklinde bir fonksiyon için (x,y) ikililerinin interpolasyonu sonucu her iki veri

noktasının arasına uyarlanan bir doğru şekilnde bir fonksiyon döndüren bir sınıftır.

>>> import matplotlib.pyplot as plt>>> import numpy as np>>> from scipy import interpolate>>> x = np.arange(0,10)>>> y = np.exp(-x/3.0) # y = e^-3>>> f = interpolate.interp1d(x,y)>>> xyeni = np.arange(0,9,1)>>> yyeni = f(xyeni)>>> plt.plot(x,y,'o')>>> plt.plot(xyeni,yyeni,'-')>>> plt.show()

Page 3: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

Aksi söyllenmediği takdirde fonksiyon, veri noktaları arasında birer doğru uyumlayacak şekilde oluşturulur. Eğer

“kind” parametresi “cubic” şekilde belirlenmişse bu kez noktaların arasına 3. dereceden birer polinom

ayarlanır. Bu yapısıyla fonksiyon gerçekte lineer ya da kübik spline interpolasyonu uygulamaktadır.

>>> from matplotlib import pyplot as plt>>> import numpy as np>>> from scipy.interpolate import interp1d>>> x = np.linspace(0, 10, 11, endpoint=True)>>> y = np.cos(-x**2/9.0)>>> f1 = interp1d(x,y)>>> f2 = interp1d(x,y,kind='cubic')>>> xyeni = np.linspace(0, 10, 41, endpoint=True)>>> y1 = f1(xyeni)>>> y2 = f2(xyeni)>>> plt.plot(x, y, 'o', xyeni, y1, '-', xyeni, y2, '–')>>> plt.legend(['veri', 'dogrusal', 'kubik'], loc = 'best')>>> plt.plot>>> plt.show()

Page 4: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

fonksiyonunun [0, 1] x [0, 1] gridindeki çok sayıda nokta için interpolasyonunu hesaplayalım. Fonksiyonun

değerini bu griddeki 1000 nokta için bildiğimizi varsayalım.

scipy.Interpolate Modülü ile İnterpolasyonÇok Boyutlu İnterpolasyon: griddata (opsiyonel)

>>> import numpy as np>>> def fonk(x, y):... return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2>>> grid_x, grid_y = np.mgrid[0:1:100j, 0:1:200j]

>>> noktalar = np.random.rand(1000, 2)>>> degerler = fonk(noktalar[:,0], noktalar[:,1])

Bu noktalardan yola çıkarak sınıfın tüm metodlarının yardımıyla interpole değerleri bulalım ve grafiğini çizdiirelim.

>>> from scipy.interpolate import griddata>>> grid_z0 = griddata(noktalar, degerler, (grid_x, grid_y), method='nearest')>>> grid_z1 = griddata(noktalar, degerler, (grid_x, grid_y), method='linear')>>> grid_z2 = griddata(noktalar, degerler, (grid_x, grid_y), method='cubic')

>>> import matplotlib.pyplot as plt>>> plt.subplot(221)>>> plt.imshow(fonk(grid_x, grid_y).T, extent=(0,1,0,1), origin='lower')>>> plt.plot(noktalar[:,0], noktalar[:,1], 'k.', ms=1)>>> plt.title('Veri')>>> plt.subplot(222)>>> plt.imshow(grid_z0.T, extent=(0,1,0,1), origin='lower')>>> plt.title('En Yakin')>>> plt.subplot(223)>>> plt.imshow(grid_z1.T, extent=(0,1,0,1), origin='lower')>>> plt.title('Dogrusal')>>> plt.subplot(224)>>> plt.imshow(grid_z2.T, extent=(0,1,0,1), origin='lower')>>> plt.title('Kubik')>>> plt.gcf().set_size_inches(6, 6)>>> plt.show()

Page 5: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı
Page 6: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

Yapısal (Procedural) Spline İnterpolasyonu

Yapısal spline interpolasyonu iki adımda gerçekleştirilir: i) verinin spline interpolasyonu ile temsili

oluşturulur, ii) istenen noktalarda spline interpolasyonu hesabı yapılır. Spline temsili için gereken

katsayılar doğrudan ya da parametrik olarak elde edilebilir. Verinin doğrudan spline temsili

(katsayıların hesabı) splrep fonksiyonu ile gerçekleştirilir. Fonksiyona verinin x,y noktaları geçirilir;

fonksiyon t: düğüm noktalarını, c: katsayıları, k: spline derecesini göstermek üzere (t, c, k) demet

değişkenini döndürür. Varsayılan spline derecesi kübiktir ancak istenirse k parametresi ile

değişitirilebilir.

N-boyutlu uzayda veri splprep fonksiyonu ile parametrik olarak temsil edilir. Bu fonksiyon tek bir

değişken kabul ettiği için N-boyutlu veri N-boyutlu bir dizi ile tanımlanır. Dizilerin uzunluğu verideki

nokta sayısını, dizilerin sayısı ise verinin kaç boyut içerdiğini gösterir. Parametre değişkeni u

parametresi ile gösterilir ve 0-1 aralığında monotonik artan bir dizidir. Fonksiyon yine spline

parametrelerini tutan (t, c, k) demetini ve u parametresini döndürür.

s interpolasyon sırasındaki düzleştimrenin (smoothing) derecesini belirlemek üzere kulanılabilecek

bir parametredir. Varsayılan değeri m: veri sayısını göstermek üzere s = m – sqrt(2m) ile verilir.

Düzleştirme istenmiyorsa s = 0 olduğu belirtilmelidir.

Spline temsili belirlendikten sonra istenen noktalarda spline interpolasyon (ve türevi ile integrailinin)

hesabını yapan fonksiyonlar splev, spalde, splint fonksiyonlarıdır. 8 ya da daha fazla düğüm

içeren kübik spline fonksiyonları için kök hesabı yapan bir de splroot fonksiyonu bulunmaktadır.

Page 7: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

Örnek: Kübik Spline İnterpolasyonu

>>> import numpy as np>>> import matplotlib.pyplot as plt>>> from scipy import interpolate

>>> x = np.arange(0, 2*np.pi+np.pi/4, 2*np.pi/8)>>> y = np.sin(x)>>> tck = interpolate.splrep(x, y, s=0)>>> xyeni = np.arange(0, 2*np.pi, np.pi/50)>>> yyeni = interpolate.splev(xyeni, tck, der=0)

>>> plt.figure()>>> plt.plot(x, y, 'x', xyeni, yyeni, xyeni, np.sin(xyeni), x, y, 'b')>>> plt.legend(['Dogrusal', 'Kubik Spline', 'Veri'])>>> plt.axis([-0.05, 6.33, -1.05, 1.05])>>> plt.title('Kubik Spline Interpolasyonu')>>> plt.show()

grafiğini çizdirelim

Spline interpolasyonun diğer uygulamaları için bkz.spline_interpolasyonu_2.py

Page 8: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

Nesne Yönelimli (Object Oriented) Spline İnterpolasyonuUnivariateSpline

Python'da spline interpolasyonu için Nesne Yönelimli bir alternatif de

bulunmaktadır. Başlatıcı (__init__) metoda x,y verisi geçirilerek olgu oluşturulur.

Sınıfın __calll__ metodu gönderilen x değerleri için spline interpolasyonu ile y

değerlerini hesaplar ve döndürür. InterpolatedUnivariateSpline alt sınıfı bu

işlemi yapmasının yanı sıra ayrıca integral, türev ve kök bulma için de metodlara

sahiptir.

Bunun yanı sıra düzleştirme istendiğinde tıpkı yapısal alternatifte olduğu gibi s

parametresi kullanılır. Bu durumda verideki düğüm sayısından daha az

(düzleştirme miktarı kadar az) düğüm içeren bir spline fonksiyonu oluşturulur. Bu

şekilde düzleştirme kullanılarak oluşturulan spline'a “interpole spline” yerine

“düzleştirilmiş spline” adı verilir.

UnivariateSpline sınıfının bir başka alt sınıfı olan LSQUnivariateSpline t

parametresi ile düğümleri dışarıdan yerleri ile birlikte sağlamak için kullanılabilir.

Aralarında eşit uzaklıklar olmayan ve her noktadan geçmeyen; bazı aralıklarda

düzleştirme içeren bazılarında içermeyen özel nitelikli spline fonksiyonları

yaratmak için kullanışlıdır.

Page 9: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

Örnek: Yapısal olarak çözdüğümüz kübik spline interpolasyon örneğini nesne yönelimli

alternatifiyle çözelim.

>>> import numpy as np>>> import matplotlib.pyplot as plt>>> from scipy import interpolate

>>> x = np.arange(0, 2*np.pi+np.pi/4, 2*np.pi/8)>>> y = np.sin(x)>>> s = interpolate.InterpolatedUnivariateSpline(x, y)>>> xyeni = np.arange(0, 2*np.pi, np.pi/50)>>> yyeni = s(xyeni)

>>> plt.figure()>>> plt.plot(x, y, 'x', xyeni, yyeni, xyeni, np.sin(xyeni), x, y, 'b')>>> plt.legend(['Dogrusal', 'InterpolatedUnivariateSpline', 'Veri'])>>> plt.axis([-0.05, 6.33, -1.05, 1.05])>>> plt.title('Nesne Yonelimli Spline Interpolasyonu')>>> plt.show()

grafiğini çizdirelim

Spline interpolasyonun diğer uygulamaları için bkz.spline_interpolasyonu.py

Page 10: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

İki boyutlu bir yüzeye üzerindeki veri için ara değer hesabı yapmak (interpolasyon) için bsplrep fonksiyonu kullanılır. Bu

fonksiyona tıpkı 1-boyutlu yapısal (procedural) spline interpolasyonunda olduğu gibi z = f(x,y) yüzeyini oluşturan x, y ve

z dizileri gönderilir. Fonksiyon tx, ty, tz: düğüm noktalarını, c: katsayıları, kx, ky: spline derecesini göstermek üzere (tx,

ty, tz, c, kx, ky) demet değişkenini döndürür. Bu demet değişken splev fonksiyonuna geçirilir ve istenen (x, y) noktaları

için interpolasyon (ara değer) hesabı yapılır.

Tıpkı 1-boyutlu spline interpolasyonunda olduğu gibi 2-boyutlu spline interpolasyounda da s parametresi düzleştirme

(smoothing) için kullanılır. s = 0 düzleştirme yapılmak istenmediği anlamına gelir. m: nokta sayısını göstermek üzere

varsayılan düzleştirme değeri s = m – sqrt(2m) 'dir.

2-Boyutlu Spline İnterpolasyonu (Yapısal)(opsiyonel)

>>> import numpy as np>>> from scipy import interpolate>>> import matplotlib.pyplot as plt>>> # 20x20 'lik bir grid uzerinde bir fonksiyon tanimlayalim>>> x, y = np.mgrid[-1:1:20j, -1:1:20j]>>> z = (x+y) * np.exp(-6.0*(x*x+y*y))>>> # grafik>>> plt.figure()>>> plt.pcolor(x, y, z)>>> plt.colorbar()>>> plt.title("Seyrek Orneklenmis Fonksiyon")>>> plt.show()>>> # 70x70'lik daha genis bir grid uzerinden ornekleme>>> xyeni, yyeni = np.mgrid[-1:1:70j, -1:1:70j]>>> tck = interpolate.bisplrep(x, y, z, s=0)>>> znew = interpolate.bisplev(xyeni[:,0], yyeni[0,:], tck)>>> # grafik>>> plt.figure()>>> plt.pcolor(xnew, ynew, znew)>>> plt.colorbar()>>> plt.title("Spline Interpolasyonu")>>> plt.show()

Page 11: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

20 x 20 'lik bir gridle (20 (x,y) ikilisi ile) örneklenmiş fonksiyon

Aynı fonksiyonun 70 x 70 'lik bir gridle örneklenmiş versiyonu

Page 12: A409 Astronomide Sayısal Çözümlemeozgur.astrotux.org/ast416/Ders_03/Ders03_Interpolasyon.pdf1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı

Ödev 3 (1 Mayıs 2017, Pazartesi 23:59)

Lagrange İnterpolasyon Yöntemi ile interpolasyon yapabilen LagrangeInterpolasyon adlı bir sınıf kodlayınız. Kodunuz aşağıdaki özelliklere sahip olmalıdır.

1. Orjinal veriyi (x ve y'leri) birer NumPy dizisi olarak başlatan bir başlatıcı (__init__) metoduna sahip olmaldıır.

2. Herhangi bir x noktası için Lagrange interpolasyonu ile interpole y değerini hesaplayan bir __call__ metoduna sahip olmalıdır.

3. Herhangi bir x dizisinin (liste ya da demet değişkenler için de çalışmalı!) tüm değerleri için Langrange interpolasyonu ile y değerlerini hesaplayıp, bir dizi şeklinde döndüren vektorel_interpolasyon metodu içermelidir.

4. Kodunuzu ders notunun (Ders03_Interpolasyon_Yontemleri.pdf) 5. bölümündeki örnek için (x = 2.2) çalıştıran bir _test() fonkisyonu kodlayınız (x0 = 1 alınız).

5. Kodunuzu aynı örnekteki veri üzerinden x = [1.1, 1.3, 1.5, 1.7, 1.9, … , 4.1, 4.3, 4.5, 4.7, 4.9] dizisi için çalıştıran ve bu x'lere karşılık hesap ettiği interpole y değerlerinin grafiğini çizen bir _test2() fonksiyonu kodlayınız.

6. Verilen x,y ikilileri için scipy.interpolate fonksiyonlarından splrep ve splev 'I kullanarak spline interpolasyonu ile 5. basamakta verilen x dizisi için interpole y değerleirni hesaplayıp, yine 5. basamakta çizilen grafiğin üzerine x'lere karşıılık olarak çizdiriniz.

7. Orjinal veride x'i y'ye bağlayan fonksiyonu da bularak, x dizisine karşılık bu fonksiyonla hesapladığınız y dizisini de bu graiğin üzerine çizdiriniz.

8. Grafiğinizin eksenlerine birer isim (xlabel, ylabel) veriniz ve başlığı (title) ile birlikte çizdirdiğiniz eğrilerin ne anlama geldiğini gösteriniz (legend).

Kodunuzu (sadece kodu, grafiği değil) Türkçe karakter içermeyecek şekilde ad_soyad_ogrno_odev3.py isimli bir dosyaya kaydedip e-posta ile gönderiniz.