You are on page 1of 382

Hesapsal Bilim

Öğretmen: Gilbert Strang

Tercüme: Burak Bayramlı


Kaynak: OCW, MIT, Computational Science and Engineering, I, II

https://ocw.mit.edu/courses/mathematics/
18-085-computational-science-and-engineering-i-fall-2008

Sayılar ve Kuramlar

https://burakbayramli.github.io/dersblog/sk/

Tüm Dosyalar, Kodlar

https://github.com/burakbayramli/classnotes
Ders 1
Bu derste matrislerden bahsedilecek, onların canlanmasını, dile gelmesini isxtiy-
oruz. Mesela alttaki gibi bir matris

 
2 −1 0 0
 −1 2 −1 0 
K=
 0 −1

2 −1 
0 0 −1 2

nedir? Nereden gelir? Bu matris bir şeyi temsil edecek, bilimsel bir problemi
çözmemizi sağlayacak.
Matrisin özelliklerine bakalım. İlk bakışta bunun simetrik bir matris olduğunu
görüyoruz. Yani K = KT . Bu tür matrisler özellikle dengedeki sistemler (equilib-
rium) problemlerinde çok ortaya çıkıyorlar. Başka özellikler? K’yi büyütseydik,
seyrek (sparse) olacaktı, yani içinde çok fazla sayıda sıfır olacaktı. Şu haliyle tam
seyrek denemez, ama aynı kalıpla büyütülürsek seyrek olur. Eğer Python kul-
lanarak sıfır olmayan elemanları saydırmak isteseydik, sonuç ne gelecekti? 4x4
olan K için alttaki kod şu sonucu verir,

K = np.array([[2,-1,0,0],[-1,2,-1,0],
[0,-1,2,-1],[0,0,-1,2]])
print (np.count_nonzero(K))
10

4x4 = 16 içinden 10 eleman sıfır değildir. Eğer 100x100 olsaydı? Matris aynı kalıbı
takip ederse, yani çaprazı, ve çaprazın bir altı ve bir üstü dolu kalırsa, çaprazda
100 eleman olur (boyutla aynı), alt ve üstünde birer az eleman olur, yani 99+99
= 198. Toplayalım, 100 + 198 = 298. Yani 100x100 = 10000 eleman içinden 298
eleman sıfır değildir, geri kalan bir sürü eleman sıfırdır. Matris seyrektir.
Sayısal hesaplamada yoğun (dense -sıfırı fazla olmayan-) matrisler, büyük boyut-
larda başımızı ağrıtabilir. Seyrek matrisleri daha hızlı çözmenin yöntemleri vardır,
ama 1 milyon x 1 milyon bir yoğun matris çözmesi imkansız hale gelebilir.
Başka özellikler? Matris üçlü köşegen (tridiagonal) -üçlü köşegenlik, matris çaprazı,
onun bir üstü ve altı haricindeki tüm diğer elemanların sıfır olduğu bir matristir-.
Bu tür matrisler çok önemlidir, Newton sağolsun, ikinci seviye diferansiyel den-
klemlerden sürekli ortaya çıkarlar mesela.
Dahası? Bu bir Toeplitz matrisi, çaprazdaki değerler sabit değerler, çapraz boyunca
hiç değişmiyorlar. Bu matrislere lineer zamana göre değişmeyen filtreler (lin-
ear time invariant filters) ismi de veriliyor, çünkü her satır birbirinin aynı (ve
hesabımızda satırların zamanı temsil ettiği kabulünden hareketle). Python ile bir
Toeplitz yaratmanın yöntemi şöyle:

import scipy.linalg as lin


K = lin.toeplitz([2, -1, 0, 0])
print (K)

1
[[ 2 -1 0 0]
[-1 2 -1 0]
[ 0 -1 2 -1]
[ 0 0 -1 2]]

100x100 için Toeplitz komutuna verdiğimiz tek satırda daha fazla sıfır gerekli.
İçinde tamamen sıfır olan bir vektör yaratırız, başındaki birkaç elemanı istediğimiz
değerle atarız.

import scipy.linalg as lin


vec = np.zeros((1,100))
vec[0,0] = 2
vec[0,1] = -1
print (lin.toeplitz(vec))

[[ 2. -1. 0. ... 0. 0. 0.]


[-1. 2. -1. ... 0. 0. 0.]
[ 0. -1. 2. ... 0. 0. 0.]
...
[ 0. 0. 0. ... 2. -1. 0.]
[ 0. 0. 0. ... -1. 2. -1.]
[ 0. 0. 0. ... 0. -1. 2.]]

Seyrek matrislerle işlem yaptığımızı Python’a bir şekilde belirtmemiz lazım, eğer
mevcut haliyle bu matrisi çözmeye uğraşırsak, Python sıfırlara gelene kadar on-
ların sıfır olduğunu bilemeyecektir.

import scipy.sparse as sparse


import numpy as np
import scipy.linalg as lin
vec = np.zeros((1,100))
vec[0,0] = 2
vec[0,1] = -1
K = lin.toeplitz(vec)
A = sparse.lil_matrix(K)
print (A.shape)

(100, 100)

Yanlız yukarıda yoğun matrisi önce yarattım, sonra onu değiştirerek seyrek ma-
tris yarattım, daha iyisi baştan bir seyrek matris yaratmaktı. Neyse, bu yöntemi
ileri de göreceğiz.
Daha derine inelim şimdi. K matrisi tersi alınabilen (invertible) bir matris midir?
Evet. Bu ne demektir? KK−1 = I, ve I matrisi birim (identity) matrisidir, Python’da
np.eye(N) komutuyla yaratılabilir.

Bir matrisin tersinin alınıp alınamayacağını nasıl anlayabiliriz? Bu çok önemli,


temel bir sorudur.
Bazılarının aklına determinantı hesaplamak gelebilir. Fakat benim ilk seçimim
bu değil, tercihim satır indirgemek (row reduce). Önümüzde bir matris var, ve
içinde neler olup bittiğini bilmiyoruz. Satır indirgeme yapın.

2
Bu nasıl yapılır? K’in çaprazının altındaki -1 değerlerini sıfırlamak istiyorum.
Orayı temizlemek istiyorum, çünkü matrislerim eğer üçgensel (triangular) ise,
olan biteni anında görebilirim.
Birinci satırı ikiye bölüp, ikinci satıra eklerim. Terminoloji: 0,0 kordinatı (en üst
sol köse) bu işlem sırasında pivot oldu.

 
2 −1 0 0
 0 3/2 −1 0 
 
 0 −1 2 −1 
0 0 −1 2

Şimdi pivot 3/2, ve onun altındaki değeri temizlemek istiyoruz. İkinci satırın
2/3’ünü alta eklersek, oradaki -1 sıfırlanır.

 
2 −1 0 0
 0 3/2 −1 0 
 
 0 0 4/3 −1 
0 0 −1 2

ve sonunda

 
2 −1 0 0
 0 3/2 −1 0 
 
 0 0 4/3 −1 
0 0 0 5/4

Bu gerçekten hızlı bir işlem oldu. Python da determinantı zaten böyle bulacaktı.
Yoketme (elimination) kullanacaktı, teker teker -1’leri yokedecekti. Peki deter-
minantın değeri nedir? 5. Niye 5? Çünkü elimizdeki artık üçgensel bir ma-
tris, ve böyle matrislerde çaprazdaki elemanları birbiriyle çarpmakla determinant
hemen hesaplanır. Python aynen böyle yapacaktı, 2 · 3/2 · 4/3 · 5/4 = 5.
Şimdi tersinin olup olmadığı sorusuna geri dönelim: Bir üst üçgensel (upper tri-
angular) matris ne zaman tersine çevirilebilir haldedir? Determinant kelimesini
kullanmamıza gerek yok, çapraza bakarız, eğer bu çapraz sıfır değeri olmayan bir
çapraz ise bu matris tersine çevirilebilir demektir. Terminoloji: demek ki elimizde
N tane (K4 için 4) tane sıfır olmayan pivot var.
1. dersin amaçlarından biri matrislere isim vermek. K matrisi bunlardan biri,
önemli bir matris, onu ileride tekrar göreceğiz, görünce tanıyacağız.

 
2 −1 0 −1
 −1 2 −1 0 
C=
 0 −1

2 −1 
−1 0 −1 2

3
Peki şu matris? Toeplitz formunda ama üst sağ ve alt sol köşelerde ekstra bir
-1 değeri var. Fakat iddia ediyorum ki bu matris tersine çevirebilir değil ve
bunun için determinant, ya da yoketme tekniğine gerek yok. Terminoloji: Ma-
trise C denilmesi onun değerlerinin dairesel (circulant) olmasından ileri geliyor. -
1 değerlerine bakın, sanki bir yuvarlak oluşturuyorlar, sıfır değerleri aynı şekilde.
Devam edelim: Diyelim ki C bir vektörü çarpıyor (zaten matrislerin tek amacı
bu, vektörler ile çarpılmak), ve ortaya sıfır vektörü çıkıyor. Boş olan vektör ne
olabilir?

    
2 −1 0 −1 0
 −1 2 −1 0     0 
C=
 0 −1
  =  
2 −1     0 
−1 0 −1 2 0

Şu olabilir

   
2 −1 0 −1 1 0
 −1 2 −1 0  1   0 
C=
 0 −1
 = 
2 −1   1   0 
−1 0 −1 2 1 0

İddia ediyorum ki böyle bir vektörün olabilmesi C’nin tersine çevirilebilir olma
olasılığını yoketti. Nasıl?
Eğer C’nin tersi olabilseydi, Cu = 0 denklemi ne olurdu? İki tarafı bu “olabilen”
C−1 ile çarpıp sonuca bakalım:

C−1 Cu = C−1 0

Iu = 0

u=0

Yani eğer C’nin tersi olsaydı, Cu = 0 denkleminin tek sonucu u = 0 olurdu.


Fakat bu böyle değildir, üstte içinde 1 olan vektör bunun kanıtı. O zaman bir
uyuşmazlık, absürtlük elde ettik, demek ki C’nin tersi olduğu iddiası yanlıştır.
Fiziksel olarak K ve C’yi kütle ve yay sistemi olarak kabul edebiliriz. Mesela K
şöyle bir sistemi temsil edebilir:

4
Yuvarlak olan C sistemi şunu temsil edebilir

Resimdeki noktalar kütleler, ve yaylar o kütleleri birbirine bağlıyorlar.


T Matrisi
Bu matris K’ye benzer, fakat en üst satırda 2 yerine 1 var.

 
1 −1 0 0
 −1
 2 −1 0 

 0 −1 2 −1 
0 0 −1 2

Kütle ve yay sistemine dönersek bu matris bir ucu serbest olan bir mekanik sis-
temi gösterebilir.
B Matrisi

 
1 −1 0 0
 −1
 2 −1 0 

 0 −1 2 −1 
0 0 −1 1

Bu sistem de her iki ucu da serbest olan bir sistemdir. Bu sistemi alıp istediğimiz
yere götürebiliriz.
Son iki matrisin ikisi de simetriktir, üçgensel ve köşegen (diagonal) matrislerdir.
Niye üçgensel ve köşegen? Çünkü her kütle sağ ve solunda tek bir (diğer) kütleye
bağlıdır, o yüzden bağlı olmadığı kütlelere olan matris değeri 0 olarak gösterilir,
bu da bir üçgensel köşegen sistem ortaya çıkarır.
Ama T ve B artık Toeplitz değildir.
Bu noktada sınır şartları (boundary conditions) kavramına vurgu yapmakta yarar
var. Mekanik sistemde üçün ne olduğu matrislere sınır şartı olarak yansıyor. Ve
bu şartlar bir sistemin çözülmesinde son derece önemli. Hoca kendisine bir prob-

5
lemle gelenlere genelde ilk önce bu soruyu soruyor o yüzden: “sınır şartların
ne?”.
Tersine çevirilme durumu? T tersine çevirilebilir, B çevirilemez. B için yine aynı
 T
u= 1 1 1 1 ispatını kullanabiliriz.
K, T, B, C matrislerini aynı anda yaratan bir Python programı şurada. Kullanım
mesela 4x4 boyutları için K, T, B, C = ktbc(4) şeklinde, bu bize tüm özel ma-
trisleri bir kerede oluşturuyor.

import scipy.linalg as lin

def ktbc(n):
vec = np.zeros((1,n))
vec[0,0] = 2
vec[0,1] = -1
K = lin.toeplitz(vec)
T = np.copy(K)
T[0,0] = 1
B = np.copy(K)
B[0,0] = 1
B[n-1,n-1] = 1
C = np.copy(K)
C[n-1,n-1] = 1

return K, T, B, C

Kapatırken şu özellikleri de ekleyelim.


K, T pozitif kesin (positive definite) matrislerdir.
C, B pozitif yarı-kesin (positive semi-definite) matrislerdir.
Eğer simetrik bir matrisim var ise ve pivotların hepsi pozitif ise, o matris hem
tersine çevirelebilir, hem de pozitif kesin demektir. Yani bir matrise bakarız,
yoketme tekniğini uygularız sonra pivotlarına bakarız.
Pozitif kesinlik çok önemli bir kavramdır, lineer cebirin tamamını biraraya getirir
sanki, özdeğerlere (eigenvalue) bağlıdır, least square yöntemine bağlıdır, deter-
minantlar. Her yerden çıkar.
Geriye Doğru Farklılık Matrisi
Python toeplitz çağrısının değişik bir şekilde kullanarak geriye doğru farklılık
(backward difference) matrisi de yaratabiliriz. Bu kullanımda matrisin sol kolo-
nunu, ve üst satırını tamamen belirtmek gerekiyor.

import scipy.linalg as lin

D = lin.toeplitz([1, -1, 0, 0], [1, 0, 0, 0])


print (D)

[[ 1 0 0 0]

6
[-1 1 0 0]
[ 0 -1 1 0]
[ 0 0 -1 1]]

Çözülmüş Soru 1.1 B


Soru: T matrisini H matrisine çevir bunu J matrisini kullanarak yap.

 
2 −1 0
H =  −1 2 −1 
0 −1 1
 
1 −1 0
T =  −1 2 −1 
0 −1 2

Kitaptaki bu sorunun çözümündeki J matrisi birimsel matrisin tersidir, şu şekildedir:

 
0 0 1
 0 1 0 
1 0 0

Yani 1 sayıları sola yatık çaprazda değil sağa yatik çaprazda. Bu matrisin çarpım
işlemi sırasında ilginç etkileri var. Eğer sağdan çarpılırsa bir matrisin her satırının
içindeki sırayı tersine çeviriyor. Eğer soldan çarpılırsa her kolon içindeki sırayı
tersine çeviriyor. J ∗ T ∗ J çarpımı aradığımız sonuç. Yani satırları çevirdikten
sonra, kolonları çevirince istediğimiz sonuca erişiyoruz. Python kodları

import scipy.linalg as lin


T = lin.toeplitz([2, -1, 0])
T[0,0] = 1
J = np.fliplr(np.eye(3))
print (T)
print (np.dot(T,J))
print (np.dot(J, np.dot(T,J)))

[[ 1 -1 0]
[-1 2 -1]
[ 0 -1 2]]
[[ 0. -1. 1.]
[-1. 2. -1.]
[ 2. -1. 0.]]
[[ 2. -1. 0.]
[-1. 2. -1.]
[ 0. -1. 1.]]

Soru 1.1 2
T3−1 hesabını üç basamakta yap ve bunu yaparken daha önce gördüğümüz U ve
U−1 matrislerini kullan.

7
import scipy.linalg as lin

T = lin.toeplitz([2, -1, 0])

T[0,0] = 1

U = np.array([[1, -1, 0],


[0, 1, -1],
[0, 0, 1]])

print (np.dot(U.T,U))
print (np.dot(U,lin.inv(U)))
print (np.dot(lin.inv(U), lin.inv(U).T))

[[ 1 -1 0]
[-1 2 -1]
[ 0 -1 2]]
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
[[3. 2. 1.]
[2. 2. 1.]
[1. 1. 1.]]

Soru 1.1.5
K3 ve K4 ’un tersini al (K2 ’yi de bir zahmet), ve şu kesirler olsun

1 11
=
det 45
.

 
  4 3 2 1
3 2 1
1 1 3 6 4 2 
K−1
3 = 2 4 2  ve K−1
4 =  
4 5 2
 4 6 3 
1 2 3
1 2 3 4

İlk önce K = K5 determinantını tahmin edin. Sonra det(K) ve inv(K)’yi hesaplayın


ve det(K) ∗ inv(K) hesabını yapın.

import scipy.linalg as lin

K, T, B, C = ktbc(3)
print (lin.inv(K))
print (lin.det(K))
print (lin.det(K) * lin.inv(K))

K, T, B, C = ktbc(5)
print (lin.det(K))
print (lin.inv(K))
print (lin.det(K) * lin.inv(K))

[[0.75 0.5 0.25]

8
[0.5 1. 0.5 ]
[0.25 0.5 0.75]]
4.0
[[3. 2. 1.]
[2. 4. 2.]
[1. 2. 3.]]
6.0
[[0.83333333 0.66666667 0.5 0.33333333 0.16666667]
[0.66666667 1.33333333 1. 0.66666667 0.33333333]
[0.5 1. 1.5 1. 0.5 ]
[0.33333333 0.66666667 1. 1.33333333 0.66666667]
[0.16666667 0.33333333 0.5 0.66666667 0.83333333]]
[[5. 4. 3. 2. 1.]
[4. 8. 6. 4. 2.]
[3. 6. 9. 6. 3.]
[2. 4. 6. 8. 4.]
[1. 2. 3. 4. 5.]]

Soru 1.1.22
Çözülmesi istenen denklem du2 /dx2 = 1, elastik çubuk problemi ve çubuğun iki
tarafı sabitlenmiş.

import scipy.sparse as sparse


import scipy.sparse.linalg
import scipy.linalg as lin

n = 1000
vec = np.zeros((1,n))
vec[0,0] = 2; vec[0,1] = -1
K = lin.toeplitz(vec)
A = sparse.csc_matrix(K)
e = np.ones((n,1))

u = sparse.linalg.spsolve(A,e)
plt.plot(u)
plt.savefig('1-1-22.png')

Sonuç üstteki grafik gibi olmalı. Yani çözümümüz olan u değerleri bir parabol
oluşturuyorlar. Bu demektir ki çubuğun orta noktaları daha fazla yer değiştiriyor,
uç noktaları daha az yer değiştiriyor.

9
Elastik Çubuk
Derste çokça kullanılan elastik çubuk kavramından şimdi bahsetmek iyi olur. Bu
çubuk tek boyutlu ve sadece boyuna doğru (yana doğru değil) uzayıp kısalabilen
matematiksel bir kurgu. Bu çubuğu hayalimizde birbirine zincirler ile bağlı son-
suz sayıda ufak parcaçığın toplamı olarak düşünebiliriz. x ve u(x) bağlamında ise
çubuğun iki kere fotoğrafının çekildiğini düşünelim. İlk fotoğrafta x bu çubuğun
üzerindeki bir parcaçık. u(x) ise tüm ağırlıklar, kuvvetler etkilerini gösterip uzama,
kısalma bitince çekilen ikinci fotoğrafta ilk resimdeki x noktasının ne kadar yer
değiştirmiş olduğu.

“Ucu sabitlemek” gibi kavramlar duyacağız, bunlar bazen fiziksel olarak anlamlı,
bazen ise ikinci fotoğrafta esneme sonrası hangi noktaya gelindiğinin önceden
belirlenmesi anlamında. du/dx gibi bir türevi irdelerken ise ortada zaman ol-
madığını dikkate alalım, türev x’e göre yani ilk resimdeki parcaçıgin yeri. O za-
man du/dx ikinci resimdeki esnemenin çubuktaki yer arttıkça (aşağı indikçe) ne
kadar değiştiği.
Denklemin sağında yer alan değerler, sisteme dışarıdan verilen güç olarak görülebiliyor,
hakikaten de değişimin ikinci türevi ivmedir. 1.2.22 sorusunu görsel olarak nasıl
hayal edebiliriz? Çubuğun iki ucu sabitlenmiş, o sebeple K matrisi kullanıyoruz
zaten, böylece sınır şartları dahil oluyor.
Python, VPython üzerinden kullanılabilecek KineticsKit adlı paket sistemi zi-
hinde canlandırmak için yardımcı olabilir. Birbirine eşit uzaklıkta, aynı kütlede
ve arasında yaylar olan 7 tane topu bırakınca ne olduğunu simüle edebiliriz. Res-
imdeki sol kısım başlamadan önce, sağ kısım yerçekimi işini bitirdikten ve toplar
durduktan sonrasını gösteriyor.

10
Alttaki program hem görsel simülasyonu yapacak, hem de topların önce ve sonra
değerlerini hatırlayarak yerçekimi sonrası aradaki farkı hesaplayacak. Sonuçlara
bakınca hakikaten de ortadaki topların daha fazla hareket ettiğini görebiliyoruz.
Grafiksel olarak düşünürsek te mantıklı, üste yakın toplar üstten bağlı olduk-
ları için fazla uzaklaşamıyorlar, ortalara yakın toplar, bir üstlerinden de aldıkları
ek mesafe sayesinde daha fazla yer değiştirebiliyor. Ama alt kısıma yaklaştıkça
orada bir birikme oluyor, çünkü alt üç kısım da sabitlenmiş.

from KineticsKit import *


from visual import vector

system = System(timestep=0.04, gravity=1)

mass1 = Mass(m=0.1, pos=(0.0, 0.0, 0.0), fixed=1)


mass2 = Mass(m=0.1, pos=(0.0, 0.5, 0.0))
mass3 = Mass(m=0.1, pos=(0.0, 1.0, 0.0))
mass4 = Mass(m=0.1, pos=(0.0, 1.5, 0.0))
mass5 = Mass(m=0.1, pos=(0.0, 2.0, 0.0))
mass6 = Mass(m=0.1, pos=(0.0, 2.5, 0.0))
mass7 = Mass(m=0.1, pos=(0.0, 3.0, 0.0), fixed=1)

system.insertMass(mass1)
system.insertMass(mass2)
system.insertMass(mass3)
system.insertMass(mass4)
system.insertMass(mass5)
system.insertMass(mass6)
system.insertMass(mass7)

spring1 = SingleHelixSpring(m0=mass1, m1=mass2, k=1, damping=0.5)


system.insertSpring(spring1)
spring2 = SingleHelixSpring(m0=mass2, m1=mass3, k=1, damping=0.5)
system.insertSpring(spring2)
spring3 = SingleHelixSpring(m0=mass3, m1=mass4, k=1, damping=0.5)
system.insertSpring(spring3)
spring4 = SingleHelixSpring(m0=mass4, m1=mass5, k=1, damping=0.5)
system.insertSpring(spring4)
spring5 = SingleHelixSpring(m0=mass5, m1=mass6, k=1, damping=0.5)
system.insertSpring(spring5)
spring5 = SingleHelixSpring(m0=mass6, m1=mass7, k=1, damping=0.5)
system.insertSpring(spring5)

loc_1 = [mass2.sphere.pos.y, mass3.sphere.pos.y,


mass4.sphere.pos.y, mass5.sphere.pos.y,
mass6.sphere.pos.y]

count = 0

while 1:
system.step()
count += 1
if count == 100: break

loc_2 = [mass2.sphere.pos.y, mass3.sphere.pos.y,

11
mass4.sphere.pos.y, mass5.sphere.pos.y,
mass6.sphere.pos.y]

from itertools import izip


for x,y in izip(loc_1, loc_2):
print x-y

12
Ders 2
Bir diferansiyel denklemle başlayıp çözebileceğimiz bir ayrıksal (discrete) prob-
leme nasıl ulaşırız? İkinci türevi içeren basit bir diferansiyel denkleme bakalım

d2 u
− = f(x)
dx2

u(0) = 0, u(1) = 0

Eksi işareti var çünkü ikinci türevler negatif kesin (negative definite) şeylerdir
ve eksi işareti bu durumu telafi etmek için, onu pozitif kesin hale çevirmek için
konuldu. Ayrıca dikkat edersek sınır (boundary) şartları var, her iki uçta da
fonksiyona sıfır değeri vermişiz, her iki uçta da onu “sabitlemişiz”. Dikkat ede-
lim, bu başlangıç değer probleminden farklı, u, x’in bir fonksiyonu, t yani za-
manın değil. Diyelim ki bu problem iki tarafı sabitlenmiş bir elastik çubuğu tem-
sil ediyor, f(x) çubuk üzerindeki her x noktasındaki yükü gösteriyor. Bu derste
f(x) = 1 alacağız, yani

d2 u
− =1
dx2

Amacımız bir diferansiyel denklem alıp, onu ayrıksal olarak temsil edebilmek,
yani şöyle

−ui+1 + 2ui − ui−1


= f(xi )
(∆x)2

Bu denklem ikinci farklılıkları (second difference) gösteriyor.


Diferansiyelden (differential) farklılıklara (differences) geçişin birkaç yöntemi ola-
bilir.
Birinci Farklılıklar (İleri Doğru)

u(x + h) − u(x)
∆F u =
h

Ayrıksal: (ui+1 − ui )/h


Birinci Farklılıklar (Geriye Doğru)

u(x) − u(x − h)
∆B u =
h

Ayrıksal: (ui−1 − ui )/h

1
Birinci Farklılıklar (Ortalanmış)

u(x + h) − u(x − h)
∆C u =
2h

Ayrıksal: (ui+1 − ui−1 )/h


Bunlar Calculus’tan hatırlanabilecek şeyler, fakat burada h limitte sıfıra doğru
gitmiyor. Hesapsal dünyada h bizim belirlediğimiz bir mesafe, belki 1, belki 0.1.
O kadar bir hesapsal adım atmayı biz seçiyoruz, her şey ayrıksal.
Ayrıca Calculus’ta hep ∆F u gösterilir ve yaklaşıksal olarak türeve eşittir yani
u 0 (x). Geriye adım da vardır, hesapsal olarak ileri adım kadar iyidir, ve o da
aşağı yukarı türeve eşittir. Çok önemli bir farklılık hesabı ise ortalanmış (cen-
tered) olandır, bu hesap ileri ve geri farklılıkların ortalamasıdır, aynı şekilde aşağı
yukarı türeve eşittir.
Baştaki denklemimize birinci türevi dahil etmedik, çünkü birinci türevler anti-
simetriktir.
Birinci farklılıklar yöntemine dönelim, türeve ne kadar yakındırlar?
Birinci Farklılıklar (İleri Doğru)

∆F u ≈ u 0 (x) + O(h)

Birinci Farklılıklar (Geriye Doğru)

∆B u ≈ u 0 (x) + O(h)

Birinci Farklılıklar (Ortalanmış)

∆C u ≈ u 0 (x) + O(h2 )

O(h) h’ye oranlı (order of h) anlamına gelir, gerçek değerden “kesilip atılmış
fark” olduğunu farz edelim. Ortalama için niye O(h2 )? Hesabı yapalım. Tay-
lor serilerinin ne olduğunu hatırlayalım ve u(x + h) açılımıni yapalım. Dikkat,
ayrıksal formla değil, sürekli fonksiyonla çalışıyoruz, sürekli fonksiyon üzerinde
“ayrıksal bir adım” atılınca ne olacağını bulmaya çalışıyoruz, bu şekilde sürekli
formatta, cebirsel bir kural elde etmeye uğraşıyoruz.

h2 00 h3
u(x + h) = u(x) + hu 0 (x) + u (x) + u 000 (x)...
2 6

Taylor açılımlarında ve hesapsal bilimde ikinci seviye kesinlik (accuracy) çoğunlukla


yeterli oluyor. Hesapsal kodları geliştirirken, test ederken tipik olarak birinci se-

2
viyede başlanır, ve nihai ürün, sonuç ortamı (production) için 2. seviye eklenir.
Devam edelim, geriye doğru:

h2 00
0 h3 000
u(x − h) = u(x) − hu (x) + u (x) − u (x) + ...
2 6
Ortalanmış farklılık için iki formülü birbirinden çıkartırız, ve 2h’ye böleriz.

h3 000
u(x + h) − u(x − h) = 2hu 0 (x) + u
3

İki tarafı 2h’ye bölelim

u(x + h) − u(x − h) h2
= u 0 (x) + u 000
2h 6

Görüyoruz ki ortalama farklılık doğru türevi u 0 eşitliğin sağında veriyor, ve h2


terimine bakarak yaklaşıklığın, hatanın ikinci seviyede olduğunu anlıyoruz.
Türevlerin yerine farklılık geçirirken seçenekler bunlar. Elimizde 3 seçenek var,
ve çoğunlukla ortalanmış olan en iyisidir.
Şimdi ikinci farklılıklara gelelim: İkinci türev nedir? Türevin türevidir. İkinci
farklılık nedir? Farkların farkıdır.
Nasıl hesaplanır? ∆F ∆B yapabiliriz. Ya da ∆B ∆F . Birisi cikip ∆C ∆C diyebilir.
Hangisi? Hoca ∆C ∆C ’yi sevmiyor çünkü elimize [1 0 -2 0 1] gibi bir farklılık
vektörü geçiyor, fazla “dağılıyoruz”. ∆F ∆B , ve ∆B ∆F daha iyi çünkü ikisi de [1 -2
1] kullanır. Onlar daha ’odaklı”.
İkincil farklılıklar (second differences) formülünü de türetelim. Bu formül ileri
doğru bir adım attıktan sonraki fark ile geri doğru adım attıktan sonraki farkın
farkı. Yani
   
1 ui+1 − ui ui − ui−1

h h h
 
1 ui+1 − 2ui + ui−1
=
h h

ui+1 − 2ui + ui−1


=
h2

İkinci seviye diferansiyel denklem çözüme dönelim.

d2 u
− =1
dx2

3
denkleminin genel çözümü ne olabilir? Özel (particular) çözüm ikinci türevi 1
olan ve negatifi alınan şey nedir sorusunun cevabından bulunabilir, iki kere en-
tegre edilerek

1
− x2
2

buna ikinci türevi sıfır olan iki tane daha çözüm eklemek istiyorum, çünkü elim-
izde ikinci dereceden bir diferansiyel denklem var.

1
u(x) = − x2 + Dx + C
2

Bu ek iki sabiti nasıl kullanacağım? Onları elimdeki iki tane sınır şartını tatmin
etmek için kullanacağım. Bunu yapmak zor değil, birinci şartı formüle koyarım,
sabitler için bir formül elde ederim, ikinci şartı koyarım, ikinci bir formül elde
ederim, iki sabit, iki formül, böylece sonuç gelir.
u(0) ise C = 0, u(1) için D = 1/2.

1 1
u(x) = − x2 + x
2 2

Şimdi ana diferansiyel denklem

d2 u
− =1
dx2

ve onun ayrıksal formu

−ui+1 + 2ui − ui−1


= f(xi )
(∆x)2

nasıl matris formatında göstereceğimize gelelim. ui , ui+1 gibi değerlerin bir-


birinden çıkartılması, vs gibi işlemler gerekiyor. Altta böyle bir işlemi matris
üzerinden yapmanın yolunu görüyoruz.


..
   .. 
. ui−1 .
 −1 0 1   ui  ui+1 − ui−1
   
= 
−1 0 1  ui+1   ui+2 − ui
   
 
.. ui+2 ..
. .
   
Soldaki matris −1 0 1 yerine ikinci farklılıklar için −1 2 1 de kullan-
abilir, o zaman ikinci farklılık hesabını yapmış oluruz. Yani şöyle

4
    
2 −1 u1 1
 −1 2 −1  u2   1 
1     
 −1 2 −1  u3 = 1 
h2     
 −1 2 −1  u4   1 
−1 2 u5 1

Bu KU = F denkleminin matris formudur. Diferansiyel denklem çözmek de-


mek u fonksiyonunu bulmak demektir, o zaman yukarıdaki bilinmeyen u1 , u2 , ..
değerlerinin hesaplamamız gerekiyor. Onlar “ayrıksal” u fonksiyonunun her
veri noktasındaki değerlerini temsil ediyor olacaklar.
Bu çözüm perde arkasında Python tarafından nasıl hesaplanacak? Yoketme (elim-
inasyon) tekniği ile.
h2 , ayrıksal formüldeki ∆x2 , nedir? u’yu kaç parçaya ve hangi değerler arasında
bolduğumüze bakalım: 0 ve 1 arasında ve 6 parçaya bölüyoruz, o zaman h = 1/6,
h2 = 1/36, yani 1/h2 = 36, yani üstteki imajda h2 ’yi en solda çarpan 36 olarak
yazabiliriz. Sonra u’yu hesaplatırız.

K matrisinin 5x5 olması karışıklık yaratmış olabilir. Burada sebep K matrisine u0


ve u6 ’nin dahil edilmemiş olması, çünkü o değerleri zaten biliyoruz. Bu değerler
olsaydı K matrisinin sol ve sağına tamamen sıfır içeren iki kolon gerekecekti,
u vektörüne alttan ve üstten u0 ve u6 eklenecekti ve bu iki değer sıfır olduğu
için K’nin sol ve sağındaki sıfırlar ile çarpılacaklardı, bu yüzden mevcut toplam
üzerinde hiç etkileri olmayacaktı . Bu sebeple bu iki kolonu ve u değerini tama-
men kaldırmak sonuç üzerine hiçbir etki yapmıyor.
Devam edelim. Şimdi orijinal problemi değiştirelim. Eğer üstteki problem iki ucu
sabitlenmiş kendi ağırlığıyla asılan bir elastik çubuğu gösteriyorsa (ve u değerleri
çubuğun ne kadar uzadığını temsil ediyorsa), bu sefer üstteki ucu serbest bırakabiliriz.
Yani u(0) = 0 olmayacak.
Yine birörnek (uniform) çubuk, eşit dağılmış yük.

d2 u
− =1
dx2

du
(0) = 0, u(1) = 0
dx

5
Burada ilk şart u’nin eğiminin (slope) sıfıra eşitlenmiş olması.
Önceki denklemdeki genel çözüm hala ise yarar.

1
u(x) = − x2 + Cx + D
2

du
= −x + C
dx

du
(0) = 0 + C = 0
dx

C=0

u(1) = 0 = −1/2 + 0 + D

D = 1/2

O zaman çözüm

1
u(x) = − x2 + 1/2
2

Grafikleyince şuna benzer

Eğimin sıfır noktasında sıfır olduğunu görüyoruz.


Şimdi farklılıklar formülüne gelelim. Diferansiyel denklemin karşılığı olan farklılık
formülü nedir? Hala aynı:

−ui+1 + 2ui − ui−1


= f(xi )
h2

Şimdi önemli noktaya geldik: başlangıç şartları ne olacak? u(1) = 0 kolay, du/dx(0) =
0 nasıl temsil edilecek? Bir fikir şu olabilir.

u1 − u0
=0
h

6
Bu ifadeyi matrise nasıl tercüme ederiz? Üstteki ifade aynı zamanda u1 − u0 = 0
demektir, yer degistirince u1 = u0 . K matrisinin birinci satırı nedir?

−u0 + 2u1 − u2

u0 yerine u1 koyalım

= −u1 + 2u1 − u2

= u1 − u2

O zaman birinci satırı üsttekigibi değiştirirsek,


 sınır şartlarından
  birini yerine
 
getirmiş oluruz, yani ilk satıra 1 −1 koyacağız, orada 2 −1 yerine 1 −1
var artık. Matris bu şekilde değişince ona K yerine T matrisi deniyor. T U =
 T
1 1 ... .

    
1 −1 u1 1
 −1 2 −1  u2   1 
1     
 −1 2 −1  u3 = 1 
h2     
 −1 2 −1  u4   1 
−1 2 u5 1

Soru: ayrıksal çözüm gerçek çözüme ne kadar yakın? Cevap hata payı O(h)
çünkü (u1 − u0 )/h tanımı birinci dereceden bir yaklaşıksallık (approximation).
Kabaca çizince şöyle gözükür:

Hesap kalitesi pek iyi denemez. Çözümü ikinci dereceden yapsak daha iyi ola-
caktı. Nasıl? (u1 − u0 )/h yerine başka bir şey kullanmamız lazım. Ortalanmış
farklılığı hatırlayalım, bu yöntem ikinci derece doğruluğu olan bir yöntemdir,
Problem 1.2 A
Kitaptaki ufak problemi hatırlayalım

    
1 −1 u1 1
 −1 2 −1   u2 = 1 
 
−1 2 u3 1

Bu problem işte O(h) hatasını azaltma konusunu işliyor, bunun için ortalama
farklılık (centered difference) kullanılacak, (u1 − uo )/h yerine 0’inci değere denk

7
gelecek şekilde farklılığı ortalayacağız, 0 üzerinde ortalama yapmamız için onun
bir gerisine ve bir ilerisine gitmek lazım, o zaman önce K matrisini bir genişletelim,
çünkü artık u0 ’in dahil edilmesi gerekecek ve hayali bir u−1 ’i düşünelim, u 0 (0) =
0 için

u1 − u−1
=0
2h

tanımını kullanalım. O zaman

u1 − u−1 = 0

u1 = u−1

−u−1 + 2u0 − u1 = h2 f(0)

u1 = u−1 ifadesini yerine koyalım

−u1 + 2u0 − u1 = h2 f(0)

−2u1 + 2u0 = h2 f(0)

1
−u1 + u0 = h2 f(0)
2

O zaman matrisin üst sol değeri u0 katsayısına göre 1, onun sağındaki değer u1
katsayısına göre -1 olmalı. 1/2 değerini de eşitliğin sağındaki f için kullandığımıza
dikkat. Tüm bunları u−1 ’in yerine değer geçirerek elde ettiğimiz için o kolona
artık ihtiyaç kalmadı, o geçici kolon, matristen atıldı.

    
1 −1 u0 1/2
1  −1
 2 −1   u1
    1 
= 
h 2  −1 2 −1   u2   1 
−1 2 u3 1

Matris boyutlarının nasıl büyüdüğüne, ve u0 ’in dahil edilmesine dikkat edelim.


Problemin başındaki matris 3x3 boyutundaydı, bu 4x4 boyutunda, ayrıca h hala
1/4 değerinde.
Problem 1-2-A

8
import scipy.linalg as lin

def ktbc(n):
vec = np.zeros((1,n))
vec[0,0] = 2
vec[0,1] = -1
K = lin.toeplitz(vec)
T = np.copy(K)
T[0,0] = 1
B = np.copy(K)
B[0,0] = 1
B[n-1,n-1] = 1
C = np.copy(K)
C[n-1,n-1] = 1

return K, T, B, C

K,T,B,C = ktbc(3); print T

h = 1./4.

discrete = lin.solve( (1./h)**2 * T, [1.,1.,1.] )

discrete = np.insert(discrete, 0, discrete[0])


discrete = np.append(discrete, 0.)

K,T,B,C = ktbc(4); print T

discrete_2 = lin.solve( (1./h**2)*T, [1./2.,1.,1.,1.] )


# add little diff for plotting
# grafik ust uste binmesin diye azicik fark ekledik
discrete_2 = discrete_2 + 0.01
discrete_2 = np.append(discrete_2, 0.)

def u(x): return (1./2.)*(1. - x**2)

p1 = plt.plot([u(0.0), u(0.25), u(0.5), u(0.75), u(1.)])

p2 = plt.plot(discrete)

p3 = plt.plot(discrete_2)

plt.legend([p1,p2,p3], ["analytical solution (analitik cozum)",


"discrete solution 1 (ayriksal cozum 1)",
"discrete solution 2 (ayriksal cozum 2)"
])

plt.savefig('1-2-A.png')

[[ 1. -1. 0.]
[-1. 2. -1.]
[ 0. -1. 2.]]
[[ 1. -1. 0. 0.]
[-1. 2. -1. 0.]
[ 0. -1. 2. -1.]
[ 0. 0. -1. 2.]]

9
Güzel. Artık hesap gerçek sonuca iyice yaklaşacak.
[Derse dönelim] Bunlardan bahsetmemizin önemli bir sebebi sınır şartlarının ne
kadar önemli olduğunu anlatmak. Görüldüğü gibi sınır şartları, onların yaklaşıksallanma
yöntemleri sonucun üzerinde direk bir etki yaratıyor.
Bir dipnot olarak bahsedelim, burada kullandığımız metot sınırlı farklılıklar (fi-
nite differences) metodu. Eğer sınırlı elementler (finite elements) metodu kul-
lanıyor olsaydık, üstteki satırın değişmesi otomatik olarak gerçekleşecekti. Sınırlı
elementler metotu ileriki derslerin birinde işlenecek.
Soru 1.2.7
u’dan alınacak dört veri noktasıyla (sample) du/dx ortada olmak üzere 4. seviye
kesinlik elde edilebilir.

−u2 + 8u1 − 8u−1 + u−2 du d5


= + bh4 5 + ..
12h dx dx
1) Bunun u = 1, u = x2 ve u = x4 için doğru olduğunu kontrol edin.
2) u2 , u1 , u−1 , u−2 ’yi genişletin. Elde edilen dört Taylor serisini birleştirerek h4
için gelecek b katsayısını hesaplayın.
Cevap
Eşitliğin sol tarafındaki 1, 8 gibi katsayılar modelleyici tarafından seçilmiş, bir
teorinin, ispatın sonucu değil. Hala birincil farklılık (first differences) dünyasındayız,
ama ileri, geriye gidip katsayı 1 kullanmak yerine dört noktayı kullanmak istemiş,
ve ortadaki noktalara daha fazla “ağırlık” vermek istemişiz. Tabii bu katsayılarla
bu noktalar kullanılınca, ortalamanın düzelmesi için katsayıların bölüme yansıması
gerekiyor, o yüzden bölümde 12h görüyoruz.
Ve aynen ileri, geriye doğru ayrıksal formu sürekli fonksiyonlar üzerinde Taylor
serisiyle temsil edebildiğimiz gibi, üstteki eşitliğin sol tarafını da Taylor serisi ile
u(x + h) türü terimler üzerinden temsil edebiliriz. Üstte u2 , u−1 gibi ibareler var,
bunların Taylor karşılığı u(x+2h), u(x−h) gibi ifadeler olur. Katsayı çarpımlarının

10
ve 12h’ye bölüm işleminin Taylor serisi üzerinde de aynen kullanılması gerekiyor
tabii ki.
Bu arada b sabitinin ne olduğunu soru söylemiyor, ama tüm bu cebirsel işlemi
gerçekleştirince denklemdeki eşitliğin sağ tarafı aynen elde edilecek ve böylece b
yerine hangi sayı geleceği de ortaya çıkacak.

−u2 + 8u−1 + u−2 du d5 u


= + bh4 5 + ..
12h dx dx

u(x) = 1 için

du −1 + 8 − 8 + 1
= =0
dx 12h

u(x) = x2 için

du 0(x + 2h)2 + 8(x + h)2 − 8(x − h)2 + (x − 2h)2


=
dx 12h

(x − 2h)2 − (x + 2h)2 + 8{(xh )2 − (x − h)2 }


12h

2h
(x −  2h)(
+ x +  x − 2h − 
x − 2h) + 8(x + 
h+x−
h)(
x+h−x+
h)
12h

−4h(2x) + 8(2x)(2h)
12h

2x

u(x) = x4 için

du (x − 2h)4 − (x + 2h)4 + 8{(x + h)4 − (x − h)4 }


=
dx 12h


2 2 2 2 2 2 2
= [(x−2h) +(x+2h) ][(x−2h) −(x+2h) ]+8{[(x+h) +(x−h) [(x+h) −(x−h)]} /12h


1 2 2 2 2
= − 8hx[(x − 2h) + (x + 2h) ] + 8(4hx)[(x + h) + (x − h) ]
12h

11

1 2 2 2 2 2 2 2 2
= 4hx+4h +x +
−8hx[x − 
 4xh+4h ]+8(4hx)[x +

 2xh+h +x −

 2xh+h ]


12h


1 2 2 2 2
= − 8hx[2x + 8h ] + 8(4xh)[2x + 2h ]
12h

8hx 2 2 2 2
= 2x + 
8h − 8x − 

8h

12h

= 4x3

1 1 1 1 5 (5)
u(x+h) = u(x)+hu 0 (x)+ h2 u 00 (x)+ h3 u 000 (x)+ h4 u 0000 (x)+ h u (x)+...
2 6 24 120

1 1 1 1 5 (5)
u(x−h) = u(x)−hu 0 (x)+ h2 u 00 (x)− h3 u 000 (x)+ h4 u 0000 (x)− h u (x)+...
2 6 24 120

1 1 1 1
u(x+2h) = u(x)+2hu 0 (x)+ (2h)2 u 00 (x)+ (2h)3 u 000 (x)+ (2h)4 u(4) (x)+ (2h)5 u(5) (x)+...
2 6 24 120

1 1 1 1
u(x−2h) = u(x)−2hu 0 (x)+ (2h)2 u 00 (x)− (2h)3 u 000 (x)+ (2h)4 u(4) (x)− (2h)5 u(5) (x)+...
2 6 24 120

−u2 + 8u1 − 8u−1 + u−2


12h

12
Ders 3
Konumuz Au = b sistemini çözmek. Bu çözüm için Python’da linalg.solve
çağrısı var. Mesela

import scipy.linalg
A = [[2,3,4],[5,5,6],[7,7,7]]
b = [1,2,3]
u = scipy.linalg.solve(A, b)
print u

[ 0.14285714 0.42857143 -0.14285714]

linalg.solve çağrısı Matlab’de \ çağrısının karşılığı, oradaki kullanım u = A \ b


şeklinde.
Eğer elimizde ikinci bir c vektörü var ise, ve eşitliğin sağ tarafında b sonrası onu
kullanmak istiyorsak ayrı ayrı solve komutlarına gerek yoktur. Her iki vektörü
birbirine ekleyerek, solve’u toplu halde çağırabiliriz, bu performans açısından
daha iyi olur.

c = [2,3,8]
bc = np.vstack((b,c)).T
u = scipy.linalg.solve(A, bc)
print u

[[ 0.14285714 -1.28571429]
[ 0.42857143 5.14285714]
[-0.14285714 -2.71428571]]

Python vstack komutu iki matrisi üst üste koymak için kullanılır.
Her iki çözüm beraber olarak geri gelecektir. Bu niye daha hızlı? Çünkü Python’un
çözücüsü daha eşitliğin sağ tarafına bile gelmeden sadece A’ya bakarak bir sürü
işlem gerçekleştiriyor, eliminasyon yaparak A’yı üçgensel hale getirmek gibi. Bu
tür işlemleri gereksiz kere iki kere yapmak pahalı olurdu.
Eğer A karesel değilse, ama biz her iki durumda da işleyen bir komut istiyorsak,
np.linalg.lstsq(A,b) kullanabiliriz.
Soru: matematiksel olarak u’yu bulmak

Au = b

u = A−1 b

demektir. Peki Python bu hesap için gerçekten A−1 ’i hesaplar mı?


Hayır. Çünkü büyük problemler için matris tersini hesaplamak oldukça pahalıdır.
Ayrıca A matrisi zaten üçlü köşegen (tridiagonal) bir halde olabilir, ve cevap za-
ten hazır haldedir, bu noktada ters alma işlemi gereksiz olurdu.

1
Biraz zihin egzersizi yapalım. Eğer şöyle bir komut kullansam ne elde ederim (ki
I matrisi birim matrisi) ?

solve(A, I)

Cevap, tabii ki A’nin tersini elde ederim, yani A−1 çünkü AA−1 = I, sağ tarafta
birim matrisi var ise çözüm sadece A−1 olabilir.

 
  1 0 0
A u1 u2 u3 =  0 1 0 
0 0 1

Bu probleme bakmanın değişik bir yolu: sağ taraftaki birim matrisi içindeki [1
0 0] gibi değerler içindeki 1 değerlerini birer zıplama (impulse) anı gibi görmek,
sanki elimizde bir düz [0 0 .. 0] bir veri var, içinde tek zıplama olan yer orası, ve
bu [1 0 0], [0 1 0], .. içinde tek zıplama olan veriler “işlenerek” bize u1 , u2 , .. gibi
sonuçları veriyorlar.
Elle A’nin tersini bulmak için ne yapardık? Bir blok matrisi yaratırdık, [A _I],
yani 3x3 ve 3x3 iki matrisi yanyana koyup 3x6 boyutunda yeni bir matris elde
ederdik, ve bu matriste A üzerinde eliminasyon, pivotları sıfırlama gibi numar-
aları kullanarak onu birim matrise çevirirdik, bu arada aynı operasyonları tabii
ki I üzerinde uygulardık. En sonunda A birim olunca I A−1 ’e dönüşmüş olurdu!
Şimdi biraz büyük resme bakalım.
Lineer cebirin 4 büyük problemi Python komutları ile beraber şunlardır:
1) Eliminasyon, scipy.linalg.lu(A) A = LU
2) Dikgenleştirme (orthogonalization), scipy.linalg.qr(A), A = QR
3) Özdeğerler (eigenvalues), scipy.linalg.eig(A) A = SAS−1
4) Eşsiz değerler (singular values), scipy.linalg.svd(A) A = UΣV T
Eliminasyon ne yapar? Dikkat edersek aslında bu işlemin bir alt üçgensel (lower
triangular) matris (L) ve bir tane de üst üçgensel matris (U) ortaya çıkardığını
görürüz. Şimdi alttaki matris üzerinde eliminasyon yapalım ve bu arada tersini
de bulmuş olalım.

 
1 −1 0
 −1 2 −1 
0 −1 2

Eliminasyon işlemlerini yapalım (pivotlar öğeleri parantez içinde)

2
   
(1) −1 0 (1) −1 0
 −1 2 −1  →  0 (1) −1  = U
0 −1 2 0 0 (1)

l21 = −1 l31 = 0 l32 = −1

 
1 0 0
L =  −1 1 0 
0 −1 1

l21 = −1 yapılan ilk işlemi kodluyor, 1. satırı -1 ile çarp ve 2. satırdan çıkart
anlamına geliyor. Diğerlerini de sırasıyla görüyoruz ve bu işlemlerin sonucunda
üst üçgensel matris U’yu elde ediyoruz. Tüm l değerlerini bir araya koyup L’yi
elde edebiliriz. Bir tane daha yapalım:

   
2 −1 2 −1 0
 −1 2 −1  →  0 3/2 −1  = U
−1 2 0 0 4/3

1 2
l21 = − , l31 = 0, l32 = −
2 3
 
1
L =  −1/2 1 
0 −2/3 1

Eğer eşsiz (singular) bir matris üzerinde eliminasyon yapsak, bu işlemi nasıl etk-
ilerdi?

   
(1) −1 0 (1) −1 0
 −1 2 −1  →  0 (1) −1 
0 −1 1 0 0 (0)

Yani bu durumda 3 tane pivot elde edemezdik, sağ alt köşedeki değer elimi-
nasyon sırasında 0 olurdu, ve sağ matris, aynen sol matris gibi, eşsiz olurdu. Bu
işimize yaramazdı.
İki üstteki probleme dönelim: Burada ilk matris simetrik idi, ama L ve U matrisi
artık simetrik değil. Simetriyi geri getirebilir miyiz? U içinden sadece çaprazları
çekip çıkartalım

    
(2) −1 0 2 1 −1/2 0
 0 (3/2) −1  = U =  3/2  0 1 −2/3 
0 0 (4/3) 4/3 0 0 1

3
 
Böylece çaprazında 2 3/2 4/3 olan bir matris elde ettik. Peki bu matrisin
çarptığı (onun hemen sağında) içinden çaprazları çekip çıkardığımız matristen
geri kalanlar tanıdık geliyor mu? Evet, bu matris te LT ’e eşit. Demek ki LU =
LDLT gibi bir ifade mümkün.
Biliyoruz ki
K = LDLT
ifadesinde K her zaman simetriktir. Ters yönden söylersek, herhangi bir simetrik
K matrisini alıp eliminasyon yaparsam ve L ve D elde edince, LT ile çarpabilirim.
Peki şunu ispat edebilir miyiz? Herhangi bir L ve çapraz D var ise, LDLT her za-
man simetrik midir? Bir matrisin simetrik olması demek kendi devriğine (trans-
pose) eşit olması demektir. Yani

K = LDLT

KT = (LDLT )T

Devriği alınca parantez içindeki çarpımların sırası değişir.

= (LT )T DT LT

DT = D çünkü D zaten köşegen bir matris, önemli tüm değerleri çaprazında ve


devrik işlemi bu durumu değiştirmiyor. O zaman

= LDLT

Tekrar başladığımız noktaya döndük. Demek ki başladığımız matris simetriktir.


İspat tamamlandı.
Genele dönelim: AT A’nin mesela karesel olduğunu biliyorduk (n × m ile m × n
çarpılınca n × n boyutu elde edilir). Şimdi bunun üzerine simetrik olduğunu da
artık biliyoruz, üstte ispatladık.
Kural: Simetrik matrislerin tersi (inverse) de simetriktir. O zaman K−1 de simetrik-
tir.

4
Ders 4
(Dirac) Delta fonksiyonları
Bugün şu türdeki diferansiyel denklemlere bakacağız

d2 u
− = δ(x − a)
dx2

u(0) = 0, u(1) = 0

Bu denklem a noktasında bir noktasal yükü temsil ediyor, delta denklemi δ işareti
ile gösteriliyor, delta kelimesi fizikte ve matematikte genelde “farklılık” anlamında
kullanılır. Fonksiyonel anlamda δ sıfır olduğu yerde sonsuzluk değeri verir, geri
kalan her yerde sıfır değeri verir.

Eğer 0 yerine başka bir noktada ağırlık koymak istiyorsak, x − a kullanabiliriz,


böylece δ(..)’ya a üzerinde sıfır gider, ve o nokta sonsuz değeri döndürür.

Not: Noktasal yük fiziksel olarak olasılığı az bir olay olabilir.


Delta fonksiyonlarının bazı özellikleri
Z∞
δ(x) dx = 1
−∞

[Ek bilgiler için ders sonuna bakılabilir]. Yani delta fonksiyonunun tamamının
altında kalan alan 1 değerine eşittir. Daha genel olarak düşünelim. Delta fonksiy-
onunu başka bir fonksiyona “karşı” (onunla çarparak) entegre edersem ne olur?

1
Z∞
δ(x)g(x) dx = g(0)
−∞

Bu eşitliğin ispatı dokümanın altında.


Grafiksel olarak delta fonksiyonunu entegre edince şunu elde ederiz

Bu fonksiyona adım (step) fonksiyonu, ya da Heaviside fonksiyonu adı veriliyor.


Bir kez daha entegre edince

Yokuş (ramp) fonksiyonu elde ediyoruz. Bir kere daha entegre

Bir kere daha

Bu son fonksiyon küpsel spline fonksiyonudur, söyle ifade edilir:


0 x60
C=
x3 /6 x > 0

2
Şimdi tersten düşünelim, bir spline C’nin üç kere türevini alsak, sıfır noktasında
hangi değer geri gelir? C 000 (0) = 1 değeridir, sıfırdan önce ise sıfırdır. Bu ilginçtir,
küpsel spline son derece pürüzsüz (smooth) bir fonksiyondur, fakat, türeve bakınca
iyice anlıyoruz ki, aslında iki tane farklı fonksiyondur. Küpsel spline’ların bu
özelliği CAD programlarında, çizimlerde çok ise yarıyor.
Dört kere türevi alırsak yani C 0000 nereye geliriz? δ fonksiyonuna döneriz. 4. türev
diferansiyel denklemlerde kullanılır, 4. türevin bir yüke eşitlinmesi çubukların
(beam) bükülmesini modellerken kullanılır. Biyoloji, mekanik konularında çoğu
denklem 2. seviyedendir, 4. seviye nadirdir.
Başa dönersek: şu denklemin genel çözümü nedir?

d2 u
− = δ(x − a)
dx2

İlk önce özel (particular) çözümü bulalım. İkinci türevinin negatifi delta fonksiy-
onu olan fonksiyon nedir? Üstte ardı ardına entegre ederken zaten bunu irdelemiştik,
işareti değiştiriyoruz tabii çünkü şimdi negatiflik var, ama aradığımız yokuş fonksiy-
onu.

u(x) = −R(x − a)

İşimiz bitti mi? Hayır. İkinci türevin sıfıra eşit olduğu iki çözüm daha lazım,
iki homojen çözüm yani, bunlardan biri C diğeri Dx. Çünkü elimizde tatmin
edilmesi gereken iki tane sınır şartı var.

u(x) = −R(x − a) + C + Dx

Sınır şartlarını yerine koyalım


x = 0 için 0 = 0 + C + 0. Rampa fonksiyonu a’dan yükselmeye başlayan, eğimi
x − a olan, başlangıçta sıfır olan bir fonksiyondur.

x = 1 noktasında rampanın fonksiyonunun değeri 1 − a’dir.


Yerine koyalım: C = 0. Onu kullanarak devam edelim, ikinci şart için:

u(x) = −R(x − a) + C + Dx

3
−(x − a) + C + Dx = 0

C = 0 ise

−(1 − a) + D = 0

D=1−a

Tamamı

u(x) = −R(x − a) + (1 − a)x

a noktası sonrasında rampa fonksiyonu x − a olduğuna göre

−(x − a) + (1 − a)x = −x + a + x − ax = a − ax = a(1 − x)

Grafik

u(x)’in kesintisiz (continuous) bir fonksiyon olduğunu söyleyebiliriz. u 0 (x) 1


kadar aşağı iner. Eğimi (slope) grafiklersek nasıl olur?

Problemi fiziksel şekilde görsellemek gerekirse, iki ucu sabitlenmiş elastik çubuğu
çizelim:

4
Çubuğun üzerindeki noktayı oraya asılmış bir ağırlık olarak düşünelim. δ(x − a)
ile belirtmeye çalıştığımız bu değil mi, bir noktaya konsantre bir ağırlık uyguluy-
oruz. Bu ağırlığı uygulayınca ne olur? Nokta altında sıkışma, üstünde ise esneme
olur.
u(x) tabii ki hep pozitiftir, yani çubuğun tüm noktaları aşağı iner. Ama bazı nok-
talar üzerinde sıkışma, pozitif eğim, diğerleri üzerinde esneme (negatif eğim)
vardır.
Bir ucu serbest, diğeri sabitlenmiş problemi çözelim.

u 00 = δ(x − a)

u 0 (0) = 0, u(1) = 0

Şartları kullanınca,

u(x) = −R(x − a) + Cx + D

x = 0 noktasında rampa daha başlamadı, Cx+D kalır, türevi C, eşittir sıfır. C = 0.


u(x) grafiği neye benzer?

Elastik çubuğa ne olacak?

5
Gri olarak nitelenen yer a’nin altında olan yer, ve o bölüm bir sıkışma yaşadı.
Onun üstündeki bölüm de tamamen aşağı doğru indi, ama tüm noktaları aynı
miktarda aşağı indi, o bölgede x değiştikçe “değişim değişmiyor”, ki u 0 türevinin
tanımı bu değil mi?
Soru: u(x)’in y eksenini kestiği noktadaki değeri nedir? Grafiğe bakalım, a son-
rası aşağı doğru inen eğim -1. a sonrası u(x) = 1 − x ve iniş x ekseninde 1 nok-
tasına doğru. u(x) y eksenini nerede kesiyor olabilir? Eğer u(x) = 1 − a ise, ancak
o zaman a noktasında önce ve sonra değerler aynı sonucu verir.
Problemi ayrıksal olarak çözelim. h = 1/6 olsun, o zaman ayrıksal u 5 elemana
sahip olacak. Önce sabit / sabit problemini çözelim.

    
0 2 −1 u1

 1   −1
  2 −1 
 u2 

KU = 
 0 =
  −1 2 −1 
 u3 

 0   −1 2 −1  u4 
0 −1 2 u5

Eşitliğin sağ tarafındaki vektör içinde ikinci hücrede 1 değeri var. O bizim daha
önce δ(x − a) ile belirttiğimiz noktasal ağırlık. K’nin üst sol köşesindeki değeri 2
olarak seçmekle sabit / sabit sınır şartlarını koymuş oluyoruz.
Problemin cebirsel çözümünü tekrar yazalım, ama bu sefer rampa fonksiyonu
kullanmadan, parça parça yazalım, böylesi daha temiz olacak.


1−a x6a
u(x) =
1−x x>a

Sonuç ayrıksal olarak şu şekilde çizilebilir:

6
Aslında eşitliğin sağ tarafında delta (ve sabit) olduğu şartlarda “şanslıyız” çünkü
bu durumlarda ayrıksal sonuç gerçek sonucun tam üstünde çıkıyor. Bu şanslılığın
sebebi, aslında, üstteki deltadan basamağa, oradan rampaya, vs. geçmek için
kullandığımız entegral yerine, ayrıksalda toplama kullanınca anlaşılıyor, o geçiş
sırasında da toplamlar ve entegraller tam uyum halindeler, bu da doğal olarak
diferansiyel denkleme yansıyor.
Neyse, sayıları da yerine koyarak elle bulunabilecek bir sonuca erişebiliriz.

Ekler
Dirac fonksiyonu


0 ∞ x = x0
δ(x − x ) =
0 x=6 x0

dedik. Bu fonksiyonu bir olasılık dağılımı gibi görmek te mümkün, çünkü Dirac
fonksiyonlarının bir diğer sonucu,
Z
δ(x − x 0 ) dx 0 = 1

olması, ki Ω, x’i içeren üzerinden entegral alınan hacim. Olasılık yoğunluğu


üzerinden entegral hep 1 değeri vermez mi? Eğer r = x − x 0 olarak düşünsek,


∞ r=0
δ(r) =
0 diğer

ile, tek değişken üzerinden entegral ile olasılık bağlantısı daha rahat görülebilirdi.

7
Bu bağlamda Dirac delta fonksiyonu ya da dağılımı bir Gaussian dağılımının
varyansı limitte sıfıra giderken ki hali olarak ta görülebilir. Varyans küçüldükçe
tepe noktası daha yükselecek, ve nihai olarak sonsuzluğa gelecektir. Amam dağılım
hala dağılım, tüm tanım alanı üzerinden entegral değeri 1.
Çekirdek (Kernel) Kullanımı ve Dirac
Dirac fonksiyonu çekirdek yaklaşıklama için, ağırlıklı ortalama bağlamında da
kullanım bulabiliyor; mesela bir fonksiyonun ağırlıklı ortalamasını alıp bunu bir
diğer fonksiyon olarak göstersek, ya da o fonksiyounun o noktadaki yaklaşık
temsili olarak görmek istesek, bunu bir W ağırlık fonksiyonu ile şu şekilde gösterebilirdik,
Z
f(x) ≈ f(x 0 )W(x − x 0 , h) dx 0

ki h dışarıdan tanımlanan bir sabit olabilir (h bir etki alanını tanımlayan bir sabit
gibi kullanılabilir), mesela [3, sf. 16] çok boyutlu bir W,


315 (h2 − ||r̄||2 )3 0 6 ||r̄|| < h
W(r̄, h) =
64πh9 0 ||r̄|| > h

olabilirdi, ya da tek boyutta


W(x, h) = exp(−x2 /h2 )/(h π)

Ağırlık deyince alttaki de doğru olmalı,


Z
W(x − x 0 , h) dx 0 = 1

Böylece olasılık yoğunluk dağılımı kavramına dönmüş olduk. Şimdi W yerine


Dirac fonksiyonu kullansak [2, sf. 196],

8
Z
f(x) = f(x 0 )δ(x − x 0 ) dx 0

Yani bir fonksiyonun herhangi bir tanım alanı içinde Dirac fonksiyonu üzerinden
ağırlıklı ortalaması yine kendisidir! Bu normal çünkü x haricinde başka hiçbir
yerde ağırlık yok!
Kaynaklar
[1] Olver, Applied Mathematics
[2] Liu, Particle Methods for Multi-scale and Multi-physics
[3] Kelager, Lagrangian Fluid Dynamics Using Smoothed Particle Hydrodynamics

9
Ders 1.4, Soru, Cevap
Sorular
Soru 1.2.2
u 00 (x) = δ(x), u(−2) = 0 ve u(3) = 0 problemini çöz. Parçalar u = A(x+2) ve u =
B(x − 3) x = 0 noktasında birleşiyor. U = (u(−1), u(0), u(1), u(2)) vektörünün
KU = F = (0, 1, 0, 0) problemini çözdüğünü göster.
Çözüm
Yukarıda çözümün hangi formda olacağı A ve B üzerinden verilmiş, burada güzel
bir numara var (alternatif çözümde bunu anlattık), fakat biz önce derste daha
gösterilen yöntem üzerinden çözümü kendimiz bulalım.
Özel (particular) çözüm nedir?

u(x) = −R(x) + C + Dx

Bildiğimiz gibi R(x) rampa fonksiyonu şöyle:


0 x60
R(x) =
x x>0

Şimdi sınır şartlarını kullanarak u(x) içinde yerine koyalım:

u(−2) = −R(x) + C − 2D = 0

u(−2) = C − 2D = 0

x = −2 yani sıfırdan küçük olduğu için −R(x) = 0 oldu ve onu formülden attık.

u(3) = −3 + 3D + C = 0

Burada x = 3, o yüzden −R(3) = −3 kullanıldı. Sonuç

C = 2D

3 + 3D + 2D = 0

5D − 3 = 0

1
3
D=
5

O zaman

3
C − 2( ) = 0
5

6
C=
5

Sıfırdan öncesi ve sonrası için (değişik R(x) durumlarına göre) fonksiyonu parçalı
bir şekilde yazarsak





 6
5
+ 35 x x60
u(x) =



 −x + 56 + 53 x = 6
− 25 x x > 0
 5

Birinci kısmı sadeleştirirsek

6 3 3
+ x = (x + 2)
5 5 5

İkinci kısmı sadeleştirirsek

6 2 2
− x = − (x − 3)
5 5 5

Problemin hazır verdiği forma, ve sonuca eriştik.

import scipy.linalg as lin

def ktbc(n):
vec = np.zeros((1,n))
vec[0,0] = 2
vec[0,1] = -1
K = lin.toeplitz(vec)
T = np.copy(K)
T[0,0] = 1
B = np.copy(K)
B[0,0] = 1
B[n-1,n-1] = 1
C = np.copy(K)
C[n-1,n-1] = 1

return K, T, B, C

2
K,T,B,C = ktbc(4)

print lin.inv(K)

[[ 0.8 0.6 0.4 0.2]


[ 0.6 1.2 0.8 0.4]
[ 0.4 0.8 1.2 0.6]
[ 0.2 0.4 0.6 0.8]]

Bir sonraki derste göreceğimiz gibi üstteki sonucun 2. kolonu aradığımız sonuç
(çünkü delta ağırlığı 2. hücre üzerinde). Bu kolondaki değerleri teker teker x =
−1, 0, 1, 2 değerlerini u(x)’i hesaplayarak kontrol edelim.

6/5 + 3/5(−1) = 3/5 = 0.6

6/5 + 3/5(0) = 6/5 = 1.2

6/5 − 2/5(1) = 4/5 = 0.8

6/5 − 2/5(2) = 2/5 = 0.4

Sonuçlar birebir uyuyor.


Alternatif Çözüm
Problemin cebirsel çözümü için bir yöntem daha var, hatta ders notlarındaki 1.2.2
çözümü bu yöntemi kullanıyor.
u(x)’in formunun lineer olacağını bildiğimizden, ve bu formül içinde bir rampa
fonksiyonu olmasından hareketle, çözümün iki lineer parça içerdiğini ve bu parçaların
0 noktasında birleştiğini farzedebiliriz. Şöyle iki fonksiyon buluruz: A(x + 2) ve
B(x − 3). Bu her iki fonksiyonun -2 ve +3 noktalarında sıfır olduğuna dikkat, ki
bu diferansiyel denklemin sınır şartları ile uyumlu.
Şimdi alttaki numaralara bakalım, tek bir integral, ve tek bir türev alarak çok
daha basit cebirsel ifadelerle çalışma imkanı var. İki tarafın entegrali:
Z Z
00
− u (x) = δ(x)

−[u 0 (x)]RL = 1

R ve L sağ (right) ve sol (left) ibareleri, delta fonksiyonunun yoğunluk yarattığı


noktanın sağındaki ve solundaki herhangi birer nokta için kullanılıyor, delta fonksiy-
onunun entegralini alırken bu noktanın “üzerinden geçersek” sonuç her zaman 1

3
verecektir. O noktaların tam olarak ne olduğu önemli değil, çünkü x = 0 solunda
ve solunda eğim her noktada aynı.

uR0 (x) − uL0 (x) = −1

Üstteki türevleri formlara uygularız

B − A = −1

İki parça x = 0 noktasında birleşiyor, o zaman

A(0 + 2) = B(0 − 3)

3
A=− B
2

Birleştirince

B − (−3/2B) = −1

B = −0.4

A = 0.6

Soru 1.2.4
  
1 0 1 −1
 −1 1 0  0 1 −1 
Tn = (geri)(−ileri) =  (1)
  
.. ..  . . . . . . −1 
 . . 0  
−1 1 0 1

.. 1
   
1 1 .
1 1
. 1 1 1
1 .. 
    
Tn−1 =
 1   ...
 
..

(2)
1 1
 
 1 1   . 
.. 1
1 1 . 1 1

(1)’deki geriye doğru farklar matrisi ∆− tersinin (2)’deki toplamlar matrisi olduğunu
kontrol edin. Dikkat: ∆0 = (∆+ +∆− )/2 ifadesinin tersi olmayabilir! ∆0 u = 0 den-
klemini n = 3 ve n = 5 için çözün.

4
import scipy.linalg as lin

DB = lin.toeplitz([1, -1, 0], [1, 0, 0])


print DB; print lin.inv(DB)

DF = lin.toeplitz([-1, 0, 0], [-1, 1, 0])

D_0 = (DF + DB) / 2


print D_0
[[ 1 0 0]
[-1 1 0]
[ 0 -1 1]]
[[ 1. 0. 0.]
[ 1. 1. 0.]
[ 1. 1. 1.]]
[[ 0 0 0]
[-1 0 0]
[ 0 -1 0]]

D_0 matrisini soruda istendiği şekilde yarattık.


Bu matrisin sıfır uzayı, yani D_0 u = 0
denklemindeki u sıfır olmadığı için, bu matris tersine çevirilemez demektir, yani
matris eşsiz (singular) demektir.
Soru 1.2.10
27. denklemden bahsediliyor, bu yanlış. Sorunun istediğini kodlamak daha iyi:
∆+ için DF ve ∆− yerine DB kullanıp, çarpımını alırsak,

import scipy.linalg as lin

DB = lin.toeplitz([1, -1, 0], [1, 0, 0])


print "backward"
print DB

DF = lin.toeplitz([-1, 0, 0], [-1, 1, 0])


print "forward"
print DF
print 'product'
print np.dot(DF, DB)
backward
[[ 1 0 0]
[-1 1 0]
[ 0 -1 1]]
forward
[[-1 1 0]
[ 0 -1 1]
[ 0 0 -1]]
product
[[-2 1 0]
[ 1 -2 1]
[ 0 1 -1]]

Bu matriste u = 0 sınır şartının hangi satır ile temsil edildiği soruluyor, yani
u(..) = 0 şartında ’..’ neresi? Bu şart için sol taraftaki kolonun atıldığını hayal

5
edelim, geriye kalanlar üst 1. satırı [-2 1] üzerinden u(0) = 0 şartını zorlar. Doğru
cevap 1. satır.
Peki u 0 (..) = 0 şartı hangi satırla, yani hangi ’..’ değeriyle zorlanır? En alt satır
gibi duruyor, kontrol edelim,

u4 − u3
=0
h
o zaman

u4 = u3

Matrisin en son satırını cebirsel şekilde yazalım

u4 − 2u3 + u2
h

u4 = u3 olduğu için

u3 − 2u3 + u2
=
h

−u3 + u2
=
h

Son ifade matrisin sonuncu satırını aynen tarif ediyor.


Soru 1.2.19
Bir merkezi farksal yaklaşıksallama (difference approximation) kur, bunu ya-
parken K/h2 ve ∆0 /2h kullan, tüm bunları

−u 00 + u 0 = 0.

çözmek için kullan, ki u(0) = 0 ve u(1) = 0. Ayrı olarak du/dx için öne doğru
farksal (forward difference) ∆+ U/h kullan. Dikkat edelim ∆0 = (∆+ + ∆− )/2.
Ortalanmış u ve ortalanmamış U’yu çözelim, ki h = 1/5 olsun. Gerçek u(x)
u = x özel çözümüdür ve bu çözüme A+Bex eklenir. Hangi A ve B sınır şartlarını
tatmin eder? u ve U ne kadar u(x)’e yakındır?
Cebirsel olarak bu denklemi çözmek için onun sabit katsayılı, 2. seviye (homojen
olmayan -sıfıra eşit değil-) denklem olduğunu görmek yeterli. Önce ana den-
klemle bağlantılı homojen denklemi (sıfıra eşitlenmiş halini yani) çözeriz.

−u 00 + u 0 = 0.

6
Bu denklemi çözmek için karakteristik denklemini buluruz, bkz [2]. Bu denklem
−r2 + r = 0 olacaktır, kökleri 0 ve 1, o zaman homojen denklemin çözüm yel-
pazesini e0x = 1 ve ex tanımlar. Genel çözüm demek ki

s + A + Bex

olur, ki A ve B rasgele sabitlerdir, ve s, −u 00 +u 0 = 1 denkleminin özel (particular)


bir çözümüdür. u(x) = x’in bu özel çözüm olduğunu bulmak zor değildir, o
zaman çözümün tamamı

u(x) = x + A + Bex

olacaktır.

u(0) = A + B = 0

A = −B

u(1) = 1 + −B + Be1 = 0

1
B=
1−e

−1
A=
1−e

Denklemin tam çözümü

1 1 x
u(x) = x − + e
1−e 1−e

import scipy.linalg as lin

K,T,B,C = ktbc(4); print K

C = lin.toeplitz([0, -1, 0, 0], [0, 1, 0, 0]); print C

print "ortalanmis", lin.solve((25*K + 2.5*C), [1.,1.,1.,1.])

F = lin.toeplitz([-1, 0, 0, 0], [-1, 1, 0, 0]); print F

print "ileri farklilik", lin.solve((25*K + 2.5*F), [1.,1.,1.,1.])

def ux(x): return x - 1/(1-np.e) + np.e**x/(1-np.e)

7
print ux(0.2), ux(0.4), ux(0.6), ux(0.8)

[[ 2. -1. 0. 0.]
[-1. 2. -1. 0.]
[ 0. -1. 2. -1.]
[ 0. 0. -1. 2.]]
[[ 0 1 0 0]
[-1 0 1 0]
[ 0 -1 0 1]
[ 0 0 -1 0]]
ortalanmis [ 0.07135546 0.11412325 0.12195055 0.0870728 ]
[[-1 1 0 0]
[ 0 -1 1 0]
[ 0 0 -1 1]
[ 0 0 0 -1]]
ileri farklilik [ 0.07956826 0.123533 0.12793827 0.08838856]
0.0711487519142 0.11376948211 0.121546007893 0.0867637263024

Bu çözümlerden ortalanmış olanın daha iyi olduğunu görebiliriz.


Soru 1.2.21
u(h) = u(0) + hu 0 (0) + 12 h2 u 00 (0) + .. açılımını ve “sıfır eğim koşulu” yani u 0 (0) =
0 olarak belirtilen sınır şartını ve −u 00 = f(x) ifadesini kullanarak u0 − u1 =
1 2
2
h f(0) şeklinde üst sınır şartını türet. 21 faktörü O(h) hatasından kurtulmamıza
yarayacak.
Öncelikle türetmemiz istenen şeyin 2. Ders Problem 1.2 A’da kullanılan ifade
ile aynı olduğunu görelim. O problemde u0 − u1 = 21 h2 f(0) ifadesine farklı bir
yönden erişmiştik, orada ortalama farklılık tekniğini kullanmıştık. Burada Taylor
açılımını kullanıyoruz, ve aynı noktaya geliyoruz!
u(0) noktasındayız, ve ileri doğru h adımı atıyoruz, bu adımı Taylor açılımı ile
nasıl gösteririz?

1
u(h) = u(0) + h · u 0 (0) + h2 u 00 (0) + ...
2
Değil mi? Şimdi, elimizde diferansiyel denklemin tanımından gelen bazı tanımları
kullanarak üstteki denklemi değiştirelim. −u 00 (x) = f(x) ise, u 00 (0) = −f(0) de-
mektir. Ayrıca u 0 (0) = 0 ise h · u 0 (0) denklemden atılabilir. Noktadan sonrasını
biz atıyoruz, yaklaşıksal olarak temsil ettiğimiz için, o zaman

1
u(h) = u(0) − h2 f(0)
2

1
u1 − u0 = − h2 f(0)
2

1
u0 − u1 = h2 f(0)
2

8
Ve Çözülmüş Problem 1.2 A’daki tanımın aynısına eriştik.
Problem 1.4.5
−u 00 = δ(x − a) denkleminin serbest-serbest şartları, yani u 0 (0) = 0 ve u 0 (1) = 0
üzerinden çözümü olamayacağını göster, bu durumda C ve D sabitleri buluna-
mayacak.
Çözüm
Tam çözüm neydi?

u(x) = R(x − a) + Cx + D

Eldeki şartlar sadece u 0 (x) için olduğuna göre üstteki denklemin türevini alalım,
ve 0 ve 1 değerlerini yerine koyarak ele geçen sonuca bakalım.

u 0 (0) = 0 + C = 0

Rampa fonksiyonunun türevi basamak fonksiyonu, fakat o noktada daha basamak


başlamamış (yani sıfır seviyesinde). Aslında soruda a > 0 bilgisini verseler iyi
olurdu, her neyse, bu sebeple ilk terim 0. Cx’den geriye C kalır, D yokolur.

C=0

Diğer koşulla

u 0 (1) = −1 + C + 0 = 0

Bu noktada basamak başlamış, çünkü a noktası ilerisindeyiz, basamak fonksiy-


onu 1 değerinde, negatifi alındığı için sonuç -1. Devam edersek:

C=1

Bu bir absürtluk ortaya çıkartı, C’nin hem 0 hem 1 olması mümkün değildir. De-
mek ki serbest-serbest probleminin çözümü yoktur.
Teori
Z∞
δ(x)g(x) dx = g(0)
−∞

İspat

9
δ(x) = 0 x 6= 0 için sıfır olduğuna göre, entegrasyon operasyonunun tek kullan-
abileceği değer g(0) değeridir (çünkü diğer her yerde iç çarpım sıfır), ki bu değer
de bir sabit olarak addedilebilir ve entegralin dışına çıkartılır [1, sf. 416]. Yani
Z∞ Z∞ Z∞
δ(x)g(x) dx = δ(x)g(a) dx = g(a) δ(x) dx = g(a) · 1 = g(a)
−∞ −∞ −∞

Alternatif İspat
Parçalı entegral yöntemini uygularsak,
Z Z
u dv = uv − v du

u = g(x), dv = δ(x) dx

ZA A ZA
dg(x)
g(x)δ(x) dx = g(x)u(x) − u(x) dx
−A −A −A dx

−A ve A entegral sınırları sıfırı ortalayacak şekilde seçilmiş iki değerdir, A her-


hangi bir sayı olabilir. u(x) δ(x) fonksiyonunun entegrali olduğuna göre x = 0
öncesi sıfır, sonrası 1 olacak. O zaman birinci kısım

A A
g(x)u(x) = g(x)u(x) = g(A) · 1 = g(A)
−A 0

x = 0 öncesi önemli değil çünkü orada u(x) = 0.


İkinci kısım

ZA
dg(x)
1· dx = g(A) − g(0)
0 dx

Biraraya koyarsak

g(A) − (g(A) − g(0)) = g(A) − g(A) + g(0) = g(0)

İspat böylece tamamlanıyor.


Kaynaklar
[2] Bayramli, Diferansiyel Denklemler, Ders 9

10
Ders 5
Önceki derste −u 00 = δ(x − a) denklemini çözmüştük. Ayrıksal olarak bu den-
klem sol tarafta matris −K, sağ tarafta ise noktasal ağırlığı tek hücre içinde 1 olan
bir vektöre tekabül edecektir. K bağlamında 1 -2 1 formu, -1 2 -1 haline gelir, u
vektörü önceki gibi, sağ tarafta ise ayrıksal delta fonksiyonu. Ağırlığın 2. hücrede
olduğu örnek alttadır.

   

2 −1 0 0 u1 0
 −1
 2 −1 0   u2
    1 
= 
 0 −1 2 −1   u3   0 
0 0 −1 2 u4 0

Ortaya ilginç bir durum çıktı: sağ taraftaki matrise bakarsak, ağırlık 2. hücrede
ve orası 1. Eğer 3. olsaydı 3. hücre 1 olurdu, vs. Tüm bu vektörleri yanyana
koysak, birim matrisini elde etmez miyiz? Evet. O zaman bir kolaylık ortaya
çıktı. Ağırlık j üzerinde ise o vektörü δj ile temsil edersek,

Ku = δj

δj yerine I kullanırsak, ve u vektörü yerine U kullanırsak,

KK−1 U = I · K−1

U = K−1

olacaktır. U içinde her türlü j olasılığı için bir çözüm içeriyor. Eğer j = 2 olasılığının
çözümünü görmek istiyorsak o zaman K−1 matrisinin yani U’nun 2. kolonuna
bakmak yeterli.
Peki, eğer yük tek bir nokta yerine “tüm” noktalarda olsaydı ne yapardık? Tüm
noktalardaki yük eşitliğin sağ tarafının tamamen 1 olması demektir. O zaman bir
başka numara yaparak, tamamen 1 içeren bu vektörü ayrı ayrı δj ’ler “toplamı”
olarak görebiliriz, mesela

       
1 0 0 0 1
 0   1   0   0   1 
 + + + = 
 0   0   1   0   1 
0 0 0 1 1

Bu ne demektir? Eşitliğin sağ tarafının “girdi” olarak görülebildiğini de biliy-


oruz. Lineer bir sistemde girdiler toplanırsa, mümkün tüm çıktılar da toplanır.
Üstteki K−1 ’in kolonları da bu mümkün tüm çıktıları zaten verdiğine göre tek
yapmamız gereken bu kolonları birbiriyle toplamaktır.

1
Green’in Fonksiyonu
−u 00 ’ya eşit olarak bir noktasal ağırlık (point load) yani delta fonksiyonu varsa
çıkan sonuç Green’in fonksiyonu olarak bilinir ve bu fonksiyon G(x, a) olarak ta
gösterilebilir, çünkü Green’in fonksiyonu hem x’e hem a’ya bağlıdır. Ayrıksal,
sürekli (continuous) bağlamında ise Green’in fonksiyonu üstte gösterilen matris
tersi işleminin sürekli hali olarak düşünülebilir.
Özdeğerler ve Özvektörler (Eigenvalues and Eigenvectors)
Özdeğerler Ay = λy formunda ortaya çıkarlar. Eğer bir problemde bu formu
bulabilirsek, çözüm için müthiş kolaylık sağlayan bir kavramdırlar. Özdeğerler
λ içinde, özvektörler y içinde bulunur.
Bu kavram hakkında anlayış geliştirelim. Mesela elimizde bir v vektörü var, ve A
matrisi ile çarpılıyor. Sonuç yine bir vektör olacak, bu vektör Av vektörü.

Eğer o vektör yukarıdaki gibiyse, v bir özvektör değil demektir. Niye? Çünkü
özvektörler özel vektörlerdir (her A için) , öyle değerlere sahiptirler ki A ile çarpılınca,
çizgisel yönleri değişmez (ama boyları değişebilir). Diyelim ki elimizde bir y var,

Ay alttaki gibi olabilir

2y olabilir, ters yönde büyüyebilir, sıfır haline de gelebilir, vs. Fakat muhakkak
aynı çizgi üzerinde kalır, λ değeri de 2, sıfır, vs gibi büyümenin, küçülmenin ne
kadar olduğunu belirten değer olacaktır. Fakat, tekrarlamak gerekirse, özvektörler
nadirdirler zaten tarif edildiği şekilde davranan bir vektörün az rastlanan bir şey
olması normal olmalıdır.
Bunun faydası, değeri nedir? Özvektör bize öyle bir yön sağlar ki o yönde A bir
sayı gibi davranır. A, y vektörünü “değiştiren”, onu transform eden bir fonksiyon-
dur bir bakıma, ve bu fonksiyon ne kadar çetrefil olursa olsun belli bir “özel”
yönde sadece sayı etkisi yapmaktadır. Mesela

2
du
= Au
dt
diyelim ki u 1000 boyutunda bir vektör, A 1000 x 1000 boyutunda bir matris.
Denklem çok büyük, ama diyelim ki biz bu A için öyle bir özvektör ve özdeğer u
biliyoruz ki (eğer bu değerler problem içinde mantıklı değerler de iseler) o zaman
şunu da biliyoruz ki çözüm o yönde başlarsa o yönde kalır.
O zaman elimizde bir skalar var demektir (çünkü A yönde tek sayı etkisi yapıyor)
yani üstteki diferansiyel denklem u 0 = Au yerine u 0 = λu haline gelebilir.
Bu daha basit denklemin direk analitik çözümünü biliyoruz:

u = ceλt

λ özdeğer olarak belli bir yöndeki büyüme, küçülmeyi gösteriyorsa, üstteki formül
içinde de benzer anlamı taşır: Artı λ üstel değer üzerinden ona oranlı bir büyümeyi,
eksi olanı o oranda bir küçülmeyi gösterir. Güzel. Kavramlar birbiriyle bağlantılı
çıkıyor, demek ki doğru yoldayız.
Diğer kullanımlar? Temel denklemi tekrar yazalım.

Ay = λy

Soru şu: A2 için öyle bir vektör arıyorum ki A ile iki kez çarpınca yön değiştirmiyor.
Cevap, yine özvektör y. Çünkü y’yi A ile çarpınca λy çıkıyor, yön hala değişmedi,
o zaman bir daha çarparsak, yön hala aynı kalır, bu sefer sonuç λ2 y.

A 2 = λ2 y

Özvektörler diferansiyel denklemler için, bir matrisin üstel değerlerini hesapla-


mak için çok faydalıdırlar. Bir matrisin pivotları sabit konum (steady-state) prob-
lemini incelerken de elimizdeki önemli sayılardır. Hareket halindeki bir maddeyi
incelerken yardımcı olurlar, salınımı (oscillate) olan, büyüyen, küçülen şeyleri in-
celemekte de faydalıdırlar.
Eğer λ kompleks bir sayı olsaydı? O zaman λ’nin reel bölümüne bakardık, < 0 ise,
stabil küçülme (decay), büyük ise stabil olmayan büyüme (growth) olurdu. Eğer
e4it gibi bir değer olsaydı, bu pür salınım olacaktı, çünkü açılımı cos(4t)+i sin(4t)
formülüdür.
Diğer bir soru: k büyürken Ak → 0 ise, yani A’yi sürekli kendisi ile çarparken
sonuç hep küçülüyorsa, bu durumu λ’ya bakarak nasıl anlayabilirim?
Ak y ise λk y demektir (üstte gördük), o zaman Ak y’nin nasıl davranacağını λk y’a
bakarak anlayabilirim. λk y ne zaman sıfıra gider? Cevap: λ < 1 olduğu zaman.
Kompleks λ’li Reel Matris

3
Diyelim ki elimizde bir vektörü 90 derece döndürebilen bir A matrisi var.

 
0 −1
A=
1 0

Bu matrisin reel özdeğerleri olamaz, çünkü bu matrisin uygulanıp yönü değişmeyen


hiçbir “reel” vektör olamaz. Gözle görülebilen her vektör 90 derece transform
edilir. İşte bu gibi örneklerde özdeğer bulmak için kompleks vektörler gerekir.
 T
Şu vektörü deneyelim: 1 i .

      
0 −1 1 −i 1
= = −i
1 0 i 1 i

Vektör ise yaradı. Şimdi ana noktaya gelelim. Özdeğerleri nasıl kullanırız? Ve on-
lardan kaç tane vardır? “İyi” bir matris, ki bu tanıma her simetrik matris dahildir,
eğer mesela büyüklüğü 1000 ise, o zaman 1000 tane farklı özvektörü olacaktır.
Simetrik matrislerde de o özvektörlerin hepsi reel olacaktır. Mesela:

 
2 −1
−1 2

2 x 2 boyutunda bu matriste 2 tane özvektör bulmamız lazım. Bu ufak bir matris,


 T
özvektörleri tahmin yapa yapa bulmaya uğraşabiliriz. 1 0 bir özvektör mü?
Çarpımı yaparsak,

    
2 −1 1 2
=
−1 2 0 −1
 T
Olmadı. Sağdaki vektör 1 0 ’in bir katı değil. Not: Lineer cebirde kafadan
 T
işlem yapmanın yollarından biri, 1 0 ile çarparken 1 görünce, soldaki ma-
 T
trisin “1. sol kolonunu olduğu gibi almak”. Peki 1 1 denersem?

    
2 −1 1 1
=
−1 2 1 1
 T
Bu oldu. İkinci özvektör ne olabilir? 1 −1 deneyelim.

    
2 −1 1 3
=
−1 2 −1 −3
 T  T
Bu da oldu. O zaman λ1 = 1, λ2 = 3, özvektörler 1 1 ve 1 −1 . Bu
özvektörlere bana ne söylüyor? Onlara bakarak ana matris hakkında ne anlaya-
 T  T
bilirim? Bakalım, 1 1 ve 1 −1 birbirine dikgen (orthogonal) vektörler.

4
Cebirsel olarak bu dikliği anlamak için yT1 y2 , ya da y1 · y2 hesabını yapabilirdik,
diklik var ise sonuç sıfır çıkardı. Özvektörlerin dikliği başka bir şey daha söyler,
simetrik matrislerin özvektörleri birbirine diktir, o zaman sadece özvektörlere
bakarak ana matrisin simetrik olduğunu anlayabilirdik.
Söylemeye çalıştığımız özdeğer ve özvektörler matrisleri incelemenin, onların
“içine bakmanın” yollarından bir tanesidir.
Peki üstteki simetrik olmayan matrise dönersek

 
0 −1
1 0

Bu matrisin özvektörleri kompleks çıkmıştı, ki bu durum simetrik olmayan ma-


trislerin bir özelliğidir. Simetrik matrisleri bu sebeple tercih ederiz, özvektörleri
reel, birbirine dik.
Özdeğerler üzerinde güzel iki tane faydalı kontrol mekanizması: λ1 = 1, λ2 = 3
bulduğumuz örnekte iki özdeğer toplamı nedir? 4. Ana matrisin çaprazındaki
değerleri toplarsak (buna matrisin “izi” -trace- adı da verilir)

 
2 −1
−1 2

Sonuç yine 4. Bu iki toplam her zaman eşit çıkmalıdır. Bir numara: bir tanesi
hariç tüm özdeğerleri bulduksak matrisi izini kullanarak sonuncu özdeğeri hızla
bulabiliriz, çünkü çapraz toplamından diğer özdeğer toplamını çıkartırız, kalan
sonuncu özdeğer olmalıdır.
Bir kontrol daha. Özdeğerleri birbiriyle çarparsam sonuç 3 çıkar. Ana matrisin
determinantını alırsam sonuç yine 3 çıkar. Bu iki kontrol tekniğini, ispatını göstermeden,
burada vermiş olalım.
Kullanıma gelelim: Diyelim ki elimizde içinde 1000 tane denklem içeren bir lineer
denklem sistemi var.

du
= Au
dt

katsayılar sabit, başlangıç noktası u(0). Özdeğer ve özvektörler burada nasıl


yardımcı olabilir? Önce onları bulmamız gerekir, 1000 tane özvektör var, onları

5
buluruz. Her i için

Ayi = λi yi

yani elimizdeki özvektörler y1 , .., y1000 , özdeğerler λ1 , ..., λ1000 .


Bu değerleri diferansiyel denklemi çözmek için nasıl kullanırım? 3 tane basamak
takip ederim.
1. u(0)’i özvektörlerin bir kombinasyonu olarak temsil et, yani u(0) = c1 y1 + ... +
c1000 y1000 .
2. eλ1 t ’yi c1 ile çarp, yani c1 ’i onun büyümesi ile çarp, genel olarak eλi t ’yi ci ile
çarp.
3. Topla: c1 eλ1 t y1 + .. + c1000 eλ1000 t y1000 .
Not: Bunun niye işlediğinin ispatı için [3]’e bakılabilir.
Not: Konuyla ilgili bir problem bu notların en altında.
Tabii bunu işlemesi için u(0)’in özvektörlere, özdeğerlere göre parçalanması gerekir,
ayrıca tüm özvektörlerin bulunabiliyor olması gerekir. Problemimiz bize simetrik
bir matris sağlıyorsa sorun olmaz, ama bazı problemlerde matris “defolu” ola-
bilir, bazı özvektörler birbirlerinin içine girerler (collapse) ve elde yeteri kadar
özvektör olmaz. Yani çözmeye çalıştığımız probleme göre bu tekniği kullanabilir
ya da kullanamayabiliriz.
Not: Özvektörlerin birbirine yakın, hatta eşit olma problemi ODE’lerdeki kri-
tik sönümlü (critically damped) koşulda köklerin birbirine eşit çıkmasıyla aynı
durum, bkz [2]. Orada yeni bir çözüm “yaratmak” için e−at ile t’yi çarpmıştık.
Burada da özdeğerleri aslında kökler olarak görebiliriz, eğer iki özdeğer eşit ise,
elimde sadece bir tane özvektör olma riski de yüksek demektir. O zaman yeni bir
çözüm yaratmak için ODE dünyasındakine benzer bir numara kullanırım, teλt
hesabını yapabilirim.
Ek Açıklamalar
u(0)’i A’nin özvektör lineer kombinasyonu olarak temsil edilirse, sonucun c1 eλ1 t y1 +
.. + cn eλn t yn şeklinde olabileceğini nereden biliyoruz? Çünkü du/dt = Au ve
Au = λu lineer denklemler. Bir sonraki adım için u(0) değiştirildiğinde, bu li-
neer bir şekilde, A üzerinden olacak, ve A’ya “girdi” olarak verilen vektörler
eğer özdeğerlerin kombinasyonu ise, bu kombinasyon çıkışa da aynen, verildiği
şekilde yansıyacak.
Bölüm 1.5 Örnek 4 (Kitaptan)
Diyelim ki vektörel formdaki bir u(t) denklemi ABD’de Missisipi nehrinin doğusu
ve batısında t anındaki nüfusu temsil ediyor. Şöyle:

6
u(t + 1) = Au(t)

Bu vektörel u(t)’yi bileşenleriyle şöyle açıklayalım

    
t + 1 anında doğuda olanlar .8 .3 t anında doğuda olanlar
=
t + 1 anında batıda olanlar .2 .7 t anında batıda olanlar

Buradaki A matrisi belli bir gözleme dayanarak modelleyicinin bulduğu bir şey
herhalde, problem onu bize veriyor. A bir “geçiş fonksiyonu”, t anından t + 1’e
geçişi o yapıyor. Diyelim ki doğuda 1 milyon insanla başladık, 1 sene sonra (A
ile çarpıyoruz) yeni rakamlar 800,000 ve 200,000 haline gelecektir.
A matrisi bir Markov matrisidir, Markov matrislerinin kolonlarının iç toplam-
ları her zaman 1’e eşittir. Özdeğer / özvektör bağlamında Markov matrislerinin
ilginç bir yanı özdeğerlerinden birinin her zaman 1 olmasıdır, yani λ = 1 muhakkak
olacaktır. İki boyutlu A matrisi durumunda bu çok ise yarar, çünkü matris izine
(trace) bakarak ve ondan 1 çıkartarak ikinci özdeğeri hemen bulabiliriz. A’nin
özvektörleri de λ = 1 için [600,000, 400,000], λ = 0.5 için [400,000, -400,000]
değerleridir.
Şimdi ilginç bir numara: eğer başlangıç değeri [1,000,000 0]’i özvektörlerin bir
kombinasyonu olarak gösterirsek,

u = [1, 000, 0000] = a1 · [600, 000, 400, 000] + a2 · [400, 000, −400, 000]

a1 ve a2 1 değerine eşit.
Soldan A ile çarpalım

Au = A a1 · [600, 000, 400, 000] + A a2 · [400, 000, −400, 000]

Au = a1 A · [600, 000, 400, 000] + a2 A · [400, 000, −400, 000]

Au = a1 λ1 · [600, 000, 400, 000] + a2 λ2 · [400, 000, −400, 000]

λ1 ve λ2 nereden geldi? Özvektörlerin tanımından: Ax = λx. Üstteki kombi-


nasyonda kullandıklarımız özvektör olduğuna göre, onların A ile çarpılmış hali
onların tekrar özdeğerle çarpılmış halini verecektir.
Ayrıca λ1 = 1 olduğuna göre, onu denklemde göstermeye gerek bile yoktur
(Markov matrisi içeren problemlerin bir güzel yan etkisi oldu bu). a1 ve a2 zaten
1 değerine eşitti, onları da atabiliriz. Yani,

7
Au = [600, 000, 400, 000] + λ2 · [400, 000, −400, 000]

Şimdi geçiş işlemini birkaç kere üst üste yapalım:

A2 u = [600, 000, 400, 000] + λ22 · [400, 000, −400, 000]

A3 u = [600, 000, 400, 000] + λ32 · [400, 000, −400, 000]

...
Böyle devam edecek. λ2 = 1/2 olduğuna göre, ve bu değer 1’den küçük olduğu
için n büyüdükçe λn
2 çok küçük bir sayı haline gelir, ve sıfıra yaklaşır. Yani üstteki
denklemin sabit konum (steady-state) çözümü [600,000, 400,000] değeridir.
Örnek Problem

du
= Au
dt

problemini çözdüğümüzü farzedelim, ki u(t) şöyle tanımlı

 
y(t)
u(t) =
z(t)

Ayrı ayrı

dy/dt = 2y − z

dz/dt = −y + 2z

Matris formunda

    
d y 2 −1 y
=
dt z −1 2 z

ki yukarıdaki 2x2 matris A matrisi olacak. Lineer Cebir Ders 23’te görüldüğü gibi
bu problemin çözümü

u = SeΛt S−1 u(0)

[1, sf. 53]’te bu problemin sadece

8
u = SeΛt v(0)

noktasına kadar gelinip bırakıldığı bir bölüm var, bu bölümün sonucunu üstteki
 T
u formülüne göre yineden türetelim. v(0) = C D şeklinde bir vektör tanımlayalım,
bunları başlangıç değerlerinin özvektörleri nasıl kombine ettiğini gösteriyor. A
 T
matrisinin özdeğerleri λ1 = 1 ve λ2 = 3, ona tekabül eden özvektörler 1 1
 T
ve 1 −1 . O zaman

     
1 1 eλ1 t C y(t)
u(t) = =
1 −1 eλ2 t D z(t)

Bu çarpımı ayrı ayrı yapınca çözümün kitapta gösterildiği gibi

Cet + De3t
   
y(t)
=
z(t) Cet − De3t

olarak çıktığını göreceğiz.


Kaynaklar
[1] Strang, Computational Science
[2] Bayramli, Diferansiyel Denklemler, Ders 9
[3] Bayramli, Lineer Cebir, Ders 23

9
Ders 1.6
Özvektör formülüne tekrar bakalım

Ay = λy

Şimdi tüm özvektörler aynı anda tek bir matris içinde olacak şekilde üstteki formülün
her özvektör için işleyecek “kombine” bir halini yazabiliriz. yi vektörünün tüm
bir kolonu kaplayacak şekilde matrise yazıldığını düşünüyoruz.

   
↑ ↑ ↑
A  y1 y2 ... yn  =  Ay1 Ay2 ... Ayn 
↓ ↓ ↓

Buna göre üstteki eşitliğin sağındaki çarpım da mantıklıdır.Peki Ayi çarpımı tanıdık
gelmiyor mu? Çarpım özvektör, özdeğer formülü. O zaman Ayi = λyi . Demek
ki,

   
 Ay1 Ay2 ... Ayn  =  λ1 y1 λ2 y2 ... λn yn 

λ’ları dışarı çekebiliriz.

  
λ1
=  y1 y2 ... yn   .. 
λn

λ matrisinde λ olmayan yerler sıfır değerini taşıyor. Özvektör matrisini S olarak,


çaprazında özdeğerleri taşıyan matrisi Λ olarak nitelersek

AS = SΛ

Eğer üstteki S (ya da herhangi bir) matrisinin tüm kolonları birbirinden bağımsız
ise S tersine çevirelebilir (invertible) demektir. O zaman şunu yapabiliriz:

A = SΛS−1

Bu forma matrisin köşegenleştirilmesi (diagonalization) deniyor.


Biraz zihin egzersizi: A2 ne olur?

A2 = (SΛS−1 )(SΛS−1 )

1
= SΛS−1 SΛS−1

ortadaki S ve S−1 birbirini iptal eder.

= SΛ2 S−1

Bu bana ne söylüyor? A2 ’nin özvektörleri A ile aynı, çünkü formülün S ve S−1


içeren kısmı değişmedi, özdeğerler ise A’nin özdeğerlerinin karesi. Bu önceden
bulduğumuz A2 y = λ2 y sonucu ile uyuşuyor.
Peki, diyelim tersine çevirilebilir ise, A−1 nedir? Ana formülden başlayalım

A = SΛS−1

Tersine çevirme işlemi eşitliğin sağ tarafında parantezin içinin sırasını değiştirir,
sonra tersine çevirir, S−1 ile başlarız, onun tersi S, vs, ve sonuç

A−1 = SΛ−1 S−1

Özvektörler matrislerinin yeri ve içeriği değişmedi. Değişik olan tek şey Λ−1
ki bu matris içinde 1/λ1 , 1/λ2 , .. gibi değerler olacak. Diğer bir açıdan kontrol
edelim:

Ay = λy

y = λA−1 y

1
y = A−1 y
λ

Bu üstteki sonuç ile aynı şeyi söylüyor. A−1 ’in tersi aynı y özvektör(ler)e sahip,
ve solda olan özdeğer öncekine kıyasla 1/λ değerinde.
Tabii tüm bunlara başlamadan önce “λ’nin sıfır olmadığı durumlarda” demeliy-
dim, çünkü bu sıfırlık durum bize A’nin tersine çevirilir olmadığı yönünde bir
işaret olurdu. Terminoloji olarak bir tane bile sıfır özdeğer A eşsiz (singular) de-
mektir, eğer hiçbiri sıfır değilse A tersine çevirilebilir demektir.
Bir simetrik K matrisini ele alalım, simetrik olduğu için tüm özdeğerleri reel
sayılar, ve özvektörleri birbirine dikgen (orthagonal).
Dik yerine normalize edilmiş de diyebilirdik, sayısal paketler çoğunlukla birimselleştirilmiş,
yani uzunluğu 1 olan vektörler döndürür, ve özdeğer/vektör ikilisi için zaten

2
yön önemlidir, hem özdeğer hem özvektörü 2 ile çarpıp aynı şeyi elde edebiliriz
mesela.
Uzunluktan bahsederken, onu daha önce yTi · yj olarak gösterdik, ki simetrik
bir matrisin dik özdeğerleri için bu yTi · yj = 0, i 6= j. Normalize edilmiş bir
özvektörün kendisi ile noktasal çarpımı nedir? yTi · yi = 1 çünkü vektör birimsel,
uzunluğu 1. Tüm özdeğerleri içeren matris üzerinden bu hesabı yapabilir miyiz?
Daha önce yarattığımız şu matris ile başlayalım:

 
↑ ↑ ↑
 y1 y2 ... yn 
↓ ↓ ↓

sol tarafına devriğini (transpose) koyalım

  
← yT1 → ↑ ↑ ↑
 ...   y1 y2 ... yn 
← yTn → ↓ ↓ ↓

Bu çarpımı yaparsak sonuç ne olacak? Mesela yT1 ile y1 çarpımı 1 değerinde, yT1
ile diğer her çarpım sıfır. Böyle gider. Ve sonuç olarak çaprazında 1 diğer her
yerinde 0 içeren birim (identity) matrisini elde ederiz.
Üzerine basarak söyleyelim, bu simetrik matrisler için, çünkü diğer A matrisleri
için özvektörlerin hepsinin birbirine dik olmasını bekleyemeyiz.
Devam edelim, o zaman üstteki hesabı kısaca gösterirsek

ST S = I

Bu hakikaten çok önemli bir sonuç.


Üsttekinin doğru olduğu durumlarda S harfini değiştirirsek aslında daha iyi olur
böylece özvektör matrisinin bir simetrik K matrisinden geldiğini daha iyi görürüz.
Bu durumlarda Q harfini kullanalım.
Q’ye bir “dik matris” te denebilir, çünkü QT Q = I. Bu ifadeye bakarak başka
bir şey daha söyleyebiliriz, Q’yu başka ne soldan çarparsa sonuç birim matristir?
Q−1 . O zaman QT = Q−1 de diyebiliriz.
Bir dik matris örneği görelim:

 
cos θ − sin θ
sin θ cos θ

İlk kolona bakalım, uzunluğu hakikaten 1, çünkü cos θ2 + sin θ2 = 1. Diğer kolon
da ona dik, 1. kolon ile çarpılınca sonuç sıfır olacak.

3
Not: Üstteki matrise “θ kadar döndüren matris” ismi de verilir, eldeki bir v
vektörünü Q ile çarpımı, yani Qv, o vektörü uzunluğunu değiştirmeden θ kadar
döndürecektir.
Devam edelim

K = SΛS−1

S yerine Q kullanmaya karar vermiştik

K = QΛQ−1

O zaman, daha önceden gördüğümüz eşitlik üzerinden,

K = QΛQT

Şu güzelliğe bakın. Buna mekanikte asal eksen teoremi (principal axis theorem),
matematikte spektral teoremi (spectral theorem), kuantum mekanikte köşegenleştirme
(diagonalization) ismi verilir, her yerde ortaya çıkar, pek çok şekilde kullanılır.
Ne zaman elde bir simetrik matris var ise, o zaman üstteki tanım kullanılabilir
demektir.
K matrisine geri dönelim.

2 −1
 
. .
−1 . . . .
 
 
K=
 .. 
 . 

 

Bu matris ikinci farklılıkları ayrıksal olarak temsil etmek için kullanılmıştı, es-
nek çubuğu temsil ettiği zaman sabit / sabit problemini çözüyordu. K sürekli
(continuous) bağlamda hangi diferansiyel denklemi temsil edecektir? −d2 y/dx2 .
Özdeğer, özvektör olarak ise

Ky = λy

Şöyle bir geçiş yapılabilir

d2 y
− = λy(x)
dx2
Burada ilginç bir numara var: daha önce sürekli fonksiyondan başlıyorduk, sonra
K matrisi üzerinden ayrıksal hale geçiriyorduk. Hoca burada özdeğer, özvektör

4
formundan başladı, ve sürekli forma geçti. Sonra üstteki denklemin çözümünü
bulunca, tekrar geri gidecek, ve ayrıksal olarak özvektörlerin birbirine dikliğini
göreceğiz, ve bunun sürekli bağlamda da hala geçerli olduğunu anlayacağız.
Çözümü bulmak için tahmin yöntemini kullanalım: hangi fonksiyonun ikinci
türevinin negatifi, o fonksiyonun katını verir? Sin ve cos fonksiyonları, yani y
sin ωx, cos ωx olabilir, ya da onların birleşimi olarak üstel e−iωx , eiωx formunda
olabilir.
Eğer y için sin, cos kullanırsak özdeğer ne olur? Yerine koyarsak görürüz, sin ωx’in
iki kere türevini alırsak ω iki kere dışarı çıkar, arada bir eksi değeri mutlaka or-
taya çıkar (çünkü cos 0 θ = − sin θ), eksi ile eksi çarpılır, sonuç ω2 . Hatta üstteki
tüm y seçenekleri için sonuç aynıdır.
Sınır koşullarını unutmayalım tabii. Problemin tamamı

d2 y
− = λy(x)
dx2

y(0) = 0, y(1) = 0

Sınır koşulları sayesinde tüm sin, tüm cos fonksiyonları arasından belli bazılarını
seçebileceğiz. En basit eleme y(0) = 0, bu şart sayesinde cos fonksiyonlarının
tamamı elenir. Değil mi? Çünkü cos(0) = 0 doğru olamaz. Diğer şarta bakalım,
y(1) üzerinden sin(ω) = 0 olur, tersinden düşünürsek sin(ω) ile sıfır değeri vere-
cek ω ne olabilir? π olabilir. O zaman bir çözüm bulduk:

y1 = sin πx

Elimizdeki ilk “özfonksiyon (eigenfunction)” bu. Özdeğeri nedir?

λ 1 = π2

çünkü üstte belirttik, ω2 , o zaman π2 .


İkinci değer ne olur? 2π.

y2 = sin2πx, λ2 = (2π)2 = 4π2

Eğer sınır şartlarını değiştirseydim, serbest / serbest, serbest / sabit gibi, o za-
man farklı y değerleri elde ederdim. Mesela ilk sınır şartı y 0 (0) = 0 olsaydı,
sin fonksiyonları yerine cos fonksiyonları elde ederdik, sin elenirdi çünkü sin’in
türevi cos(0) = 0 doğru bir ifade olamazdı.
Ayrıksal olarak temsil edersek, sin πh ve h = 1/n + 1, n = 4 kullanalım

5
sin π5
 
 sin 2π 
y1 =  5 
 sin 3π 
5
sin 4π
5

Bu da ikinci özvektör (özfonksiyon).

sin 2π
 
5
 sin 4π 
y2 =  5 
 sin 6π 
5
sin 8π
5

Özvektörler olduğunu söylemekle ikinci bir şey daha söylüyoruz, bu iki vektör
birbirine dik. Buradan hareketle sin(πx) fonksiyonu (iki üstteki resim) sin(2πx)
fonksiyonuna (bir üstteki resim) dik diyebilirdik, ki hakikaten öyledir. Hatta bu
matematiksel durum Fourier Serilerinin işlemesini sağlayan önemli bir etkendir.
Bu bağlantıdan devam edelim: pür vektörler olduğu zaman diklik kontrolü için
yT1 ·y2 diyordum, ve y1 ve y2 ’nin eşleşen elemanları birbiriyle çarpılıp, bu sonuçlar
teker teker toplanıyordu. Elimde y1 ve y2 için birer fonksiyon var ise, bir tarafta
sin(πx) var, her x için değişik değerler veriyor, diğer tarafta sin(2πx) var, bun-
ları çarpıp toplamam lazım. Ama elimde teker teker toplayabileceğim değerler
olmadığı için (x reel bir sayıdır, belli bir aralıkta bile sonsuz tane değere sahip
olabilir), o zaman toplama yerine entegrasyon kullanmam lazım. O zaman

Z1
yT1 · y2 = (sin πx)(sin 2πx) dx
0

Sonuç sıfır gelecek, çünkü iki fonksiyon birbirine dik.


Soru 1.5.3

import scipy.linalg as lin

def ktbc(n):
vec = np.zeros((1,n))
vec[0,0] = 2

6
vec[0,1] = -1
K = lin.toeplitz(vec)
T = np.copy(K)
T[0,0] = 1
B = np.copy(K)
B[0,0] = 1
B[n-1,n-1] = 1
C = np.copy(K)
C[n-1,n-1] = 1

return K, T, B, C

import scipy.linalg as lin


import ktbc

K,T,B,C = ktbc.ktbc(5)

u,v=lin.eig(K)

print u

print 2-np.sqrt(3), 2-1, 2-0, 2+1, 2+np.sqrt(3)

print 2*np.ones((5,1)).T - 2*np.cos((np.arange(5)+1) * np.pi/6)

[ 3.73205081+0.j 3.00000000+0.j 2.00000000+0.j 0.26794919+0.j


1.00000000+0.j]
0.267949192431 1 2 3 3.73205080757
[[ 0.26794919 1. 2. 3. 3.73205081]]

7
Ders 1.7
Bugün pozitif kesinlik (positive definite) günü. Şimdiye kadar lineer cebirin
temellerini işledik, bundan sonra uygulamalara daha ağırlık vereceğiz, tabii ki
matrisler yapacağımız her şeyin temelinde olmaya devam edecekler. Konuya şu
açılardan yaklaşacağız:
1) Testler 2) Anlam 3) Uygulamalar
İlk önce testler. Pozitif kesinlik kelimesi söyleyince matrisin simetrik olduğunu
anlamak gerekiyor, yani matrisin reel özdeğerleri var, ve pek çok diğer özelliği
de var muhakkak, mesela özvektörlerinin birbirine dik olması gibi. Bu derste
daha fazla özellik göreceğiz, ve bu ekstralar özellikler uygulamalarda hakikaten
müthiş faydalar sağlıyorlar.
Daha önce söylediğimiz gibi pozitif kesinlik lineer cebirin tamamını bir araya
getirir. Testleri şunlardır:
1) Tüm pivotlar > 0
2) Tüm üst sol determinantlar (upper left determinants) > 0
3) Tüm özdeğerler > 0
“Üst sol” ile neyi kastediyorum? 3x3 bir matriste (alttaki resim) kareye alınılmış
bölümlerden. Bunlardan birincisi sadece a değerini veriyor. İkinci üst sol de-
terminant ac − b2 (iki tane b var çünkü matris simetrik, unutmayalım) değerini
veriyor, vs. Bu iki değerin de sıfırdan büyük olması gerekiyor. Tabii ki ana de-
terminantın da > 0 olması gerekiyor. Doğal olarak ac > b2 , çaprazdaki çarpım,
çapraz dışındaki değerlerin çarpımını “pozitiflikte geçmeli”, başka türlü çıkarma
işlemi pozitif sonuç vermezdi.

Anlama gelelim. Pozitif kesinlik kavramı, bir eğrinin [eliyle dışbükey bir parabol
hareketi yapıyor, onun alt noktasını kastederek] minimumunu bulmak ile yakından
alakalı, ya da “enerjiyi azaltma” problemleriyle alakalı. Bu fiziksel anlamı bu
özelliğin uygulamalarda niye bu kadar faydalı olmasının da bir sebebi aslında.
x’in bir fonksiyonunu hayal edelim:

f(x) = xT Kx

ve diyelim ki K

1
 
a b
b c

bu derste x’in kendisi ile çarpımını ilk kez kullanıyoruz bu arada. Bu form doğal
olarak karesel bir sonuç ortaya çıkartacak. Biraraya koyarsak

  
  a b x1
f(x) = x1 x2
b c x2

Sonuç hangi boyutlarda çıkar?

T
f(x) = |{z}
x |{z}
K |{z}
x
1xn nxn nx1

Zinciri takip edersek, 1x1 boyutlarında. Temel lineer cebirden hatırlarsak, N × M


ve M × K çarpımı N × K boyutlarında bir matris çıkartır. Elde edeceğimiz 1 × 1
ise, bu tek bir sayıdır. Tek sayının bileşenleri nedir? Çarpımı cebirsel olarak takip
edersek

= ax21 + 2bx1 x2 + cx22

İşte “enerji” formülü bu, bu forma niye enerji dediğimiz ileriki derslerde uygula-
malara girince daha da iyi belli olacak. Formun çok önemli bir anlamı var.
Bu noktada üstte belirttiğim testlere bir 4. kalem ekleyebilirim, hatta önemini
belirtmek için başına yıldız bile koymak düşünülebilir!
4) x = 0 haricindeki tüm x’ler için xT Kx > 0.
Bu son formülü açıklamak için bir grafik çizelim.

Değişen her x1 ve x2 ’ya göre hesaplanan, çizilen xT Kx’in grafiği yani. Bu grafik
neye benzerdi acaba? Sıfırdan başlarsam hep yukarı gider değil mi? Bir kapa
benzerdi, ve resmi aşağı yukarı şöyle olurdu.

2
K yerine diğer bazı pozitif kesin matrisleri düşünelim. Mesela birim matris hangi
f(x)’e sebep olur? x21 + x22 , ki bu formülde mükemmel bir kap şeklini ortaya
çıkartır. Ya şu matris olsaydı?

 
1 2
2 9

Sonuç x21 + 4x1 x2 + 9x22 olurdu, o zaman şekil üst kesitinde daha eliptik bir şekilde
olurdu. Üstteki matriste 2 değerinden yukarı çıkabiliriz, ama pozitif kesinlik is-
tiyorsak bu 9 · 1’i geçmeyecek kadar olmalı.
İlginç bir durum pozitif kesinliğin tam sınırındaki durumdur. Matematikte bu tür
sınır şartları anlamak bütünü kavramakta faydalı oluyor. Mesela üstteki örnekte
2 yerine 3 olsaydı o zaman

 
1 3
3 9

Bu matrise bakalım, ikinci kolon birincisinin “katı” olduğu için hemen bu ma-
trisin eşsiz olduğunu anlıyoruz. O zaman özdeğerlerinden biri kesinlikle 0 ol-
malı. Matrisin izi özdeğer toplamını verdiğine göre ikinci özdeğer 10. Formülü
neye benzer? x21 + 6x1 x2 + 9x22 . Bu tür matrislere pozitif yarı-kesin (semi-definite)
deniyor. Özdeğerleri > 0, determinantları > 0, ve sebep oldukları f(x) > 0, yani
enerjileri > 0.
Mantık yürütmeye devam edelim. Pozitif yarı kesinlik eşsiz bir matrisin olduğu
anlamına geliyorsa, o zaman bazı x değerleri için f(x) sıfır olacak demektir. Üstteki
örnekte bu hangi değer? [3 -1]’i deneyelim, ve çarpımı yapalım

    
1 3 3 0
=
3 9 −1 0

Hakikaten de x1 = 3 ve x2 = −1 kullanınca x21 + 6x1 x2 + 9x22 formülünün sıfır


sonucunu verdiğini görürüz. Şekil aşağı yukarı şöyle:

3
Hoca bu şekli çizmek için x1 üzerinde 3 birim ileri, x2 üzerinde 1 birim geri gitti,
ve o noktadan geçen bir çizgi üzerinde değişim, yukarı aşağı gidiş yok. Bu çizgi
tabii ki 3 ve -1’ın katları alınarak elde edilebilecek noktalardan oluşuyor, ve bu
noktalar üstteki matrisin “sıfırlık uzayında (nullspace)”. Pozitif kesin matrisler-
den gelen grafikler, kıyasla, böyle değildi. O grafiklerde kap uzerindeki her nok-
tadaki gidiş yönü yukarı işaret ediyordu.
Daha iyi çizilmiş bir şekil şöyle:

Şimdi de pozitif yarı-kesin bile olmayan bir matrisi düşünelim. Bu matriste çapraz
dışı (off-diagonal) değerler çok daha büyük ve “kazanıyorlar”. Örnek

  
1 5 x1
= x21 + 10x1 x2 + 9x22
 
x1 x2
5 9 x2

Bu formülü belli bazı x değerleriyle negatif yapmak mümkün. Hangi değerler


mesela? Diyelim ki x1 = −1 ve x2 = 1/2. Bu formül bazı noktalarda aşağı,
bazılarında yukarı gidebiliyor. Bu durumu ortaya çıkartan matrislere “tanımsız
(indefinite)” ismi veriliyor. Grafiği alttaki gibi, atların üzerine koyulan bir eğer
gibi.

Bunlar önemli noktalar. Şimdi biraz ileri atlayalım. Elimizde bazı seçenekler var.
Mesela tipik olarak Ku = f durumunda bir formül çözüyorduk ve tek bir çözüm
buluyorduk. Bir diğer seçenek te bir fonksiyonu, bir enerjiyi minimize etmek.
Uygulamalar için seçenekler bunlar.
Pozitif kesin matrisler alttaki ifadeden gelirler. Bu kavram test olarak ta anlamlı,

4
o yüzden testlere bir 5. kalem ekleyeceğiz.
5. K = AT A.
Bu ifade pozitif kesin. Niye? xT Kx = xT AT Ax’ye bakalım.

xT AT Ax

Bu ifade aslında şu değil mi?

= (Ax)T (Ax)

Ve bu ifadenin de (Ax)T (Ax) > 0 olduğunu biliyoruz, çünkü Ax’in devriği tekrar
kendisi ile çarpılıyor. İfadenin sıfıra eşit olması ancak Ax = 0 ise mümkündür.
Mantık zincirine devam edersek, Ax = 0’yi çözen bir x varsa (A’nin sıfır uzayı
boş değilse), yani Ax = 0’e sebep olacak sıfır vektörü haricinde bir x mevcutsa, o
zaman (Ax)T (Ax) pozitif yarı-kesin demektir, çünkü o zaman Ax = 0 olabilecek-
tir.
Ax = 0 uygulamalarda nasıl ortaya çıkar? Mesela bir yay sisteminde eğer yer
değişimi var ama yay esnemesi yoksa (Ax yay esnemesini ölçer), bu durum or-
taya çıkabilir. Peki bu nasıl mümkün olabilir, yay esnemeden, daralmadan nasıl
hareket olabilir? Eğer yay sisteminin “tamamı” kaldırılıp başka yere götürülürse.
Bu sistem serbest-serbest sistemi ile mümkün, yani iki ucun bir yere bağlı ol-
madığı bir yay sisteminde, sistem 1 1 1 vektörü ile bir yere taşınıyor. Bu
durumda matris eşsiz demektir, çünkü pozitif yarı-kesindir. Yani tipik matrisler-
imizden
K, T pozitif kesin.
B, C pozitif yarı-kesin.
Mantığa devam: Sadece ve sadece A matrisinin bağımsız kolonları var ise, o za-
man Ax pozitif kesindir.
Şimdi pozitif-kesin matrislerin tersini (inverse) düşünelim. Tersini alınca ele geçen
matris te pozitif kesin midir? Bunu kararlaştırmak için elimizde bir sürü test var.
Pivot ve determinantlara girmek biraz işleri karıştırır, ama özdeğerlere ne olur,
kendimize bunu soralım. Bu özdeğerlerin ne olacağını hemen biliyoruz, mesela
elimizde 3,4,5 gibi özdeğerler olsa (hepsi pozitif tabii ki), matrisin tersini alınca
elde edeceğimiz özdeğerler 1/3,1/4,1/5 gibi değerler olacaktır, ki bu değerler
de pozitiften. 1’den küçük olabilirler ama 0’dan büyüktürler. En basit kontrol
edilebilecek test buydu. Pozitif kesinlik için bütün testlerin doğru olması gerekir.
Peki elimizde iki pozitif kesin matris K1 ve K2 varsa

K1 + K2

5
pozitif kesin midir? Bu toplamın özdeğerlerine bakmak zor olur. Fakat 4. testi
kullanabiliriz. K1 ve K2 ’yi x ile çarpalım.

xT K1 x + xT K2 x

Formüldeki her terim sıfırdan büyüktür, çünkü bu pozitif kesinliğin tanımı. O


zaman toplam da sıfırdan büyük olacaktır. Bu sonuca eriştikten sonra, şimdi
cebirsel olarak basitleştiririz:

xT (K1 + K2 )x

Ve iki pozitif kesin matrisin toplamına erişmiş oluruz. Demek ki iki pozitif kesin
matrisin toplamı da pozitif kesindir.
Peki toplam şöyle olsaydı?

K1 + K2
|{z} |{z}
AT A BT B

A ve B’yi tek bir matris içine koyduğumuzu varsayalım, ki bu matrislere “blok


matrisleri” deniyor:

 
A
C=
B

Blok matrisinin devriği nedir?

CT =
 
AT BT

Blok matrisleri nasıl çarparım?

CT C = AT A + BT B

Bu K1 + K2 ’ya eşittir.
Ekler
Noktasal çarpım bakış açısı çarpım içeren açılımı göstermek için (Ax)T Ax iyi bir
örnek. Mesela bir problemde ||Ax||2 = Ax · Ax verilmiş ise eşitliğin sağ tarafını
(Ax)T Ax olarak görerek açılıma oradan devam edebiliriz [1],

Ax · Ax = (Ax)T Ax = xT AT (Ax) = xT (AT A)x

6
Dikkat, xT ile ifadenin geri kalanı arasında da bir noktasal çarpım var aslında, o
zaman

= x · (AT A)x

formülüne de erişilebilir.
Kaynaklar
[1] Math Stack Exchange, Transpose matrix and inner product, https://math.
stackexchange.com/questions/2823831/transpose-matrix-and-inner-
product

7
Ders 1-8
Yaylar ve Ağırlıklar (Springs and Masses)
Dersimizin uygulama kısmına geldik. Diyelim ki alttaki gibi bir yay sistemi
var, 4 tane yay 3 tane ağırlıktan oluşuyor, ve sonları duvar, tavan gibi bir yerde
sabitlenmiş.

Kütlelerin bir ağırlığı var tabii, ağırlıklar o yaylar aşağı doğru çekiyor, bu çekim
yayları açacak, gerecek, soru yayların ne kadar aşağı ineceği. Bir yer değişim (dis-
placement) sorusu bu yani. Unutmayalım yay açılıp kapanan bir mekanizmadır
ama açılırken de kapanırken de bir direnç gösterir. Yer değişim en üstte ve en
altta sıfır çünkü oralar sabitlenmiş.
Bir başlangıç hali düşünürsek, diyelim ki yerçekimi o anda etkisiz, ama sonra
yerçekimini bir düğmeye basıp açıyoruz, her yay başlangıç halinden aşağı doğru
bir yer değişimi yaşıyor,

bunlara u1 , u2 , u3 diyebiliriz.
Dikkat salınımı ölçmeye uğraşmıyoruz burada, o daha sonraki derslerde devreye
girecek, zaman faktörünü resme dahil edeceğiz; o sonra.. Şimdi sadece kalıcı
durumla ilgileniyorum, yerçekimi açılıyor, yaylar aşağı doğru uzuyor, ve her şey
yerli yerine oturduktan sonra gözlemlenecek yer değişimiyle ilgileniyorum.
Her yay parçasının ne kadar uzadığı / esnediği (elongation) ayrı bir ölçüt. Düşünürsek
ikinci kütledeki yer değişimi u2 içinde hem ikinci hem de birinci yayın esnemesi
rol oynar. O yüzden esneme için ayrı bir değişken kullanıyoruz, e1 , e2 , e3 . O za-
man ikinci yay ne kadar uzar? u2 − u1 kadar. Bir farktan bahsediyoruz burada.
Bazı yaylar sıkışma da yaşayabilir tabii, mesela tahmin ediyorum ki en alttaki
yayda sıkışma olacak.
Tüm bunlar işin geometrik kısmı bir anlamda, yer, uzama, kısalma.. Materyel
faktörleri de resme dahil etmek lazım, Hooke Kanunu bunu yapacak. İlk ağırlık
mesela aşağı inerken ilk yayı gerecek. Hooke Kanunu bu noktada der ki yay belli

1
bir kuvvetle ağırlığı geri çekecek, bu çekiş yayın gerilmesi / uzamasıyla orantılı
olacak. Her yaydaki kuvvete w1 , w2 , w3 , w4 diyelim. Esneme ile ona karşılık or-
taya çıkan kuvvet ilişkisi her materyel için farklı olur, yay çeşidine göre değisen
Hooke yay sabiti bu farklılığı denkleme dahil edebilir, bu sabitlere c1 , c2 , c3 , c4
diyelim.
Hooke Kanunu lineerdir, ki aşırı fazla olmayan esnemeler için lineerlik geçerli
olacaktır, muhakkak yayı aşırı gerseydik belli bir noktadan sonra lineer olmayan
etkiler görebilirdik, biz bu tür aşırı sonuçlara şu anda bakmıyoruz.
Devam edelim, Hooke Kanunu der ki her yaydaki kuvvet o yaydaki esnemeyle
orantılıdır,

wi = ci ei

Burada bir köşegen matris görüyorum ben, tüm yaylar, esnemeler, sabitler için

    
w1 c1 e1
 w2   c2   e2 
 w3  = 
    
c3   e3 
w4 c4 e4

Ve nihai matris formunda

w = Ce

ki w, C, e üstte görülen vektörler ve matris. Materyel kısmı bu şekilde dahil


etmiş olduk, ortadaki sabit matrisi üzerinden. Benzer kanunlar fiziğin diğer alan-
larında da görülebilir, mesela üstteki C matrisi iletkenliği de temsil ediyor ola-
bilirdi. Demek istediğim materyel özellikler denkleme oradan dahil oluyor. Bu
resmi nasıl tamamlarız? Yerçekim bir dış kuvvet, kütleler var, yer değişimlerine
sebep oluyor..
Resmi tamamlamak icin “kuvvet denge” denklemi ekleyecegim, her kütle icin bir
denge denklemi olacak.
Not ekleyelim, üstteki türden problem modellemesi pek çok diğer uygulamada
işe yarıyor. Bir geometri var, buradan bir A matrisi çıkartıyoruz, sonra bir fiziksel
adım var, oradan C matrisi geliyor, ve kuvvet dengesi ekleniyor, resim tamam-
lanıyor. Kuvvet denge denklemi diğer bir alanda, mesela elektrikte, Kırchoff
Akım Kanunu olabilirdi, ileride ağ yapılarına bakarken göreceğiz, giren akım
çıkan akıma eşit.. Buradaki denge bir yandaki kuvvetin diğer yandakine eşit
olması. Eğer sistemde bir dengeden (equilibrium) bahsedebiliyorsak bir denge
denklemi yazabiliriz demektir.
Şimdi esneme kısmını matris formuna çevirelim. Ne demiştik? Mesela ikinci yay
esnemesi eşittir ikinci yer değişimi eksi birinci yer değişimi. Matrissel formda

2
konuşmak için ei ve uj vektörleri lazım, ilişkileri bir matris çarpımı. Alttaki ma-
triste ikinci satıra ne yazarız?

   
e1  
 e2   ? ? ?  u 1
  u2 
 e3  = 
  

u3
e4

O satır sağdaki u vektörü ile çarpılacak ve sonuçlar toplanacak, o zaman u1 eksi


bir ile, u2 artı bir ile çarpılır, u3 ile ilgilenmiyoruz, orası sıfır, yani

   
e1  
 e2   −1 1 0  u 1
  u2 
 e3  = 
  

u3
e4

Üstte görülen satır bu tür matrislerde tipik bir satırdır. Peki birinci satır neye
benzer? Orada sadece u1 olur, tabii u1 − u0 farkı ama ilk yay en üstte sabitlendiği
için orada yer değişim olması mümkün değil u0 = 0, geriye sadece u1 kalıyor.
Üçüncü satır kolay. Dördüncü satırda u4 sabitlenmiş yani sıfır, tek kalan −u3 .
Hepsi bir arada,

   
e1 1 0 0  
u 1
 e2   −1 1 0 
 e3  =  0 −1
     u2  (1)
1 
u3
e4 0 0 −1

Matrise A ismi verirsek, üstteki denklem e = Au olarak belirtilebilir.


Bir adım daha var, kuvvet denge denklemi. Dışarıdan etki eden kuvvet yerçekimi,
m1 g, m2 g, m3 g. Denge için mesela ilk kütleye bakarım, ona hangi kuvvetler etki
eder diye sorarım kendime ve onları dengelemeye uğraşırım. Bu bana nasıl bir
denklem verir acaba?
İlk kütle için etki eden kuvvetlere bakarsak, yukarı, aşağı.. Yukarı çeken bir
kuvvet var, yay kuvveti w1 . Aşağı çeken w2 , değil mi? Alttaki yay her iki yöne
de bir kuvvet uygular. Ayrıca bir de yerçekimi var, m1 g. Hepsi bir arada

w1 = w2 + m1 g

Diğerleri benzer şekilde,

w2 = w3 + m2 g

3
w3 = w4 + m3 g

Üsttekini vektör, matris olarak yazmak istiyorum tabii ki, w’ların hepsini sol
tarafa geçirirsek işler daha kolaylaşabilir,

w1 − w2 = m1 g

w2 − w3 = m2 g

w3 − w4 = m3 g

Bunlar dış kuvvetler.. Yani (1)’deki iç kuvvetlerle üstteki dış kuvvetleri den-
geleyeceğiz, w’lar iç kuvvetler. Bir matris ortaya çıkacak şimdi. Önceki numarayı
tekrarlarsak,

 
 w1  
1 −1 0 0  f1
 0 w2  

1 −1 0 
 w3  = f2
 (2)
0 0 1 −1 f3
w4

ki fi = mi g.
Nasıl ufak adımlarla ilerledik görebiliyoruz herhalde.. Üç adım attık, birinci adım
bizi yer değişimlerinden yaylara götürdü, ikincisi yaylar arasındaki ilişkilere baktı,
üçüncü adım düğüm noktalara, kütlelere baktı.
Şimdi ana soru şu, üçüncü adımdaki matris nedir? Onun için yeni bir isme
ihtiyacımız var mı?
Aslında yok. Dikkat edersek (2)’deki matris (1)’dekinin devriği değil mi? Evet!
O zaman ona sadece AT diyeceğiz.
Üç adımdaki formülleri yanyana koyalım şimdi,

e = Au (3)

w = Ce (4)

f = AT w

Bu üç formülü birleştirip nasıl tek formül haline getiririm? Üçüncü formüldeki w
içine ikinci formüldeki w’yu sokabilirim, sonra elde edilenin içine birinci formüldeki
e’yi sokarım,

4
f = AT w = AT Ce = AT CAu

Nihai sonuç

f = AT CAu

Tüm yapıyı biraraya getiren formül bu işte, çözmemiz gereken nihai denklem.
Literatürde AT CA’ye direngenlik (stiffness) matrisi adı veriliyor, ben çoğunlukla
o matris için K sembolünü kullanırım, yani bu örnek için K = AT CA ve çözmemiz
gereken sistem Ku = f.
Bu arada w bilinmiyor, aslında burada iki bilinmeyen, bulmaya uğraştığımız iki
tane fiziksel değişken bloğu var, kuvvetler w ve yer değişimleri e; bir köprü,
başka bir tür yapı tasarlıyor olabilirdik, onun için yer değişimlerini ve içsel kuvvetler
w değerlerini arıyor olurduk. w ve u değişken öbekleri birbiriyle yakın ilintili
(dual), bazen biri, bazen öteki, ya da ikisiyle aynı anda iş yapıyor olabiliriz, bi-
raz ileri atlamak oluyor ama sonlu öğeler (finite element) metodu üstteki formül
altyapısını çözer (aslında direngenlik matrisi kavramı oradan çıkmıştır, şimdi pek
çok alanda görülebiliyor).
AT CA matrisine yakından bakmak bilgilendirici olur; mesela boyutları nedir? A
boyutu 4 x 3, C boyutu 4 x 4, AT tabii ki 3 x 4, çarpımın sonucu 3 x 3.
Çarpım büyük ihtimalle simetrik, öyle mi bakalım, simetrik demek devriğin ken-
disi ile aynı olması demektir,

(AT CA)T = AT CT (AT )T = AT CA

Başlangıca döndük demek ki simetri var.


Şimdi K = AT CA çarpımına gelelim, onun bulmamız gerekiyor, bu bize tüm
diğer çözümleri zincirleme verecek, Ku = f çözüyorsak, çözüm u = K−1 f. Eger
u’yu biliyorsam esnemeyi biliyorum demektir, (3) formülü e = Au idi, o zaman
e = AK−1 f demektir. Onu alıp (4) içine sokarım, w = Ce formülüne, o sonuç
ta w = CAK−1 f. Listeden aşağı indim, hepsi teker teker çıktı, tabii anahtar ilk
çözüm u = K−1 f.
Ondan önce soralım K çarpımını yapmadan K−1 içeriğini açsak, K−1 = A−1 C−1 (AT )−1
olur ve sağ tarafta bazı hızlı hesaplar yapabilir miydim acaba? Ne yazık ki A ma-
trisi kare matris olmayabilir ve bu tür matrislerin tersini almak istemiyorum.
O zaman K için çarpım yapmamız lazım, yani

  
1 0 0 c1  
1 −1 0 0
 −1 1 0  c2 
 0
K=
 0 −1
 1 −1 0  (5)
1   c3 
0 0 1 −1
0 0 −1 c4

5
Biz altta bu çarpımı hemen sympy ile yapalım

import sympy aş sp


c1,c2,c3,c4 = sp.symbols('c1 c2 c3 c4')
A = sp.Matrix([[1, 0, 0],
[-1, 1, 0],
[0, -1, 1],
[0, 0, -1]])

C = sp.Matrix([ [c1, 0, 0, 0],


[0, c2, 0, 0],
[0, 0, c3, 0],
[0, 0, 0, c4] ])

K = A.transpose() * C * A
K
Out[1]:
Matrix([
[c1 + c2, -c2, 0],
[ -c2, c2 + c3, -c3],
[ 0, -c3, c3 + c4]])

İşte problemimizi kontrol eden K matrisi bu. Matris kare, simetrik.


Bu tür matrisi daha önce görmüştük değil mi? Üstteki ci değerlerinin 1 olduğunu
farz edin, o zaman C matrisi birim matris olurdu, bu durumda geriye sadece AT A
kalırdı.

 
2 −1 0
 −1 2 −1 
0 −1 2

Bu matris daha önceki derste gördüğümüz özel K matrisi.


İki üstteki matris, tekrar yazalım,

 
c1 + c2 −c2 0
K= −c2 c2 + c3 −c3  (6)
0 −c3 c3 + c4

Tüm yay sabitleri bu matris içinde. Üstteki matris hakkında önemli bilgileri iki
üstteki matristen anlayabiliriz.
K hakkındaki önemli ipuçları nedir? Kare, simetrik dedik, ayrıca pozitif kesin
bir matris. Ve pozitif kesinlik bizi diğer bir özelliğe götürür, bu matrisin tersi
alınabilir.
Peki K matrisi niye pozitif kesin? Hatırlarsak pozitif kesinliğin ana kavramı
pozitif enerji idi. Şu ifade uT AT CAu pozitif olmalı, parantezleri (uT AT )C(Au)
şeklinde koyunca belli oluyor, ya da (uA)T C(Au). Ayrıca Au için bir eşitliğimiz
var, Au = e o zaman eT Ce. Eğer e, C, eT açık yazarsam,

6
 
c1

e1

e1 e2

e3  ..  e2 

.
cn e3

Bu bana c1 e21 + c2 e22 + c3 e23 + c4 e24 verir. Hooke Kanuna dönerse bir esnetilmiş
yaydaki enerji bu karesel formülle hesaplanır. Formülün esası her şeyi 1/2 ile
böler aslında, neyse, ana mesajımız şu, hesaplanan tek sayı pozitif.
Şimdi Profesör Bathe’nin ADINA adlı o ünlü sonlu öğeler çözen yazılım paketini
düşünürsek, ya da herhangi bir diğer paketi, Ansys, Abaqus gibi, bu paketlerin
odaklandığı büyük resim nedir? Bu paketleri geliştirmek için yıllar geçmiştir, on-
lara bir sürü kod eklenmiştir, fakat hepsinin arkasındaki temel fikir sudur, mod-
eli seç, materyel özellikler (bizim C matrisi) ekle, K matrisini bir araya getir, nihai
adımda sonlu öğeler tekniğiyle sistemi çöz. Her şey K matrisi etrafında dönüyor.
Son bir konuya daha değinmek isterim; matris çarpımına değişik bir bakış açısından
bahsetmek faydalı olur. Bu önemli çünkü ADANI gibi sonlu öğeler paketleri
çarpımı böyle yapıyorlar.
Klasik çarpım yöntemi nedir? Satır çarpı kolon yöntemidir. Mesela (5)’teki çarpım
için soldaki matrisin ilk satırını alıp sağdakinin ilk sol kolonu ile çarparım, bu
bana bir tek sayı verir, onu sonuç matrisin (1,1) kordinatındaki hücreye yazarım,
böyle devam ederim.
Fakat sonlu öğeler paketlerinin kullandığı, hatta çoğunlukla doğru bakış açısı
denebilecek olan yöntem bunun tam tersidir. Bu yöntem soldaki matrisin kolonu
ile sağdaki matrisin satırını çarpar. Boyutsal olarak düşünürsek mesela 3 x 1 kolon
ile 1 x 3 satır çarpılınca ne çıkar? 3 x 3 boyutunda bir matris değil mi? Ve bunu
tüm mümkün kolonlar ve satırlar için yapınca aynı boyutta daha fazla matris elde
ederiz ve nihai çarpım sonucu tüm bu matrislerin toplamı olacaktır.
Mesela (5) için ilk kolon çarpı ilk satır (aradaki C matris değerlerini de dahil ed-
erek tabii),

 
c1 0 0
 0 0 0 
0 0 0

Şimdi bu matrisin problemimiz bağlamında bir anlamı da var (bakış açısının bir
faydası da bu), üstteki matris bir öğe matrisi (sonlu öğeler bağlamında bir öğe).
Üstteki hesap içinde c1 içeren parça. Belki soldan ikinci kolon c2 ve sağdan ikinci
satırı da hesaplayınca daha iyi anlaşılacak,

   
c1 0 0 c2 −c2 0
 0 0 0  +  −c2 c2 0  + ...
0 0 0 0 0 0

7
İkinci matris bana ikinci yay hakkında bilgi veriyor. İlk matris birinci yayın sis-
teme, K’ye katkısını tarif ediyordu. Bu şekilde tüm yayların matrislerini topla-
yarak nihai sistemi elde edebiliyoruz. Klasik yaklaşımla çarpıma bu şekilde bak-
mazsınız, fakat mesela ADINA sistemi çarpımı aynen tarif ettiğim şekilde bi-
raraya getiriyor. ADINA türü sistemler klasik çarpımı yapmazlar, tarif ettiğimiz
kolon çarpı satır metotunu uygularlar.
Problem
Farz edelim ki üstteki kütle-yay sisteminde ci = c ve mj = m, yani tüm yaylar
aynı materyel ve tüm kütleler aynı ağırlıkta. Yer değişimi u ve kuvvet w’leri
hesapla [1, sf. 103].
Çözüm
Önce K matrisinin tersini bulmak istiyoruz. Eğer ci = c ise (6)’daki K matrisi şu
hale gelir,

 
2c −c 0
K =  −c 2c −c 
0 −c 2c

c’yi dışarı çıkartalım,

 
2 −1 0
K = c  −1 2 −1 
0 −1 2

Temel lineer cebirden biliyoruz ki (cA)−1 = c−1 A−1 , tabii skalar tek sayı c için
c−1 = 1/c demektir. O zaman üstteki matrisin tersini alalım sadece ve 1/c ile
çarpalım,

import numpy.linalg as lin


K = np.array([[2,-1,0],[-1,2,-1],[0,-1,2]])
print (lin.inv(K))
[[0.75 0.5 0.25]
[0.5 1. 0.5 ]
[0.25 0.5 0.75]]

 
0.75 0.5 0.25
K−1 = 1/c  0.5 1 0.5 
0.25 0.5 0.75

[1, sf. 103]’ta görülen sonuçla aynı olması için matrisi 4 ile çarpıp dışarı 1/4
çıkartalım,

import numpy.linalg as lin


print (4*lin.inv(K))

8
[[3. 2. 1.]
[2. 4. 2.]
[1. 2. 3.]]

Aynı sonuca eriştik,

 
3 2 1
1 
K−1 = 2 4 2 
4c
1 2 3

Yer değişimleri o zaman

   
3 2 1 mg 1.5
1  mg 
u = K−1 f = 2 4 2   mg  = 2.0 
4c c
1 2 3 mg 1.5

Ortadaki kütle yer değişimi u2 ’nin diğer u1 , u3 ’ten daha fazla olduğunu görüyoruz.
Birimleri hemen kontrol ediyoruz, kuvvet mg bölü birim uzunluktaki kuvvet c
bize uzunluk u’yi verir.
Esnemeler e = Au ile hesaplanır, biraz önce bulduğumuz u ile bu hesabı yapa-
biliriz,

   
1 0 0   1.5
 −1 1 0  mg 1.5 mg  0.5 
e = Au =    2.0  =  
 0 −1 1  c c  −0.5 
1.5
0 0 −1 −1.5

Sonuca göre ilk iki yay esnemiş, alt iki yay sıkıştırılmış.
Ornek
Her iki ucu serbest olan yayları düşünelim [1, sf. 106], bu yaylarda destek yoktur;
Bu durum A ve K’de problem çıkartır (dördüncü ve birinci yay gitti), A matrisi 2
x 3 boyutuna indi, boyu kısaldı eni uzadı. O zaman e = Au neye benzer?

 
      u1
e2 u2 − u1 −1 1 0  u2 
= =
e3 u3 − u2 0 −1 1
u3

Alt soldaki şekli düşünebiliriz. Hatta benzer bir örnek olarak sağdaki şekil de
olabilirdi.

9
Üstteki durumda artık Au = 0 denkleminin sıfır olmayan bir çözümü var, yani
sıfır uzayı boş değil. Au = e olduğuna göre e esnemedir, yani esneme olmadan
yer değişimi olması mümkün. Bu şekilden rahatça görülebiliyor zaten, yay sis-
temı havada asılı, alıp olduğu gibi bir yere taşınması mümkün. Hiç esneme
olmadan. Mesela tüm yay u = (1, 1, 1) olarak taşınabilir, bu hala e = (0, 0)
verir. Bu ortaya çıkar çünkü A kolonları birbirine bağlı (dependent) ve bu se-
beple u = (1, 1, 1) vektörü sıfır uzayında.
Kaynaklar
[1] Strang, Computational Science and Engineering

10
Ders 1-15
Makaskirişler (Truss)
Bir makaşkiriş esneyebilen çubuklardan (bar) oluşur, bu çubuklar birbirine bağlantı
pimleri (pin joint) ile bağlıdır. Bağlantı pimi derken şunu kastediyorum, çubukları
esnetmek özellikle uzunluğu yönünde kuvvet gerektirir, ama pim etrafında çubukları
döndürmek efor gerektirmez.

Mesela resimdeki 3 no’lu çubuğu sağa ve sola esnetmek zor, ama o çubuğu 3
no’lu pim etrafında döndürmek kolay.
Bu derste iki boyutlu makaşkirişler incelenecek, daha önce iki boyutlu yay-kütle
sistemini incelediğimiz gibi; muhakkak üç boyutlu makaşkiriş sistemleri de var
ama iki boyut üzerinde ana başlıkları daha rahat olarak inceleyebiliriz.
Üstte görülen örnekte 5 tane çubuk 3 tane düğüm (nod, pim noktası) görüyorum.
Peki bilinmeyenler ne? Yani daha önceki yay-kütle problemindeki hesapladığımız
u nedir? Çünkü u’dan e’ye oradan w’ya oradan da f’ye gitmek istiyorum. İlk
geçişi matris A yapar, ikinciyi C, üçüncüyü AT .. Bildiğimiz şeyler bunlar ama bu
yapıyı önümüzdeki probleme göre oluşturmak gerekiyor. Bahsettiğimiz matris-
lerin içini doldurmamız gerekiyor.
O zaman yapıyı tarif edelim. Mesela önce 1 no’lu düğüme bakalım, ona etki eden
kuvvetler nedir? İk boyuttayız demiştik, o zaman bir yatay bir de dikey kuvvet
olacak, en azından o düğüme etki eden tüm kuvvetler bu iki eksen bağlamında
incelenebilir. Bilinmeyen u’yu bu fırsatla tanıştırıyorum, alttaki resimde mesela
ikinci düğümdeki yer değişimini yatay ve dikey bileşenlerine ayırarak gösterebilirim,

Bileşenler yatay yönde uH V


2 , dikey yönde u2 . Bu yer değişimlerini, yatay, dikey
her pim için yaparız, böylece, bir anlamda elimizdeki biinmeyen değişken sayısı
ikiye katlanmış oldu. Artı, eksi olabilen tek bir u öğesi yerine artık her düğüm

1
için iki tane u öğesi takip etmemiz gerekiyor.
Şimdi alttaki yere bağlı destek noktalarına bakalım; orada ne oluyor? Bu nokta-
larda ne sağa, ne sola, ne yukarı aşağı hareket var, çünkü oraları sabitlendi. O
zaman uH V H V
4 = u4 = 0 = u5 = u5 = 0. Toplam kaç tane bilinmeyen var? Altı
tane. 1,2,3 düğümleri için ikişer tane, sabitlenmiş noktalarda yok, onlar biliniyor.
Demek ki A matrisim 5 x 6 boyutunda olacak. Bu yapı bize 6 tane u, 5 tane e, 5
tane çubuk kuvveti, ve 6 tane denge denklemi verecetir.
Fakat bu makaşkirişin üstünde durmak güvenli olmayabilir.. Bu püf noktası
makaşkirişlere özel olarak devreye giriyor, ve konuyu daha ilginç hale getiriyor.
Niye? Pür lineer cebirsel sebeplerle aslında, A matrisi 5 x 6 boyutlarında, yani
satırdan fazla kolon var, bu durumda Au = 0 denklemini çözen sıfır olmayan
bir u var, [1]’deki örnekte olduğu gibi. Bu arada A matrisleri gerçek dünya
örneklerinde rahatça satırdan fazla kolona sahip olabilir çünkü düğüm ekledikçe
o sayı çarpı iki kadar kolon eklemek lazım, A büyüyecek ve A bağımlı kolonlara
sahip olacak. Fiziksel dilde devam edersek sıfır olmayan yer değişimlerinin sıfır
esnemeyi ima ettiği durumlar ortaya çıkabilecek.
Makaskiriş üzerinde bu neye benzerdi? Yer değişimi var, ama esneme yok. Alt-
taki gibi olabilirdi mesela,

Bu harekete tekabül eden u’yu hayal etmeye uğraşıyorum şimdi, yine 1, 2, 3


düğümleri aynı yerde olsun, ve ufak bir hareketi bir birimlik değerle temsil eder-
sem (vektör içinde önce yatay sonra dikey değer gelecek şekilde),

 
1

 0 

 1 
u= 

 0 

 1 
0

Yani sadece yatay yer değişimi oldu, dikey hiç olmadı. Fakat bazılarımız şimdi
diyebilir ki “ama az da olsa dikey bir yer değişimi gözüküyor”. Bu doğru, ama
unutmayalım her şeye lineer bakıyorum, yaklaşıklama “birinci derece terimle”
yapılıyor, o zaman mesela

2
gibi bir durumda, θ kadar bir kayma var, çubuğun uzunluğu 1 diyelim, gelinen
nokta neresidir? Yatay olarak bu yer değişim sin θ kadar, dikey olarak 1 − cos θ.
Şimdi ufak θ sözkonusu ise sin θ ≈ θ. Peki 1 − cos θ yaklaşık olarak nedir? Her
iki terim için de açılım yapalım, ve yüksek dereceki terimleri yoksayalım,

θ3
sin θ = θ − ... ≈ θ
6

θ2 θ2
1 − cos θ = 1 − (1 − ...) = ... ≈ 0
2 2

Eğer θ2 ifadesinin probleme dahil olmasına izin verseydim o zaman gayrı lineer
bir problem elde ederdim. Bunu istemiyorum, yaklaşım lineer, o sebeple o ter-
imleri atınca geriye üstteki sonuçlar kalıyor. Zaten gayrı lineerlige çoğunlukla
ihtiyaç ta olmayabiliyor. Sonlu öğeler, yapılar, köprüler, alanım, araçlarım her ne
ise umudumuz ve beklentimiz hep ufak θ varlığı ve problemin lineer olması. Ve
lineer bir insan için θ2 sıfırdır. İşte bu sebeple üstteki u içindeki bazı öğeler sıfır.
Devam etmeden ekleyelim, bir probleme gayrı lineerlik bazı durumlarda dahil
olabilir; mesela geometrik gayrı lineerlik ile, üstteki problemde eğer θ’ların çok
büyük olmasına izin verseydim, o zaman θ2 ’i yok sayamazdım. Bu işleri zorlaştırırdı
tabii, mesela bazı sonlu öğeler yaklaşımları buna izin verir, Abaqus’ta mesela
bu tür hesap şekli desteklenir, o alanda ilk bakılan problemlerden biri Atlantik
altındaki kablolara ne olurdu mesela, müthiş ilgi çekici problemler, bir diğeri
araba kazası sırasında arabaların dış yapısına ne olur? O anda geometri değişiyor
muhakkak, büyük yer değişimleri oluyor.. Bunlar gayrı lineer yaklaşım gerek-
tiriyor.
Bizim problemde her şey lineer. Makaskirişin çok daha çetrefil olduğu prob-
lemler görürünüz belki ileride ama o durumda bile hala lineerlik varsayımı ile
hesaplar yapmak mümkündür.
Bir soru daha sorayım; üstteki problemdeki şekil bozulma durumunu, defor-
masyonu (literatur bu duruma Ingilizce biraz garip olan “mechanisms” yani “mekanizma”
ismini vermis) nasıl engellerim? Çünkü eğer azıcık sert bir rüzgar esse bu yapı
küt diye aşağı düşecek değil mi? O zaman yapıyı nasıl stabil hala getiririm?
Bu yapıyı tasarlıyor olsaydınız siz ne yapardınız? Bir tane daha çubuk ekleye-

3
bilirdim.

Sol alttan çapraz yukarı sağa doğru giden çubuğu yeni ekledim. Bu eklemeyi
yapınca altı tane çubuk elde ettim, ve altı tane yer değişimi var, bu demektir ki A
matrisi 6 x 6 boyutunda. Bu durumda umut edilebilir ki A matrisi artık eşsiz (sin-
gular) değildir, tersi alınabilir bir matristır, deformasyon olma durumu ortadan
kalkmıştır.. Daha matrisi yazmadım tabii ama bir mühendislik kabaca olayı tarta-
biliyorsak üstteki makaskirişin artık stabil olduğuna kanaat getirebilirdik. Yapıyı
daha da stabil yapabilirdim, mesela sağ alttan sol üst köşeye doğru yedinci bir
çubuk ekleyerek. Bu durumda 7 x 6 matris elde ederim, hala deformasyon ol-
maz.
Ama şunu da belirteyim, 6 x 6 ya da 7 x 6 matris olsa da, A matrisini yazmadan
hala eşsizlik var mı yok mu bunu önceden söylemek mümkün değil. Sistem
hala gayrı stabil olabilir (kıyasla 6 x 5 matris olsa mesela stabil olmama durumu
kesindir). Acaba bol çubuklu ama stabil olmayan bir makaskiriş bulabilir miyim?
Alttaki gibi bir yapı olabilir,

Üstteki örnek üzerinde egzersiz yapalım biraz (bu arada ders kitabında da [2] ek
egzersiz örnekleri var). Bu yapıdan nasıl bir matris elde ederim? Çubuk sayısı
nedir? Altı. Bilinmeyen sayısı? Sekiz. Çünkü hareket edebilen her pimde iki
bilinmeyen, dört pim var, 4 x 2 = 8. O zaman A matrisi 6 x 8 boyutunda.
Bu durumda kaç tene deformasyon olasılığı var? Büyük ihtimalle iki tane. Bir
tanesi alt iki pimin yana kayması üst taraf beraber gelecek şekilde, diğeri alt iki
pim yerinde durup üst iki pimin yana kayması. Bu iki seçeneğin bir kombinasy-
onu da ortaya çıkabilir muhakkak.

4
Bu örnek için de çubuk ekleyerek yapıyı stabil hale getirebilirim. En az iki tane
çubuk ekleyerek bunu yapabilirim. Ama çubuk sayısı stabiliteyi garanti etmez,
dikkat, çubukların nereye koyulduğuna dikkat etmek lazım, üst bölümde çapraz
iki tane çubuk eklesem bu stabiliteyi garanti etmez, alt kısım hala deforme olabilir
(hoca söylemedi ama çözüm herhalde bir çapraz çubuk alta, bir üste koymakla
oluyor).
Aynı örneği değiştirelim, yere olan alt iki desteği siliyorum, ve hem alta hem üste
iki tane çapraz çubuk ekliyorum.

Tekrar soralım, bu makaşkirişin esnemeden hareket etmesi mümkün müdür?


Au = 0’in çözümü var mıdır sorusunu sorduk yine. Yapı artık havada uçuyor,
normal olarak bu mümkün.. Üç şekilde bu hareket mümkün. Her şey toptan
yatay sağa, ya da herşey dikey yukarı/aşağı gidebilir (translation). Üçüncü katı
hareket şekli dönmedir (rotation), mesela sol alt pimi etrafında dönüş olabilir
(diğer pimler etrafındaki dönüş bu pime etrafındaki bir dönüş artı yer değişimleri
olarak indirgenebilir).
O zaman deformasyonlar ile katı gövde hareketlerini birbirinden ayırmak gerekiyor.
Katı gövde durumunda deformasyon yok, her şey hareket ediyor. Katı gövde
hareketi yeteri kadar destek olmadığı zaman, deformasyon ise yeteri kadar çubuk
olmadığı zaman ortaya çıkar.
Dersi bitirmeden önce son bir soru sorayım? İlk baktığımız örnek için C matrisi
nedir? Hangi boyutdadır? 5 x 5 değil mi? Çünkü beş tane çubuk var, her biri
için C köşegen matrisi içinde bir öğe olacaktır. Bu öğeler üzerinden w = Ce
formülü devreye sokulur, bu denklem her çubuk için geçerli olan Hooke Ka-
nunudur. Gayet basit, İki A ortasında bu C var, ve Hooke Kanununu sisteme
dahil ediyor.
Kaynaklar
[1] Bayramlı, Hesapsal Bilim, Ders 1-8
[2] Strang, Computational Science and Engineering

5
Ders 1-16
Bugünün en önemli iki işi var, biri A matrisini ortaya çıkartmak, zorlanma (strain),
ya da esneme (stretching) matrisi yani.. Çubuklar ne kadar esner? A’da her
çubuk için bir satır olacak. A biraz çetrefil hale halde, yaylar yerine çubuklar var,
bu daha fazla kolon demek çünkü iki boyutta her düğüm için iki bilinmeyen ek-
leniyor. Bu ortamda AT CA’ye en iyi bakış açısı çubuk bazında. İkincisi eğlenceli
kısım, bazı makaşkırış örnekleri göstereceğim, bunlardan bazıları deforme ola-
bilen, stabil olmayan türden olabilecek. Bu sistemleri analiz ederken muhakkak
Au = 0 sistemini hesaplatabiliriz, fakat biz aynı anda mühendislik bakış açısını
da geliştirmek istiyoruz.
AT CA çarpımının çubuk bazlı olmasına döneyim, bu çarpımı satır çarpı C öğesi
çarpı kolon olarak görmenin faydalarından bahsetmiştik. Her satır çarpı kolon
bana bir matris verecek ve bu matris tek bir çubuğa tekabül eden sonuç olacak.
Tüm bu tür çarpımlar toplanınca AT CA elde edilmiş oluyor.

1
Ders 1.17
[Giriş Konuları Atlandı]
Sonlu Öğeler Metodu (Finite Elements Method)
FEM yöntemiyle diferansiyel denklem çözerken önce denklemin zayıf formu elde
edilir. Dikkat, bu formu daha sonlu öğeleri ortaya atmadan, matrislerden vs bah-
setmeden yazmak gerekir. Başlangıç diferansiyel denklem ve onun belli şartlarda
eşit olduğu (ama çözüm için faydalı olabilecek) başka bir formu ortaya çıkartmaktan
bahsediyorum.
Zayıf formu “kuvvetli formdan” çıkartıyoruz, kuvvetli form diferansiyel den-
kleminin ilk hali,
 
d du
− c(x) = f(x)
dx dx

Zayıf forma geçmek için eşitliğin iki tarafını ona v sembolü vereceğim bir “test
fonksiyonu” ile çarpıyorum. Dikkat, u çözüm, v üstteki formülü “test” etmek
için kullandığım herhangi bir fonksiyon.
 
d du
− c(x) v(x) = f(x)v(x)
dx dx

Sonra üsttekini entegre ediyorum,

Z1   Z1
d du
− c(x) v(x) dx = f(x)v(x) dx
0 dx dx 0

Böylece zayıf forma neredeyse erişmiş olduk. Not: herhangi bir v(x) dedik ama
orada bazı şartlar olabilir, ileride göreceğiz. Üstteki formül her v(x) için doğru ol-
malıysa belki v(x)’in bir alanda konsantre olmasını zorlayabilirdim, sonra başka
bir v(x) denerdim belki onun başka noktalara konsante olmasını sağlayabilirdim...
Üsttekinden neler çıkartabilirim buradan diye düşünüyorum şu anda.. Fakat
sundan eminim ki sol taraf sağ tarafa eşit olmalı. Bunu kullanarak bir sürü takla
attıktan sonra bile güçlü forma dönebileceğimi biliyorum.
Ama biz şu anda zayıf formu seviyoruz.. onu sevmeyi öğrenmemiz lazım, bize
pek çok bazı ek yetenekler sağlayacak çünkü. Eşitliğin sol tarafında ek neler ya-
pabilirim mesela? Sağ taraf tamam, orası kafama uygun.
Sol tarafı daha iyi hale getirebilirim, parçalı entegral (integrate by parts) alarak..
Formülün sol tarafına sevmediğim bazı şeyler var, mesela u üzerinde iki tane
türev var, ama v üzerinde hiç türev yok, tek başına orada duruyor. Ben simetri
görmek istiyorum. Parçalı entegral nasıl yapılıyordu,

1
Z Z
y dz = yz − z dy

değil mi? Bir şeyin türevi çarpı v var, türevi v’ye geçiriyoruz, eşitliğin sağ tarafı
hala aynı,

Z1 Z1
du dv
c(x) dx = f(x)v(x) dx
0 dx dx 0

Nihai zayıf form bu. Parçalı entegral açılırken

 1
du
− c(x)
dx 0

ortaya çıkıyor, bu sıfır olup yokoluyor, çünkü serbest uçta c(x) du


dx
sıfıra eşit. Sabit
uçta ise u sıfıra eşit, tabii o zaman v de orada sıfıra eşit olmalı işte “herhangi bir
v” ibaresine bir sınırlama burada geliyor, sabit uçta v = 0 olacak şekilde bir v
seçilmeli.
Bu arada v’yi u’dan ufak sapmalar olarak görmek te faydalı.. Bu durumda sabit
uçta sapma sıfır demiş oluyoruz.
Dersin sonunda zayıf form nasıl kullanılır onu görelim. Galerkin’in fikri buydu,
Galerkin sürekli bir problemi ayrıksal bir probleme çevirmenin yolunu bulmuştu.
Bilinmeyen bir fonksiyon yerine bilinmeyen N tane yeni fonksiyon ortaya çıkart,
ki bu yeni fonksiyonlar KU = F içinde kullanılabilsin ve çözülebilsin. KU = F’e
FEM ile erişmeye uğraşıyorum dikkat, FD ile değil.
Galerkin dedi ki N tane deneme fonksiyonları φ1 , ..., φN olsun. Bu fonksiyonların
ne olduğunu biz seçeceğiz, uygulamalı matematikte bu çok olur, bir fonksiyon
seçersiniz, iyi seçerseniz her şey iyi işler, kötüyse işlemez. Neyse iyi, temel olan-
lardan seçtik diyelim, onların bir kombinasyonu üzerinden u’yu yaklaşık şekilde
temsil edebiliyoruz,

U ≈ U1 φ1 (x) + ... + UN φN (x)

φ1 , ..., φN fonksiyon, U1 , .., UN tek sayı, onları ağırlık değerleri. Şu anda bilin-
meyen Ui katsayıları üzerinden optimal bir φi kombinasyonu bulacağım ki bu
olabileceği kadar u’ya yakın olacak. Fakat N tane bilinmeyen katsayı var bu-
rada, o zaman bana N tane denklem lazım. İşte N tane test fonksiyonu V1 , ..., VN
üzerinden zayıf formu N kere kullanarak bu denklemleri üretebilirim. Her Vi
bana yeni bir denklem verir, N tane bilinmeyenim var, bu bana bir kare matris
verir, bir lineer sistem olur, KU = F’e böylece erişirim.
Fakat aslında bu fikir FEM’den 100 sene daha yaşlı. FEM’in katkısı deneme ve test
fonksiyonlarını belli bir şekilde seçmektir, kısaca basit polinom olarak. Aklımıza

2
gelebilir Galerkin niye bunu yapmadı? Belki yapmıştır, fakat bugünün bilgisayar
yazılımları bu yolun seçilmesini daha rahatlaştırdı muhakkak. Bugün biz FEM
çözerken üç, beş değil binlerce baz fonksiyon kullanabiliyoruz.

3
Ders 1-18
Sonlu Öğeler, 2. Bölüm
Üzerinden geçelim, sistem zayıf form ile ise başlar. Önceki dersin sonunda Galerkin
fikrini tanıştırdık, sürekli diferansiyel denklem yerine onu ayrıksal temsil etmeye
uğraştık. Galerkin bunun için bazı deneme fonsiyonları kullanır onlara φ1 , ..., φN
diyelim, ayrıca test fonksiyonları da vardır (fakat çoğunlukla test fonksiyonları ile
deneme, yani φ ve v fonksiyonları aynı seçilir). Bugün işleyeceğimiz bu fonksiy-
onların nasıl seçildiği ve hazırlık aşamasını gösterdikten sonra elde edilen KU = F
denkleminin nasıl çözüldüğü. K nereden geliyor, F nereden geliyor? F bir şekilde
alttaki ikinci denklemin (oktan sonra) sağ tarafından geliyor, K ise sol tarafından..
Detayları şimdi göreceğiz.
 
d du
− c(x) = f(x) →
dx dx
Z1 Z1
du dv
c dx = f(x)v(x) dx (1)
0 dx dx 0

ki eğer u(1) = 0 ise v(1) = 0 (sınır şartı).


Sonlu öğeler metotunun (FEM) temeli KU = F. Üstteki denklemde okun sol tarafı
diferansiyel denklemimiz, sınır şartları vs ile “güçlü formda”, oktan sonrası zayıf
form, ki onun da kendi sınır şartları var. Sabit değişkenler güçlü formdan zayıf
forma geçiyor, ama serbest değişkenler geçmiyor. v’yi u’dan olan ufak sapmalar
olarak gördüğüm için eğer u’yi sabitliyorsam v de sabitleniyor.
Tüm bunları gördük ama hala ayaklarımız yere basmadı; bir çok fikirden bah-
settik, ama şimdi daha gerçek dünyaya bağlanacağız. Gerçek dünya demek tabii
φ’lerle alakalı, hangi somut fonksiyonları φ olarak seçeceğiz?
Acaba örnek bir φ ne olabilir? Mesela x = 2 noktasında tepe yapan bir parçalı
lineer fonksiyon kullanabilirim,

Bu fonksiyona φ2 (x) diyelim, 1 ila 3 arasında 2 üzerinde tepe yapıyor diğer yer-
lerde ya lineer eğimi var, ya da değeri sıfır. Her φ maksimum tepe noktası
1 olarak seçilebilir. Onun sağındaki φ3 olabilir, benzer bir fonksiyon sadece 3
değeri bazlı tanımlı. Buradaki ana amaç sistemı basit ögeler üzerinde inşa etmek.
FEM’in ana fikri budur; φ için basit fonksiyonlar kullan. Bu basitliğin devamı
olarak φ ve v fonksiyonlarını aynı seç.
Peki sınır noktalarında ne olacak? Üstte serbest-sabit problemi çözeceğim, sol üç
nokta serbest, sağ üç nokta sabit (sınır tanımlanmış).

1
Üstteki resme bakarsak, x = 0 için bir “yarım şapka” fonksiyonu tanımladım,
φ0 diyelim, ve eğer diğer üçgen fonksiyonlara tam şapka dersek bu da yarım
şapka. O noktada φ ve v’lerim kısıtlı değiller. Böylece elimde beş tane deneme
fonksiyonu oluyor, φ0 , φ1 , φ2 , φ3 , φ4 .
Amaç nedir? Yaklaşık FEM çözümüm U(x)’in üstteki basit şapka fonksiyon-
larının bir kombinasyonu olmasını istiyorum.

U(x) = U0 φ0 (x) + ... + U4 φ4 (x) (2)

U0 , .., U4 değerleri skalar, tek sayı.. onlar ilk başta bilinmeyen “ağırlık” değerleri,
φ’leri belli şekilde çarpacaklar ve bu çarpımların toplamı yaklaşık bir u olacak.
Bu kombinasyonlar neye benzerdi acaba? Şöyle olabilirdi,

Başlangıçtaki değer niye u0 ? Çünkü orada tüm diğer φ fonksiyonları sıfır se-
viyesinde, hemen yandaki φ1 bile orada sıfır ve maksimum φ değer 1 olduğu
için başlangıç değeri u0 .
Bu arada Galerkin, ismini taşıyan yöntemi bulurken, aklında erişmeye uğraştığı
belli bir çözüm fonksiyonu vardı, ve şapka fonksiyonlarını oraya varmak için
seçmişti fakat modern FEM yaklaşımlarında, yazılımlarında bir temel fonksiyonu
ilk baştan seçeriz, problem hakkında bir şey bilmesek bile. Şapka fonksiyonları
bu fonksiyonlardan biridir.
Sonlu öğeler temel fonksiyonları düğüm noktalarıyla bağlantılıdır, bu bağlamda
sonlu farklılıkler (finite differences) metotuna benzer, öğeler düğüm noktalarına
oturtuluyor. FEM ile şapka fonksiyonu özelinde her düğüm noktasındaki u değerinin
o noktadaki ağırlık değeri ile aynı olmasını zorlamış oluyoruz; mesela 1 düğümündeki
değer nedir? u1 ! Çünkü orada diğer tüm şapka fonksiyonları sıfırdır, sadece φ1
değeri 1, toplanan tüm terimler yokoluyor geriye sadece u1 φ1 = u1 kalıyor.

2
FD benzerliği hakkında, KU = F’i oluşturduğumuzda onun bir FD denklemine
oldukca benzediğini göreceğiz, arada yapısal farklar var tabii, FD ile ayrıksal
denklemleri biz tanımlıyoruz, FEM ile sadece baz öğeleri seçiyoruz denklemin
ne olduğunu Galerkin yöntemi bize söylüyor.
Şimdi bize lazım olan üstteki resimdeki her nokta için ayrı bir denklem, yani
toplam 5 tane denklem. Bu denklemler nereden gelecek? Kritik bir soru.
Bu denklemler zayıf formdan gelecekler. Şunu yapıyorum, (1)’deki u yerine
(2)’deki U’yu sokuyorum. Ayrıca bir v lazım, daha önce v(1) = 0 şartı takip
edilmek suretiyle herhangi bir v olabilir demiştik, ama şimdi ayrıksal forma geçtik,
ben de φi fonksiyonlarını Vi fonksiyonlarım için kullanmaya karar veriyorum.
Böylece,

Z1 Z1
dU dVi
c(x) dx = f(x)Vi (x) dx (3)
0 dx dx 0

ki i = 0, 1, 2, 3, 4. Böylece 5 tane denklem elde ediyorum, 5 tane V ile ana formülü


“test ediyorum”. Yani üstteki denklemi 5 tane V için farklı şekillerle üretmiş oluy-
orum. İşte 5 x 5 sistemim bu. Neler yaptım şimdiye kadar? Baz fonksiyonlarını
seçtik, onları zayıf forma sokuyoruz. dU/ dx ağırlıklı toplamdan geliyor (dikkat
tüm V’leri kullanarak), sonra dVi / dx sokuyoruz, ve entegrali hesaplıyoruz. FD
durumunda bu hesap yoktu, entegral hesabı yani, FEM ile var, eşitliğin hem
sağında hem de solunda. Eşitliğin sağındaki entegral her Vi için bize bir Fi vere-
cek, yani F vektörünün bir satırını. Tabii K matrisi eşitliğin solundan bir şekilde
çıkacak, nasıl birazdan göreceğiz.
Örnek
Sağ tarafa bakalım önce, mesela i = 0 için, f(x) = 1 olsun (örneğe göre böyle) bu
R1
durumda 0 1 · V0 (x) dx entegrali ne olur? Entegral bir alan hesabıdır hatırlarsak,
o zaman

V0 üstteki ilk yarım şapka, o üçgenin alanı, eğer x ekseni eşit aralıklarla bölmüşsek
ve her aralık ∆x ise, (∆x · 1)/2 = ∆x 2
.
Dikkat 0 ila 1 arası entegral üstteki resimdeki tüm yatay ekseni kapsar, 0,1,2,..
indisleri kafa karıştırmasın. O indisler x = 0 ile x = 1 arasını indisliyor. O
zaman 0 ile 1 arası entegral tüm V’lerin olduğu alan üzerinden alınır, fakat biz her
seferinde birini seçtiğimiz için onun alanını hesaplamış oluyoruz çünkü mesela
V0 tanımlandığı yer sonrasında sıfır değerinde.
R1
i = 1 için ne olur? 0 1 · V1 (x) dx, üçgen tabanı 2∆x, çarpı 1, sonuç ∆x. diğer V

3
değerleri benzer şekilde, o zaman F vektör şu şekilde,

 
1/2

 1 

F=
 1 

 1 
1

K için hazır mıyız? Anahtar bölüm orası.


(3) formülünün tüm sol tarafı KU’yu vermeli.. Satır satır gidelim, mesela sıfırıncı
denklem hangisi? i = 0 olduğu zaman, yani V0 kullanılan, zayıf formu V0 ile test
ettiğimiz durumdur. Her şeyi açarak yazarsak,

Z1
dV0 1
c(x) (U0 φ00 + ... + U4 φ40 ) dx = F0 = ∆x ·
0 dx 2

Şu ana kadar eldekileri matris formunda yazarsak,

   
  U0 F0


 U1  
  F1 




 U2 =
  F2 

 U3   F3 
U4 F4

Boş matrisin ilk satırını V0 ’yi kullanarak yapacağım entegral hesabından elde
edeceğim. Daha kolay başlayalım, ilk satırın sol ilk hücresine ne gelir? K00 diye-
lim, oradaki değer U0 ’i çarpıyor değil mi ve bir şekilde entegralinin alınması
lazım.. Şöyle olabilir mi?

Z1
K00 = c(x)φ00 V00 dx
0

c(x) için şimdilik 1 kabul edelim. Fakat eğer 1 olmasaydı daha çetrefil bir fonksiyon
olsaydı? İçinde c(x) olan birçok entegrali üstteki gibi hesaplamak lazım, ve bu
hesapların kesin olması gerekmeyebilir, yani bu entegralleri yaklaşık olarak hesaplasak
ta yeterli olabilir. Sonuçta diğer her şeyi yaklaşık yapıyoruz değil mi? Belli nok-
talar üzerinden yaklaşık bir temsil yaratıyoruz vs.. Bu çerçevede eğer üstteki
türden entegralleri hesabın tümünü bozmayacak seviyeye yetecek kesinlik3te
hesaplayabilirsek, işimizi halletmiş oluruz. c(x) 1 olunca tabii ki kesin çözümü
bulacağız ama diğer tür durumlar için aklımızda olsun.
Hesabın kendisine gelelim. φ00 nedir? Bu arada φ’leri V ile aynı seçtiğimiz için
φ00 = V00 ve her iki türev üstteki resimdeki baştaki yarım üçgenin eğimi. Eğitim
dikey artış bolu yatay artış, yatay kısım ∆x, o zaman 1’inci dugume kadar −1/∆x,
sonrası sıfır.

4
Bu vurgulanması gereken bir noktaya götürüyor, fonksiyonlarımız yerel / lokal.
Bu ne demek? Eğer φ10 türevini V40 türeviyle entegre etseydim (K matrisinde
4’uncu satır ile 1’inci kolon değeri yani) ne olacaktı? Sıfır olacaktı. Niye? Çünkü
bu fonksiyonlar yerel, 0’inci ve 4’uncu düğümlerden uzakta değerleri sıfır, sıfır
olmadıkları yerler çakışmıyor. Şimdi bu dinamiği tüm matris için düşünürsek
ne kadar az çakışma yeri olduğunu görebiliriz. Herhangi bir φ mesela, tabii
ki kendisiyle çakışır ve yanindaki komşularla biraz çakışır. Ama daha ilerisiyle
örtüşmesi yoktur. Bu bize K için üçlü köşegen bir matris verecek, üç öğeli köşegen
bantında değerler olacak, geri kalan her yer sıfır.

K00 hesabına dönelim, c(x) = 1, φ00 = −1/∆x, V00 aynı değer, ve entegre ettiğimizi
unutmayalım, 0 ile 1 arası ama aslında 0 ile ∆x arası çünkü sadece oraya kadar
değerler var, o zaman K00 = 1/∆x oluyor.
Peki

Z1
K11 = c(x)φ10 V10 dx
0

φ1 eğimi nedir? Bu şapka fonksiyonu tam, ∆x’e kadar yukarı çıkıyor sonra aşağı
ınıyor, o zaman


1/∆x 0 < x 6 ∆x
φ10 = V10 =
−1/∆x ∆x < x 6 2∆x

φ10 ve V10 çarpımı her iki bölüm için 1/∆x2 verir. Peki K11 entegral sonucu ne o
zaman? 2∆x değil mi? Çünkü bu sefer entegral sınırlarına dikkkat, 0 ile 2∆x
arasında.

Z 2∆x
K11 = c(x)φ10 V10 dx = 2∆x
0

K22 , K33 , .. benzer şekilde olacak.


Peki K01 ne olur? Yani sıfırıncı satır ve 1’inci kolona bakıyorum. Her iki şapka
fonksiyonunu çizersek,

5
Görüldüğü gibi biri yarım, diğeri tam, ama çakıştıkları yer hocanın gri kalın
şeritle gösterdiği bölümden öncesi. Ondan sonrası φ0 sıfır değerinde orada ente-
gral almaya gerek yok.
Tabii entegre edilen eğimler, φ00 −1/∆x olacak, V10 ise pozitif değerli, 1/∆x. Çarpımları
−1/∆x2 entegre sınırı 0 ile ∆x arası, entegrasyon sonucu K01 = 1 − /∆x. n
Köşegen bir üstü ve bir altı aşağı çapraz inen tüm satırlar için aynı şey geçerli,
çünkü hepsi de yanyana olan φ ve V üzerinden entegral alıyor olacaklar

Tüm matrisi doldursak görürdük ki K matrisi simetrik, pozitif kesin olacak. Hatta
onun ötesinde biraz basitleştirme sonrası üstteki matris bize bu dersten daha da
tanıdık gelebilir. Eğer 1/∆x dışarı çekilirse bizim T matrisi ortaya çıkıyor,

 
1 −1
 −1 2 −1 
1  
K=  −1 2 −1 
∆x  
 −1 2 −1 
1 2

Hepsini bir araya koyarsak,

    
1 −1 U0 1/2
 −1 2 −1  U1   1 
1     
KU =  −1 2 −1  U2  = ∆x  1 =F
∆x     
 −1 2 −1  U3   1 
1 2 U4 1

Basit örneğimiz için FEM sistemi KU = F işte bu.


Gerçi üstteki denklem sonlu farklılıklara (FD) benzer bir sistem ortaya çıkarttı,
derse o sebeple ’bu iki yaklaşımın farkı nerede?’ sorusuyla başlamıştım. Fakat
dikkatli bakarsak bu çok basit problemde bile ufak bir fark var, üstteki vektörde
1/2 var mesela, FD sistemine bu yok. Ama tabii F 1 değilse ya da c 1 değilse daha
fazla farklar ortaya çıkacaktır, c 1 değilse bir sürü çetrefil entegral ortaya çıkar,

6
onları yaklaşık şekilde temsil etmeye uğraşırım muhakkak.
Ya F için pür 1 değil mesela nokta yük (point load) δ(x − 15 ) olsaydı elimizde?
Şimdi entegrallere geri dönmem gerekiyor değil mi? (3) denklemindeki eşitliğin
sağ tarafındaki entegralden bahsediyorum. Şimdi o entegralde 1 yerine noktasal
yük var

Z1
= δ(x − 1/5)Vi dx
0

diye gidiyor, yani δ(x − 1/5) fonksiyonunu her şapka fonksiyonuna karşı entegre
etmem gerekiyor. Ne elde ederim? Delta fonksiyonu 1/5 noktasındaki değeri
çekip çıkartır, çünkü o noktada zıplama yapıyor, orada entegrali, alanı 1, o za-
man 1/5 üzerindeki Vi değerini seçecektir. O da i = 1 olur, demek ki iki üstteki
eşitliğin sağ tarafı suna benzer,

 
0

 1 

= ∆x 
 0 =F

 0 
0

Gerçi bu da FD’nin üreteceği sonuca biraz benzer.


Ya nokta yükü düğüm üzerinde değil iki düğüm arasına gelecek şekilde seçseydim?
Mesela 3/10 noktasında? O zaman entegraller bana

 
0

 1/2 

= ∆x 
 1/2 =F

 0 
0

verirdi değil mi? Görüyoruz, FEM nasıl otomatik olarak akılcı olan şeyi yaptı..
Noktasal yükün etkisini iki vektör hücresine yaydı. Otomatik olarak c(x)’i, f(x)’i
esnek şekilde probleme dahil ediyor, serbest sınırı idare ediyor.. FD bunu yapa-
mazdı, çünkü FD katı olarak düğümler üzerinde tanımlıdır.

7
Alttaki Eski Bir Ders Video’sundan Alınmıştır
Sonlu Öğeler Metodu (Finite Elements Method)
Bu metot differansiyel, kısmi differansiyel denklemleri (partial differential equa-
tions) yaklaşıksal olarak modelleme ve çözmenin yöntemleridir.
Formül: Başlangıç denklemi
 
−d du
c(x) = f(x)
dx dx

İki tarafı da v(x) ile çarpıyoruz ve 0 to 1 sınırlarıyla entegralini alıyoruz.

Z1   Z1
−d du
c(x) v(x) dx = f(x)v(x) dx
0 dx dx 0

Parçalı entegral (integration by parts) formülü şöyledir:


Z Z
y dz = yz − z dy

Ana formülün bölümlerini, parçalı entegrale göre bölüştürürsek:


 
−d du
dz = c(x) dx
dx dx

du
z = −c(x)
dx

y = v(x)

dv
dy = dx
dx
1
Yukarıda dz içinde dx ve dx birbirini iptal eder. Parçalı entegral formülünün sağ
tarafına göre yerlerine koyarsak:

Z1    x=1 Z 1
−d du du du dv
v(x) dx c(x) = − v(x)c(x) c(x) dx
0 dx dx dx x=0 0 dx dx

Üstteki parçalı entegral açılımında sol taraf entegrale sınır değerleri aldığında,
sağ taraftaki yz sonucunun aynı sınır değerlerine tabi olduğuna dikkat edelim.

8
Differansiyel denklemde sınır koşulları x = 1 durumunda c(1)u 0 (1) = 0, ve x = 0
durumunda v(0) = 0 olarak biliniyor. O zaman üstteki denklemin sol tarafında
x = 0 ve x = 1 koşulları için tanımlı bölüm 0 − 0 = 0 olacaktır ve denklemden
atılabilir. Geriye kalanlar

Z1 Z1
du dv
c(x) dx = f(x)v(x) dx
0 dx dx 0

Bu fonksiyonu Galerkin adlı bir matematikçi bulmuş, ”zayıf form (weak form)”
olarak adlandırılıyor.
Şimdi diyelim ki n tane test fonksiyonu seçtik φ1 (x), .., φ(n) ve bu fonksiyonların
Uj sayıları ile çarpımının toplamını, yani bir tür kombinasyonunu u(x) yerine
kullanmaya karar verdik.

U(x) = U1 φ1 + ... + Un φn

O zaman

U 0 (x) = U1 φ10 + ... + Un φn0

X
n
dφj
= Uj
1
dx

Şimdi du/dx yerine U 0 (x) koyarsak

Z1 X
n  Z1
dφj dVi
c(x) Uj dx = f(x)Vi (x) dx
0 1
dx dx 0

Dikkat edelim, v(x) yerine Vi (x) kullandık. Üstteki formül her i için yeni bir
formül ”üretecek”. Niye Vi ? Zayıf formdaki v(x) formülünü de zaten biz uydurmuştuk,
yani v(x) biz ne istersek o olur. O zaman bu fonksiyonu n tane formül üretmek
için bir numara olarak kullanıyoruz, n tane formül olunca matrisin n x n ele-
manını doldurabileceğiz ve çözüme erişebileceğiz. Ek not, çoğunlukla Vi (x) için
φi sembolü kullanılıyor.
Ayrıca formüldeki Uj kısmını cekip çıkartırsak ve bir vektör içine koyarsak, geri
kalanlar bir Kij matrisi içinde tutulabilir.

Z1
dφj dVi
Kij = c(x) dx
0 dx dx

Sağ taraf aynı şekilde i tane formül üretir

9
Z1
Fi = f(x)Vi (x) dx
0

Final formül matrix formunda basit bir şekilde temsil edilebilecektir.

KU = F

Örnek
Örnek olarak −u 00 = 1 denklemini çözelim. Not: Differansiyel denklemlerde
sonuç bulmak demek bir ”fonksiyon” bulmak demektir. Normal cebirsel den-
klemlerde sonuç bulmak değişkenlerin ”sayısal” değerini bulmak demektir. Bi-
razdan bulacağımız sonuç u(x) ”fonksiyonu” olacak.
Eğer denklem −u 00 = 1 ise o zaman bu formülü ana forma uygun hale getirmek
için c(x) = 1 olarak almamız gerekir. −u 00 = 1 denkleminde eşitliğin sağ tarafı 1
olduğuna göre f(x) = 1 demektir.
Artık φ fonksiyonlarını seçme zamanı geldi. Bu fonksiyonların ”toplamı” hede-
flediğimiz fonksiyonu yaklaşıksal (approximate) olarak temsil edecek. Örnek
olarak seçebileceğimiz bir fonksiyon ”şapka fonksiyonu (hat function)” olarak
bilinen üçgen fonksiyonlar olabilir. Alttaki figürde bu fonksiyonları görüyoruz.

Bu figürde x ekseninin h büyüklüğündeki parçalara bölündüğünü görüyoruz.


Entegralleri hesaplayalım

Z1
F1 = V1 (x) dx
0

Daha önce V1 ve φ1 ’i aynı kabul ettiğimizi belirtmiştik.


Yukarıdaki entegralin aslında bir alan hesabı yaptığını görüyoruz. Sınırlar 0 ve
1 arasında, ama 2h ötesinde zaten φ1 fonksiyonu yok. φ1 ’in alanı nedir? Alan
üçgenin alanı: Taban çarpı yükseklik bölü 2: 2h, yüksekliği 1, o zaman alan (2h ×
1)/2 = 1/3
Benzer mantıkla bakarsak, F2 ile F1 aynı, yani 1/3. F3 ise onların yarısı, yani 1/6.

10
Kij nasıl hesaplanacak? c(x) = 1 olduğu için formülden çıkarılabilir ve V1 ve
φ1 ’in aynı olduğuna söyledik:

Z1
dφj dVi
Kij = c(x) dx
0 dx dx

Z1  2
dV1
K11 = dx
0 dx

dV1 /dx nedir? Birinci şapka fonksiyonunun türevidir. Bu türeve bakarsak, 0 ve


h arasında artı eğim (slope) 1/h, h ve 2h arasında eksi eğim −1/h oluyor. Ama
kare aldığımız için sonuç aynı, 1/h2 . O zaman h = 1/3 olduğuna göre 1/(1/3)2 ,
yani dV1 /dx = 9.

Z 2/3 2/3

K11 = 9 dx = 9x = (9)(2/3) − 0 = 6
0 0

K22 şeklen aynı fonksiyon parçasını temel aldığı için aynı değere sahip: 6. K33
onların yarısı, eşittir 3.
K12 farklı eğimlerin çarpımı anlamına gelir, yani V10 ile V20 çarpımı olur. Bu iki
fonksiyona bakalım, 0 ile h arasında V2 yok, eğim 0. İkisinin de sıfır olmadığı,
çarpımda kullanılabilecek bir eğiminin olduğu tek aralık h ve 2h arası. Burada
V10 = −3, V2 = 3.

Z 2/3 2/3

K12 = (3)(−3) dx = −9x = −6 − (−3) = −3
1/3 1/3

Aynı şekilde K23 = −3. Ama K13 = 0 çünkü hiç çakışma yok.
Matrisi doldurursak,

KU = F

    
6 −3 0 U1 1/3
 −3 6 −3   U2  =  1/3 
0 −3 3 U3 1/6

Python kodu

K = [[6., -3., 0],


[-3., 6., -3.],
[0., -3., 3.]]

11
f = [1./3., 1./3., 1./6.]

print np.linalg.solve(K,f)

[ 0.27777778 0.44444444 0.5 ]

print 5./18., 4./9., 1./2.

0.277777777778 0.444444444444 0.5

Rapor edilen değerler bu denklemin bilinen çözümü u(x) = x − 21 x2 ile 0, h, 2h


noktalarında (mesh points) birebir uyum gösterdiğini görüyoruz. Yani yaklaşıksal
olarak differansiyel denklemi çözmeyi başardık.
Kaynaklar
[1] Strang, G., Computational Science and Engineering

12
Ders 1-20
Sona yaklaşırken 4’uncu seviye bükülme denklemleri (4th order bending equa-
tions) ve öğe matrisleri konusunu biraz daha genişletmek istiyorum, hala sonlu
öğeler (FEM) dünyasındayız, öğe matrisleri FEM yaklaşımının öğeleri ve tam ma-
trisler.. Hatırlarsak makaşkirişin her çubuğu AT A’nin bir parçasını veriyordu, ve
bu parçalar birleştirilerek K oluşturuluyordu. Bir çizitte her kenar bir satıra 1, -1
diye tekabül edecek şekilde bir matris ortaya çıkartabiliyordu.. Şimdi öğe ma-
trislerinin FEM ile ilişkisini yakından görmek istiyoruz. Bugünkü dersin yarısı
bu.

Dersin diğer yarısı 4’uncu derece diferansiyel denklemler. Şimdiye kadar gördüğümüz
tüm diferansiyel denklemler ikinci derece idi, 4’uncu derece önemli denklemler
var mı diye merak edenler olabilir, evet var. Kiriş bükülmesi problemi bunlardan
biri mesela, üstte inşaatlarda kullanılan türden bir kiriş görüyoruz, resim bir stres
analizi programından alınmış, mavi, yeşil, kırmızı renkler kiriş uygulanan yükün
etkilerini gösteriyor, kırmızı en fazla stres olan yerler mesela, işte üstteki türden
çıktılar 4’uncu derece bükülme denklemini gerektiriyor.
Bu tür denklemler bizim AT CA altyapımıza uyuyor mu? Muhakkak öyle, biraz-
dan göreceğiz.
Tek boyuta dönüş yapalım, analiz edilen cismi parçalara böleceğiz, ve her parça
bir öğeye tekabül ediyor olacak. Cisim bir büyük çubuk, kiriş olabilir.. Sonlu
farklılıklar (finite differences) ile size araları eşit olmayan izgara noktaları versem
ki alttaki resimde mesela h ile H birbirinden farklı olsa, bu FD ile bizi bayağı
uğraştırırdı, ikinci farklılıktaki -1, 2, -1 satırı yerine biraz daha dengesiz değerler
elde ederdik, bu izgaranın dengesizliği sebebiyle olurdu. FD ile bu durumu ciddi
tartmak gerekirdi, FEM ile sistem o düşünme işini bizim için hallediyor, dengesi-
zlikler, olduğu yerlere sistemin yapısı sayesinde doğal olarak çözülüyor.
Basit tek aralığa odaklanalım şimdi, iki tane şapka fonksiyonumuz olsun, her
ikisinin de maksimum seviyesi 1,

Fonksiyonumuz iki seçilmiş noktada u0 ve u1 değerlerinde, bu değerlerden ilki


u0 çarpı birinci şapkadan geliyor, aynı şekilde ikincisi u2 çarpı ikinci şapkadan..
u0 ve u1 arasında ne olur? Fonksiyon

1
U(x) = u0 φ0 + u1 φ1

Bu bir lineer fonksiyon, alttaki gibi bir çizgi ile gösterilebilir,

[devam edecek]

2
Ders 1.22
Basit bir u ile başlayalım, u = x2 + y2 = c. Bu bize iki boyutta bir çember veriyor.
Bu formülün gradyanını alarak ne öğreniyorum? Bu çembere her noktadan dışarı
dik giden vektörü. v = [2x, 2y].
[atlandı]
Bize iki v1 ve v2 fonksiyonları verilmiş, öyle ki

∂u
v1 =
∂x

∂u
v2 =
∂y

Buradan türevin tersine giderek bir u nasıl elde ederim? Yani x türevi v1 olarak
verilmiş, y türevi v2 olarak verilmiş bir u’yu bulabilir miyim? Şansımız pek fazla
değil, çünkü iki tane bilinen denklemim, ama bir tane bilinmeyen değişkenim var.
Çoğunlukla bu tür sistemlerde çözüm olmaz, ama bazen olur. O zaman sonucu
bulduğumuza dair tutarlılık testimiz ne olabilir? Bu bizi kısmı türev bazlı bir
eşitliğe götürüyor.
Düşünelim. Üstteki iki denklemi birbiriyle nasıl ilintilendirebilirim? Ki, ma-
tris dilini kullanırsak, “v1 , v2 ’nin gradyanin kolon uzayında olduğunu anlayabi-
leyim”.
Ana fikir şu, v1 ’in y bazlı v2 ’nin x bazlı türevini al.

∂v1 ∂2 u
=
∂y ∂y∂x

∂v2 ∂2 u
=
∂x ∂x∂y

Fakat türevlerde sırabağımsızlık sebebiyle üstteki iki denklemin sağ tarafları aynı
şeyi söylemiyor mu? Evet. O zaman formüllerin sol tarafları da birbirine eşit
demektir,

∂v1 ∂v2
=
∂y ∂x

Ya da

∂v1 ∂v2
− =0 (1)
∂y ∂x

1
Bu formül önemli çünkü Vektör Calculus’un temel eşitliği.
[atlandı]
Testi bulduk. Şimdi “dolam (curl)” kelimesini kullanmak istiyorum, üsttekine,
curl v = 0 şartı diyebilirim. İtiraz edenleriniz olabilir, “ama dolam üç boyut-
tadır” vs. Daha önce hakikaten üç boyutta gördük bu kavramı, ve sonucun da üç
bileşeni oluyordu. Fakat üsttekine “düzlemde dolam” diyebiliriz. Ya da sanki üç
boyuttayız ama v = [v1 (x, y), v2 (x, y), 0] durumu var, z hep sıfır, ve dolam hesabı
bu şartta yapılınca dolamın tüm bileşenlerinden geri kalan sadece üstte görülen
formül olacaktır. Mesela v3 ’un türevini kullanan kısım yokolur, çünkü v3 yok.
[atlandı]
(1) formülü bir nokta için geçerli. Bu formülü bir çember, döngü etrafında nasıl
uygularım? Kapalı bir devre etrafında uygulamak istiyorum,
I
v1 dx + v2 dy = 0 (2)

Mesela bir hız alanında bir kapalı devre içinde gidiyorum, böyle bir alanda tüm,
toplam sirkülasyon, dönüş sıfır olmalı. (2) de aslında Vektör Calculus’ta bir eşitlik,
(1) ile (2) bağlantılı aslında, biri diğeri sıfır olunca sıfır oluyor.. Stokes Teorisi
mesela (2) entegraline (1)’in çift entegral alınmış hali der, vs.
Şimdi uzaklaşım (divergence) konusuna gelelim. Eğer ∇ · w = 0 görürsem bu ne
demektir? Bir sıvı akışını düşünürsem, bu ifade kaynak yok demektir. İçeriye ne
giriyorsa o dışarı çıkıyor [bir şey eklenmiyor yani, kaynak yok]. Bu ne kanunu?
Bu da bir Kirchoff kanunu aslında, Akım Kanunu [tabii fizikte pek çok diğer
alanda benzer kanunlar var]. “Girenler eşittir çıkanlar” matematiksel olarak nasıl
derim? İşte Uzaklaşım Teorisi’ne şimdi ihtiyacım var.
Her nokta için giren eksi çıkanlar hesabını yapıp tüm bir bölge için topluyorum,
ve geriye kalan tek “çıkış”, o bölgenin sınırından dışarı çıkanlar olur tabii. Bu
doğal tabii, eğer bir net çıkış var ise, ya da giriş, o giriş ya da çıkış o bölgenin
sınırından
RR giriyor ya da çıkıyor olacaktır.
H O zaman bir bölge üzerinden entegral,
bölge , sınırdan olan akış entegrali hesabına eşit olmalı. Eğer w akışı gösteren
vektör alanı ise, s sınırından akana, daha doğrusu akışın sınıra dik olan bileşenini
sınır üzerinden toplarım,

ZZ   I
∂w1 ∂w1
+ dx dy = w · n ds
bölge ∂x ∂y

İşte iki boyutta Vektör Calculus’un önemli bir eşitliği bu. Bir anlamda Calcu-
lus’un Temel Teorisi gibi bu ama şimdi iki boyuttayız.
Ekler
Uzaklaşım Teorisi tam formu

2
ZZ Z
(div w) dx dy = (w · n) ds
R B

Uzaklaşım Teorisi hakikaten Calculus’un Temel Teorisinin çok boyutlu karşılığı,


tek boyutta Uzaklaşım Teorisi aynen şöyle olurdu [1, sf. 262],

Zb
dw
dx = w(b) − w(a)
a dx

Tek boyutta normal vektörü görmüyoruz ama aslında orada. Bitiş noktası x =
b’de çıkış yönü n sağa doğru, değil mi? Bu bize +w(b) veriyor. Başlangıç noktası
x = a’da n sola doğru işaret ediyor, yani dışarı doğru, bu bize −w(a) veriyor.
İkisini toplayınca w(b) − w(a) elde ediyoruz.
Gauss-Green Eşitliği
Bu eşitlik iki boyutta şu şekilde gösterilebilir,
ZZ ZZ Z
(∇u) · w dx dy = u(− div w) dx dy + uw · n ds
R R C

Türetmek için başlangıç noktası uv üzerinde uzaklaşım almak. Aslında ileride


göreceğimiz gibi çok boyutta parçalı entegral tekniği Gauss-Green’in uzantısı bir
bakıma ve tek boyutta gördük ki [2] parçalı entegrale erişmek için de Calculus’un
çarpım kuralından başlanmıştı.

∂u ∂w1 ∂u ∂w2
div(uw) = div(uw1 + uw2 ) = w1 + u+ w2 + u
∂x ∂x ∂y ∂y

Gruplarsak,
   
∂u ∂u ∂w1 ∂w2
= w1 + w2 + u+ u
∂x ∂y ∂x ∂y

Daha kısa şekilde,

div(uw) = ∇u · w + u div(w)
RR
Üstteki ifade üzerinde Uzaklaşım Teorisi’ni uygulayalım. Önce R div(uw),
ZZ ZZ
div(uw) dx dy = ∇u · w + u div(w) dx dy
R R

ZZ ZZ
= ∇u · w dx dy + u div(w) dx dy
R R

3
R
Uzaklaşım Teorisi’ne göre sağ taraf C uw · n ds olmalı, yani
ZZ ZZ Z
∇u · w dx dy + u div(w) dx dy = uw · n ds
R R C

Eşitliğin sol tarafındaki ikinci terimi sağa geçirirsek,


ZZ ZZ Z
∇u · w dx dy = u(− div w) dx dy + uw · n ds
R R C

[1] notasyonu ile ∇ yerine grad,


ZZ ZZ Z
grad u · w dx dy = u(− div w) dx dy + uw · n ds (3)
R R C

Böylece Gauss-Green eşitliğine erişmiş olduk.


Green’in İlk Eşitliği
Eğer (3) içinde w için grad u sokarsak, bu bize Green’in İlk Eşitliği (Green’s First
İdentity) denen formülü veriyor [1, sf. 281],

ZZ ZZ Z
grad u · grad u dx dy = u(− div grad u) dx dy + u grad u · n ds
R R C

Gradyanın uzaklaşımı bazen ∆ notasyonu ile gösterilir, öyle yapalım,


ZZ ZZ Z
| grad u| dx dy = −
2
u(∆u) dx dy + u grad u · n ds
R R C

Eşitliğin sağından, solundan birkaç yer değişim sonrası,


ZZ ZZ Z
u(∆u) dx dy = − | grad u| dx dy +
2
u grad u · n ds
R R C

Böylece [1, sf. 281]’daki forma erişmiş olduk. Bu Green’in İlk Eşitliği.
Kaynaklar
[1] Strang, Computational Science and Engineering
[2] Bayramlı, Diferansiyel Denklemler, Ekler

4
Ders 24
[Ders notları atlandı]
FIR Filtreleri
Bir sinyalin içinden belli frekansları ayıklama işlemine filtreleme adı veriliyor;
çeşitleri alçak geçiren (low-pass), yüksek geçiren (high-pass), ve bant geçiren
(band-pass) filtreleri. Alçak geçiren filtrelerle mesela 2 kHz üstündeki tüm frekan-
ları sinyalden çıkartmak istiyorsak eşik değeri 2 kHz’lük olan bir filtre kullan-
abiliriz, yüksek geçiren bunun tersini yapabilir. Bant geçiren ise sadece belli bir
aralıktaki frekanslara izin vermek için kullanılır, mesela sinyalde 4 ve 5 kHz arası
frekanslar kalsın istiyorsak bir bant geçiren filtre kullanırız.
Bu yazıda sonlu dürtü yanıtlı (finite impulse response -FIR-) adı verilen sayısal
filtreleri kullanacağız, bu filtreler tipik olarak sonlu sayıda katsayı olarak hesa-
planırlar, sonra bu katsayılar bir evrişim (convolution) operasyonu ile sinyale
uygulanır.
FIR filtre tasarımını kolaylaştıran en önemli numara evrişim ile ayrıksal Fourier
transformu arasındaki bir ilişkiye dayanıyor. Bir x’e evrişimle bir h filtresi uygu-
layacağımızı düşünelim, ve bu bize y = x ∗ h sonucunu verecek. İlişki şudur
ki eğer x ve h’nin Fourier transformunu alırsak x ∗ h işlemi “frekans yöresinde
(frequency domain)” X · H çarpımına dönüşür, yani frekans yöresindeki çarpım
işlemi zaman yöresindeki evrişim işlemine eşittir [1, sf. 161].

x(n) ∗ h(n) ↔ X(θ)H(θ)

ki X ve H, x, h’nin Fourier transformu.


İspat
Ayrıksal evrişim formülünü hatırlarsak,

X

y(n) = x(n) ∗ h(n) = x(m)h(n − m)
m=−∞

Eşitliğin iki tarafının Fourier transformunu alalım, y(n)’nin transformu Y(θ) ol-
sun,

X
∞  X
∞ 
Y(θ) = x(m)h(n − m) e−jθn
n=−∞ m=−∞

Toplamların yer değiştirebilme özelliğini kullanırsak,

X
∞ X

= x(m) h(n − m)e−jθn
m=−∞ n=−∞

1
Şimdi k = n − m tanımlayalım,

X
∞ X

= x(m) h(k)e−jθ(k+m)
m=−∞ k=−∞

X
∞ X

Y(θ) = x(m)e−jθm h(k)e−jθk
m=−∞ k=−∞

Son ifadede x ve h’nin ayrı ayrı Fourier transformlarını elde etmiş olduk, ve
bu transformlar birbiriyle çarpım halindeler. İspat tamamlandı, gerçekten de
evriştirilen iki öğenin arasındaki ilişki ayrı ayrı Fourier transformu üzerinden
çarpım haline geliyor.
Bu özellik filtre tasarımında son derece faydalı: çünkü eğer belli frekansları ele-
mek istiyorsak bunu yapmanın en rahat yolu frekans yöresinde öyle bir H tanımlamak
ki X’in bazı bölgelerini olduğu gibi bıraksın diğerlerini sıfırlasın. Bu fonksiyon
istenen yerlerde 1 değerine diğer yerlerde 0 değerine sahip olan bir fonksiyon-
dan ibarettir. Fonksiyon bir dikdörtgene benzer, ki bu sebeple ona “tuğla duvarı
(brickwall)” deniyor. Bu tuğla duvarının önemli bir avantajı (ters Fourier trans-
formu ile) zaman yöresine geçiş yapıldığında yine basit bir fonksiyon olması, bu
ünlü sinc fonksiyonudur,

sin(x)
sinc(x) =
x

x=np.linspace(-10.0,10.0,100)
y=np.sinc(x)
plt.plot(x,y);
plt.savefig('compscieng_1_24_14.png')

Sayısal olarak geçişi yapalım, bir kısmı 1 gerisi 0 olan tuğla duvarı tanımlayıp
numpy.fft.ifft ile h’yi elde edelim,

2
H = np.zeros(242)
H[128:142] = 1.
plt.figure()
plt.plot(H)
plt.savefig('compscieng_1_24_02.png')
h1 = np.fft.ifft(H,140)
h = np.real(np.fft.ifftshift(h1))
plt.figure()
plt.plot(h)
plt.savefig('compscieng_1_24_01.png')

İspat
Diyelim ki frekans yöresinde tanımlı H(ω)’nin tuğla duvarı şekli var [3, sf. 247],
öyle ki sıfırda ortalanmış ve −ω, ω arasındaki bir bölgede fonksiyon 1, diğer yer-
lerde 0, yani


1, −ωc 6 ω 6 ωc
H(ω) =
0, ωc 6 |ω|

Bu fonksiyonun zaman yöresindeki karşılığını analitik olarak bulalım. Ters Fourier


transformu,

Z∞ Z ωc
1 jωt 1
h(t) = H(ω)e dω = ejωt dω
2π −∞ 2π −ωc

1 1 jωc t 1
= (e − e−jωc t ) = sin(ωc t)
2π jt πt

ωc sin(ωc t) ωc
= = sinc(ωc t)
π ωc t π

sinc’e erişmiş olduk. Ayrıksal ortamda

sin(2πfc i)
h[i] =

3
Bu fonksiyonu bir sinyal ile evriştirince ona frekans filtresi uygulamış oluruz,
sadece fc altındaki frekanslara izin veren alçak geçiren (low-pass) filtreyi ederiz
[2, sf. 285].
Fakat bir problem var, sinc fonksiyonu sıfır genliğe erişmeden eksi ve artı son-
suzluğa sürekli devam eder. Bu sonsuz uzantı sayısal ortamda kullanışlı değil.
Bunun için fonksiyonu bize sıfırda ortalanmış M+1 tane katsayı değeri bırakacak
şekilde kırpacağız (M çift sayı olmalı, sıfırda ortalanınca geri kalan katsayılardan
her iki yönde eşit sayıda olması için), ve geri kalan tüm sinc değerleri sıfır kabul
edilecek.
Bir diğer problem sıfırda ortalama demek negatif indisler kullanmak demek, bu
bilgisayarlar için problemli; o sebeple her şeyi M/2 sağa kaydırıyoruz.
Fakat kırpmanın bir yan etkisi şudur; kırpma çok keskin bir şekilde yapıldığı için
bu fonksiyonda ani bitiş (abrupt end) yaratıyor ve bu frekans yöresinde pürüzlere
yol açıyor.

Bu problemin bir çözümü pencereleme fonksiyonu kullanmak, ve filtreleme ya-


pacak çekirdeği bu pencereyle çarpıp ani geçişi yumuşatmaya uğraşmak. Ham-
ming penceresi bir seçenek,

w[i] = 0.54 − 0.46 cos(2πi/M)

Nihai filtre
 
sin(2πfc (i − M/2))
h[i] = K 0.54 − 0.46 cos(2πi/M)
i − M/2

4
Kodları altta görüyoruz,

import scipy, matplotlib.pyplot as plt


import numpy as np

def hamming(window_size):
N = window_size;
output = np.zeros((N, 1));
if np.mod(N, 2) == 0 :
m = np.fix(N / 2)
n = m
else:
m = np.fix(N / 2)+1;
n = m-1;
window = 0.54 - 0.46 * np.cos(2*np.pi*(np.arange(m)) / (N-1))
tmp1 = window[:int(m)]
tmp2 = window[np.arange(int(n)-1,-1,-1)]
return np.hstack((tmp1,tmp2))

def sinc_filter_low(order, fc1, fs):


Fc1 = fc1 / np.float(fs)
M = order
B = np.zeros((M+1, 1))
window = hamming(M+1)
for i in range(M+1):
if 2 * i == M:
B[i] = 2*np.pi*Fc1
else:
tmp1 = 2*np.pi*Fc1 *(i-(M/2.))
tmp2 = (i-(M/2.))
B[i] = np.sin(tmp1) / tmp2
B[i] = B[i] * window[i]
return B / np.sum(B)

5
def sinc_filter_high(order, fc1, fs):
Fc1 = fc1 / np.float(fs)
M = order
B = np.zeros((M+1, 1))
window = hamming(M+1)
for i in range(M+1):
if 2 * i == M:
B[i] = 2*np.pi*Fc1
else:
tmp1 = 2*np.pi*Fc1 *(i-(M/2.))
tmp2 = (i-(M/2.))
B[i] = np.sin(tmp1) / tmp2
B[i] = B[i] * window[i]
B = B / np.sum(B)
B = -B
B[(M/2)] = B[(M/2)] + 1
return B

def sinc_filter_band(order, fc1, fc2, fs):


M = order
A = sinc_filter_low(order, fc1, fs).T[0]
B = sinc_filter_high(order, fc2, fs).T[0]
output = A+B
output = -output
output[(M/2)] = output[(M/2)] + 1.
return output

def plotSpectrum(y,Fs):
n = len(y) # sinyal uzunlugu
k = np.arange(n)
T = n/Fs
frq = k/T # frekansin her iki kismi
frq = frq[range(n/2)] # frekansin tek tarafi
Y = scipy.fft(y)/n # fft hesaplamak ve normalizasyon
Y = Y[range(n/2)]
plt.plot(frq,np.abs(Y),'r') # spektrumu grafiklemek

Terminoloji bilgisi: katsayıların kaç tane olduğu filtre performansında değişiklik


yaratabiliyor, bu sebeple filtrelerin bazen kaç tane katsayı içerdiği özellikle belir-
tilir, mesela alttaki örnekteki filtrelere “33 vuruşlu (33-tap)” adı verilir.
Alçak Geçiren Filtre
Bir alçak geçiren filtre örneği fc eşik değeri için altta görülüyor.

import filt
fy=300; # Hz ile sinyal frekansi
wy=2*np.pi*fy; # radyan / saniye ile sinyal frekansi
fs=50; # Hz ile orneklem frekansi
tiv=1./fs; # orneklemler arasinda zaman
tend = 5 # saniye
t=np.linspace(0,tend,tend/tiv); # gecen zaman (5 saniye)

y=0.6*np.sin(wy*t)+0.3*np.sin(3*wy*t)+0.2*np.sin(5*wy*t);

6
f=plt.figure()
plt.plot(t,y)
plt.title(u'Ana Sinyal')
plt.savefig('compscieng_1_24_05.png')
f=plt.figure()
plt.title(u'Filtre Öncesi Frekans')
filt.plotSpectrum(y, fs)
plt.savefig('compscieng_1_24_06.png')

order = 32
fc1 = 1.0
f1 = filt.sinc_filter_low(order, fc1, fs=20).T[0];

y1 = np.convolve(f1, y)
f=plt.figure()
plt.title(u'Alçak Geçiren Filtre Sonrası Sinyal')
plt.plot(np.arange(len(y1)), y1)
plt.savefig('compscieng_1_24_08.png')

f=plt.figure()
filt.plotSpectrum(y1, fs)
plt.title(u'Alçak Geçiren Filtre Sonrası Frekanslar')
plt.savefig('compscieng_1_24_07.png')

7
Yüksek Geçiren Filtre
Yüksek geçiren filtre elde etmek için herhangi bir fc için tanımlı bir alçak geçiren
filtreyi alıp katsayılarını negatife çevirmek yeterli (bir de ortada sıfır noktasında
bir pozitif değer ekleniyor). Bu değişim o filtreyi fc için yüksek geçiren hale ge-
tirir.

fc1 = 4
f2 = filt.sinc_filter_high(order, fc1, fs).T[0];
y2 = np.convolve(f2, y)
f=plt.figure()
plt.plot(np.arange(len(y2)), y2)
plt.title(u'Yüksek Geçiren Filtre Sonrası Sinyal')
plt.savefig('compscieng_1_24_10.png')
f=plt.figure()
filt.plotSpectrum(y2, fs)
plt.title(u'Yüksek Geçiren Filtre Sonrası Frekanslar')
plt.savefig('compscieng_1_24_09.png')

8
Bant Geçiren Filtre
fc1 ve fc2 frekansları arası haricindeki tüm diğer frekanslar elensin istiyorsak fc1
için alçak geçiren fc2 için yüksek geçiren filtre tanımlayıp bu iki filtreyi toplarız.
Bu toplam bize bir bant reddi (bant-reject) filtresi verir. Ama biz bunun tersini
istiyoruz, o zaman eldeki katsayıların üstteki bahsedilen yöntemle tersini alırsak
bir bant geçiren filtre elde ederiz.

fc1 = 4.0
fc2 = 4.5
f3 = filt.sinc_filter_band(order, fc1, fc2, fs);
y3 = np.convolve(f3, y)
f=plt.figure()
plt.title(u'Bant Geçiren Filtre Sonrası Sinyal')
plt.plot(np.arange(len(y3)), y3)
plt.savefig('compscieng_1_24_12.png')
f=plt.figure()
filt.plotSpectrum(y3, fs)
plt.title(u'Bant Geçiren Filtre Sonrası Frekanslar')
plt.savefig('compscieng_1_24_11.png')

9
Karşılaştırma amaçlı olarak scipy.signal.butter kütüphane çağrısı ile bir But-
terworth bant geçiren filtreyi de aynı veri üzerinde işlettik.

from scipy.signal import butter, lfilter


def butter_bandpass(lowcut, highcut, fs, order):
nyq = 0.5 * fs
low = lowcut / nyq
high = highcut / nyq
b, a = butter(order, [low, high], btype='band')
return b, a

def butter_bandpass_filter(data, lowcut, highcut, fs, order):


b, a = butter_bandpass(lowcut, highcut, fs, order=order)
y = lfilter(b, a, data)
return y

low = 4; high=4.5
yb = butter_bandpass_filter(y, low, high, fs, order=1)
plt.title(u'Bant Geçiren (Butterworth) Filtre Sonrası Sinyal')
plt.plot(np.arange(len(yb)), yb)
plt.savefig('compscieng_1_24_13.png')

10
Not: Butterworth filtreleri FIR değil IIR filtreleri (bir sonraki yazının konusu).
Kaynaklar
[1] ElAli, Discrete Systems and Digital Signal Processing with Matlab, 2nd Edition
[2] Smith, The Scientist and Engineer’s Guide to Digital Signal Processing, 2nd Ed.
[3] Sierra, Digital Signal Processng with Matlab Examples Volume 1

11
Ders 25
[ders notları atlandı]
z Transform
z Transform, Laplace Transformunun ayrıksal dünyadaki karşılığıdır, transform
edilen sürekli fonksiyon f(t) değil, ayrıksal, bir vektör olarak görülebilecek x(n)’dir.
z Transform

X

Z[x(n)] ; X(z) = x(n)z−n
−∞

ki z bir kompleks sayıdır.


Gelişigüzel (casual) sistemlerden gelen verilerde sadece n > 0 veriye bakılabilir,
o zaman alt sınır sıfır olur

X

X(z) = x(n)z−n
0

z Transform ne işe yarar? Laplace Transform diferansiyel denklemlerin çözülmesine


yardım ediyordu. z Transform benzer şekilde farklılık (difference) denklemlerin
çözülmesine yardım eder. Farklılık denklemi mesela

y(n) = 0.85y(n − 1) + x(n) (3)

şeklinde olabilir. Daha genel olarak farklılık denklemleri şu şekilde belirtilebilir,

X
N X
M
ak y(n − k) = bl x(n − l) (1)
k=0 l=0

İki üstteki örnek, bu genel denklemin N = 1, M = 0 olduğu halidir, katsayılar


a1 = 0.85, b0 = 1. Genel formdan y(n)’i dışarı çekebiliriz, o zaman k sıfır yerine
k = 1’den başlar

X
N X
M
y(n) + ak y(n − k) = bl x(n − l)
k=1 l=0

Genel çözüm için farklılık denkleminin bu formuna z Transform uygulayabiliriz.


Ama ondan önce kaydırma işlemi, lineerlik gibi bazı temel özellikleri, işlemleri
görelim. Mesela

1
X(z) = x(0) + x(1)z−1 + x(2)z−2 + ... (2)

ise, bu dizin üzerinde zaman kaydırma işlemi yapsak, yani −1 indeksi 0 haline
gelse, onun gibi tüm değerler bir ileri kaysa, x(−1), x(0) olur, ve transform

x(−1) + x(0)z−1 + x(1)z−2 + ...

Şimdi z−1 ’i dışarı çekelim


 
−1 −1
= x(−1) + z x(0) + x(1)z + ...

Köşeli parantez içine bakarsak, oradaki değerler (2)’deki seriye benzemiyor mu?
O zaman oraya direk X(z) değerini koyabiliriz

= x(−1) + z−1 X(z)

Bir daha kaydırırsak,

z−2 X(z) + z−1 x(−1) + x(−2)

elde ederiz. Genel olarak m kadar kaydırırsak

z−m X(z−1 ) + z−m+1 x(−1) + z−m+2 x(−2) + ... + x(−m)

Eğer başlangıç şartları sıfır ise, üstteki formülde x(−1), x(−2), .. tamamen sıfır
kabul edilebilir, ve daha basit şu formülü elde ederiz.

Z[x(n − m)] ; z−m X(z−1 )

Ayrıca, z Transformun lineerlik özelliği sayesinde

Z(ax(n)) = aZ(x(n)) ; aX(z)

Şimdi bu bilgiyle beraber (1)’in z Transformunu yapalım.

X
N X
M
Y(z) + ak z−k Y(z) = bl z−l X(z)
k=1 l=0

 X
N  X
M
−k
→ Y(z) 1 + ak z = bl z−l X(z)
k=1 l=0

2
PM
bl z−l X(z)
l=0
→ Y(z) = PN (5)
1 + k=1 ak z−k

Formülün bölümdeki üst kısmını açarsak

b0 z0 + b1 z−1 + b2 z−2 + ... + bm z−M

b0 z−M dışarı çekilirse

b1 M−1 b2 M−2 bM
= b0 z−M (zM + z + z + .. + )
b0 b0 b0

Bölümün alt kısmını açarsak

1 + a1 z−1 + a2 z−2 + ... + aN z−N

z−N dışarı çekersek

= z−N (zN + zN−1 + .. + aN )

Bu yeni formları bölümde Y(z) içinde yerine koyalım

b0 z−M (zM + .. bbM0 )


Y(z) =
z−N (zN + .. + aN )

N−M
zM + .. bbM0
= b0 z
zN + .. + aN

Bölüm ve bölene bir daha bakalım şimdi. Burada gösterilenler birer polinom, ve
Cebirin Temel Teorisi’ne (Fundamental Theorem of Algebra) göre n derecesin-
deki bir p(x) polinomunun mutlaka n tane reel ya da kompleks kökü vardır.
Bir polinomun kökü var ise, bu polinom p(x) şu şekilde de gösterilebilir

p(x) = (x − rn )(x − rn−1 )..(x − r1 )

Bu mantığı iki üstteki formüle uygularsak

QM
N−M (z − zl )
= b0 z QNl=1
k=1 (z − pk )

Yani b0 zN−M haricindeki ifadeler bir polinomun oluşmasına sebep olurlar, ve bu


polinomun kökleri bulunabilir, kökler bulununca çözüm olan z değerleri bulunmuş

3
olacaktır. Bu z değerlerini alıp z Transformunu oluşturuz, ve ya tabloya bakarak,
ya da başka şekilde ters transform yaparak farksal denklemin çözümüne ulaşmaya
çalışırız.
Çözmek istediğimiz örnek (3)’e tekrar bakalım. Üstteki formüle bu noktada gerek
yok, (5)’e göre bile bu denklemin z Transformunu bulabiliriz.

1
Y(z) =
1 − 0.85z−1

Eğer yaygın z Transformların tablosuna bakarsak, |z| > 0.85 için üstteki formülün
ters z Transformunun

h(n) = Z−1 [Y(z)] = 0.85n u(n)

olduğunu öğreniyoruz, ve u(n) şöyle


1, eğer n > 0
u(n) =
0, eğer n < 0

Dikkat edilirse ters z Transform tablosunda y değil h bazlı sonuçlar gösteriliyor, h


fonksiyonları dürtü cevabı (impulse response) fonksiyonlarıdır, ve hesaplamaları
evrişim (convolution) üzerinden olur. Bir h, bir lineer sistemi özgün olarak tem-
sil ettiği için h’i alıp y bazlı sonuca gitmek çok kolaydır, hemen h’in tarif ettiği
evrişimi yaparız.

X
∞ X

y(n) = x(k)h(n − k) = x(k)0.85n−k u(n − k).
k=−∞ k=−∞

Kodlama
Düşünelim ki (3) ile tarif edilen farklılık denklemi bir şirketin patent portföyünü
temsil ediyor.
Bu şirket, her sene portföyü y(n)’e, x(n) kadar yeni patent ekliyor, ama her sene
aynı zamanda elindeki patentlerin yüzde 15’i ”eskiyor”, yani zamanları dolarak
portföyünden çıkıyor. Bu eksiltme işlemini bir önceki y(n)’i 0.85 ile çarparak
temsil ediyoruz.
Böyle bir problemde x(n) bize veri olarak verilecektir, ve toplamsal / kümülatif
(cumulative) y(n)’i hesaplamamız istenecektir. Bu hesap literatürde “değer kaybe-
den kümülatif toplam (cumulative sum with deprecitation)” olarak biliniyor.
O zaman üstteki formüldeki sonucu kodlarsak, ve örnek veriyle

patents = np.array([ 4., 3., 2., 8., 4.,


4., 10., 4., 10., 7.])

4
def u(n,k):
if n-k < 0: return 0
return 1.

def y(n,data):
sum = 0
for k in range(len(data)):
sum += data[k]*(0.85**(n-k))*u(n,k)
return sum

for n in range(len(patents)):
print y(n,patents)

4.0
6.4
7.44
14.324
16.1754
17.74909
25.0867265
25.323717525
31.5251598962
33.7963859118

Bu sistemi otomatik olarak çözen Python işlemi lfilter çağrısıdır.

from scipy.signal import *

a = np.array([ 4., 3., 2., 8., 4.,


4., 10., 4., 10., 7.])
d = 0.15
res = lfilter((1,),(1,d-1),a)
k = [a[0]]
for inv in a[1:]: k.append((1-d)*k[-1] + inv)
print np.array(k)

[ 4. 6.4 7.44 14.324 16.1754 17.74909


25.0867265 25.32371752 31.5251599 33.79638591]

Not: Üstteki hesaplar [1] için kullanıldı.


Frekans Filtremek, IIR Filtreleri
Önceki dersteki FIR filtreleri sinyal üzerinde bir evrişimle kodlandı, filtre kat-
sayılarını geriye dönük ham sinyal üzerinde uygulayarak filtrelenmiş sonucu
üretiyorduk,

y[n] = a0 x[n] + a1 x[n − 1] + a2 x[n − 2] + a3 x[n − 3] + ...

Fakat filtre için ham sinyalin kendisi elimizdeki tek girdi seçeneği değil, sinyal x
ile beraber geriye dönük şekilde y’nin kendisini de kullanabilirdik, bu durumda
y’yi üretmek için y’nin kendisini kullanmış olurduk, bu sebeple bu tür filtrelere
özyineli (recursive) filtreler ismi de veriliyor. Yani

5
y[n] = a0 x[n] + a1 x[n − 1] + a2 x[n − 2] + a3 x[n − 3] + ...
+ b1 y[n − 1] + b2 y[n − 2] + b3 y[n − 3] + ..

Peki FIR yöntemi ile filtre tasarlamayı biliyoruz, niye üstteki gibi bir yaklaşım
kullanalım ki? Cevap özyineli filtrelerin FIR’e göre çok hızlı işlemeleri. IIR yönteminin
de bazı negatif tarafları var, fakat bunlardan uzak durabilirsek optimal hızda
işleyen bir filtre elde etmek mümkündür. Ayrıca elektronik devrelerden, analog
temelli pek çok özyineli filtre biliniyor, bu filtreleri sayısal ortamda kullanabilmek
iyi olur.
IIR’nin genel verimliliği hakkında bir örnek verelim: diyelim ki 7 vuruşlu bir
ortalama filtremiz var, ve n = 50 anında y[50] şu değere sahip,

y[50] = x[47] + x[48] + x[49] + x[50] + x[51] + x[52] + x[53]

Sinyalde n merkezli olacak şekilde 3 geri ve 3 ileri gidilerek toplam alınıyor,


filtrelenmiş sinyal bu. Şimdi aynı filtrenin bir sonraki zaman kesitinde, y[51]’deki
değerine bakalım,

y[51] = x[48] + x[49] + x[50] + x[51] + x[52] + x[53] + x[54]

Bu toplam aşağı yukarı iki üstteki ile aynı değil mi? x[48] ve x[53] arası değerler
aynı şekilde toplanıyor, o zaman eğer elimizde y[50] değeri var ise, y[51]’i hesapla-
mak için en optimal yöntem

y[51] = y[50] + x[54] − x[47]

hesabı olacaktır, yani y’nin bir önceki zaman kesitindeki değerini kullanmak.
IIR filtreleri işte bu sebeple daha verimli işlerler, eğer tasarımlarında dikkatli ol-
unursa daha az miktarda katsayı ile çok daha hızlı hesaplar yapabiliriz [2, sf.
283].
Şimdi daha önceki genel formu hatırlayalım

X
N X
M
y(n) + ak y(n − k) = bl x(n − l)
k=1 l=0

Bu formül bir farklılık denklemi. Bu denklemin transfer fonksiyonu altta, ki (5)’in


literatürde daha çok görülen hali H kullanır,

PM
bl z−l X(z)
l=0
H(z) = PN
1 + k=1 ak z−k

6
Açılmış şekilde

b0 + b1 z−1 + .. + bm z−l
=
1 + a1 z−1 + .. + an z−k
Bu formun güzel tarafı farklılık denklemleri ile üstteki formun arasındaki di-
rek bağlantı. Eğer transfer fonksiyonuna bir şekilde erişebilirsek oradan direk
farklılık denklemine geçilebiliyor, katsayılar a0 , .., an ve b0 , .., bm farklılık den-
kleminde aynen kullanılacak haldeler. Bu kavram IIR filtresi tasarlarken faydalı
olacak.
IIR Tasarımı
IIR filtre tasarımı için pek çok yöntem var. Bizim işleyeceğimiz yöntem dürtü
değişmezliği (impulse invariance) yöntemi, bir diğeri mesela çiftlineer (bilinear)
transform yöntemi. DD ile bilinen bir analog filtrenin analog transfer fonksiyonu
H(s)’yi alırız, sonra ters Laplace transformu ile dürtü cevap fonksiyonu h(t)’yi
elde ederiz. Sayısala geçmek için bu fonksiyonu belli aralıklarla örnekleriz, yani
h(t)’yi h(nT ) haline getiririz. Sonra bu örneklenmiş fonksiyonun z-transformunu
alarak H(z)’ye geçiş yaparız, bu geçiş bize özyineli fonksiyonumuzda kullan-
abileceğimiz direk katsayıları verecektir.
Analog deyip geçmeyelim, alçak geçiren, yüksek geçiren, vs. filtreleme konusunda
burada derin bir literatür var. Sayısal yöntemler ortaya çıktığından beri haklı
olarak çok ilgi gördüler, fakat unutmamak lazım, sayısal yöntemlerden önce ana-
log elektronik devreler filtreleme yapıyordu (halen de yapıyor), mesela alttaki
devre çok basit bir alçak geçiren filtredir [4].

Bu devreye verilen vs sinyali (yani içinde pek çok frekans içeren elektrik akımı)
seçilen R, C’ye göre vo ’da alçak geçiren şekilde filtrelenmiş olarak çıkacaktır. Bu
klasik bir filtre devresi ve bir transfer fonksiyonu var. Aslında çok basit,

1
H(s) =
s+1
Bir frekans eşik değeri (cutoff frequency) Ωc için [3, sf. 527] H( Ωsc ) kullanılıyor.
Diyelim ki Ωc = 20 rad/s,
   
s s 1 20
H =H = =
Ωc 20 (s/20) + 1 s + 20

7
Simdi ters Laplace ile h(t) bulunur,
 
s 20
h(t) = L H −1
=L−1
= 20e−20t
20 s + 20

Sonra T h(nT ) ayrıksal fonksiyonunun z-transformunu alırız,

X
∞ X

n 20T
H(z) = 20T e −20nT −1
z = 20T e20T z−1 = (4)
n=1 n=0
1 − e−20T z−1

Son eşitlik nasıl mümkün oldu? Geometrik serilerinin açılımı sayesinde, hatırlarsak,

X

1
xn =
n=0
1−x

Bu kadar. (4) formülündeki son durum bize a, b katsayılarını da veriyor. a0 =


1.0, a1 = −e−20T , b0 = 20T . Bu şekilde seçtik çünkü scipy.signal.lfilter ile
uyumlu olmasını istedik, bu kütüphane,

a[0]y[n] = b[0]x[n] + b[1]x[n − 1] + ... + b[M]x[n − M]


−a[1]y[n − 1] − ... − a[N]y[n − N]

formülünü kodluyor.
Şimdi örnek üretelim, 1 rad/s = 1/2π Hertz olduğuna göre, eşik değeri Ωc

cutoff = 20 * 1/(2*np.pi)
print cutoff, 'Hz'

3.18309886184 Hz

O zaman

fs = 40.0 # orneklem orani


T = 1/fs
L = 5.0 # saniyelik sinyal
n = int(L * fs)
t = np.linspace(0, L, n, endpoint=False)
data = np.sin(2.0*2*np.pi*t) + np.cos(7*2*np.pi*t)
plt.plot(t,data)
plt.savefig('compscieng_1_25_02.png')

8
Biri 2 diğeri 7 Hz ile üretilmiş iki sinyali üst üste koyduk. Filtreleme ile bunu
ayrıştırmaya uğraşalım,

x = data # formul ile ayni olsun diye


a = [1.0, -np.exp(-20*T)]
b = [20*T]
print b, a
y = np.zeros(len(x))
for n in range(1,len(data)):
y[n] = b[0]*x[n] - a[1]*y[n-1]
plt.plot(t,y)
plt.savefig('compscieng_1_25_03.png')

[0.5] [1.0, -0.60653065971263342]

Fena değil. Eğer scipy.signal.butter ile katsayıları üretsek ve lfilter ile uygu-
lasak (ki üstteki kod lfilter ile aynı çarpımı yapıyor),

from scipy.signal import butter, lfilter


nyq = 0.5 * fs
low = 2.0 / nyq
b, a = butter(1, low, btype='lowpass')
print b,a

9
y = lfilter(b, a, x)
plt.plot(t,y)
plt.savefig('compscieng_1_25_04.png')

[ 0.13672874 0.13672874] [ 1. -0.72654253]

Bu biraz daha pürüzsüz oldu, kütüphane çağrıları farklı katsayılar gösteriyor bu


arada, çünkü farklı bir sayısala geçiş yöntemi kullanıyorlar (çiftlineer transform
olmalı). Eğer filtre derecesini yani vuruş sayısını arttırırsak, yani daha fazla kat-
sayı ile

b, a = butter(2, low, btype='lowpass')


print b
print a
y = lfilter(b, a, x)
plt.plot(t,y)
plt.savefig('compscieng_1_25_05.png')

[ 0.02008337 0.04016673 0.02008337]


[ 1. -1.56101808 0.64135154]

Bu daha da iyi oldu.


Bir mühendislik notu olarak şunu ekleyelim, diyelim ki mobil ortamda filtreleme

10
yapmak istiyoruz, ve IIR yaklaşımı kullanacağız. Bu durumda üstteki sayısal
kütüphanelere mobil ortamında ihtiyacımız yok. Bize tek gereken a, b katsayıları,
geliştirme sırasında dizüstü bilgisayarımızda vuruş sayısını verip filteyi “tasarlıyoruz”
ve katsayıları elde edip mobile sadece bunları taşıyoruz. Artık bu katsayıları alıp
sinyal üzerinde uygulamak basit bir çarpma / toplama işlemi haline gelecektir.
Bütün sihir katsayılarda!
Kaynaklar
[1] Bayramlı, M., Patent Strategies and R&D in Complex Product Industries, http:
//amsdottorato.unibo.it/5151/1/bayramli_meltem_tesi.pdf
[2] Smith, The Scientist and Engineer’s Guide to Digital Signal Processing, 2nd Ed.
[3] Pularikas, Signals and Systems Primer with Matlab
[4] Irwin, Basic Engineering Circuit Analysis, 10th Edition

11
Ders 1.26
[giriş bölümü atlandı]
Dersin son 10 dakikasında iki boyutlu sonlu öğeler (finite elements -FEM-) konusuna
giriş yapalım. Problem alanını temsil etmek için üçgenler kullanacağım, ızgara
üçgen bazlı yani. Kareler vs de olabilirdi..

Önemli nokta şu, üçgenler gelişigüzel noktalarda olabilir, düğümlerin nerede,


üçgenlerin ne şekillerde olacağını biz belirleriz. Bu FEM yaklaşımının güçlü taraflarından
biri. Üstteki ızgara fena değil, 180 dereeye yakın açılı üçgenler yok (o zaman öteki
açılar yamyassı hale gelirdi, üçgen ise yaramazdı). Tabii yapısız dahi olsa ızgarayı
yaratmak için bir program kullanmak iyi olur, benim bir tez öğrencim böyle bir
programı geçende yazdı [hoca bugünlerde pek çok kişinin kullandığı distmesh
programından [1] bahsediyor herhalde].
Şimdi FEM ana fikrini hatırlayalım. Zayıf forma geçiş yapıyorduk değil mi? Pois-
son için ne olur? Hatırlarsak Poisson, Laplace’in eşitliğin sağında bir değer olan
hali.
ZZ ZZ
∂u ∂v ∂u ∂v
+ dx dy = f(x, y)v(x, y) dx dy
∂x ∂x ∂y ∂y

v’ler tüm mümkün test fonksiyonları. FEM fikri nedir? Bir deneme (trial) fonksiy-
onu seç, ve çözümün yaklaşıksal formu bu deneme fonksiyonlarını bir kombi-
nasyonu olsun.

U = U1 φ1 (x, y) + ... + Un φn (x, y)

Tabii [Galerkin yaklaşımına göre] deneme ile test fonksiyonları aynı, yani φ = V.
Boylece n tane denklem elde ediyorum. Zayıf formu n kere kullanarak, n tane
test ile n tane denklem elde ediyorum. Her denklem için iki üstteki formülde v,
φ’lerden biri oluyor, u ise üstteki toplam, yerine koy, bir denklem elde et.

1
Hangi φ’nin seçildiği çok önemli. FEM’e kazandıran bu özelliği. Her ızgara nok-
tasında, her üçgende geçerli olacak basit, iyi huylu fonksiyonlar seçmem (basit
polinomlar mesela) ve onlar üzerinden ana fonksiyonu çözebilmem. Bugün li-
neer olanlarından bahsedeceğim, şapka fonksiyonları, çok boyutlu formda tabii
ki, yani piramit olacaklar. Üstteki figürde yeşile işaretli olan yerde mesela bir pi-
ramit olsun, orada değer 1 olacak, piramitin üst noktası orada, ve o yerel fonksiyon,
o piramit için çevresindeki ve diğer her ızgara noktası için değer 0.
Dersin geri kalanında bu piramiti hayal edin.. Belki de ona çadır demek daha
doğru olur. Piramitin bazı nerede? Alttaki koyu çizgi,

Piramitin, çadırın 6 tane yüzü, düz kenarı var. İşte bu piramit, mesela φ1 ola-
caktır.. bir diğer çadır φ2 vs. Bu fonksiyonları bu şekilde kurduğum zaman
x türevlerini alabilirim, y türevlerini alabilirim, değil mi? Çünkü düşünürsek,
tipik bir üçgenin türevi hakkında ne biliyorum? Mesela düzlemlerden biri için
fonksiyon a + bx + cy formülünde olsun, üç boyutlu uzayda düzlemin formülü
doğal olarak, üçgenin üç köşesi var, formülde üç tane katsayı var, a, b, c. Bu du-
rumda mesela x türevi çok basit, cevap b. y türevi aynı şekilde basit, sadece c.
Bu durum üstteki entegral hesabını basitleştirecek tabii ki, tüm FEM hesabı pat
diye çözülebilecek. Tabii işin zor tarafı hangi üçgenin hangi düğünlerle bağlantılı
olduğunu takip etmek, tüm çözüm matrisini oluştururken bunu hesaba katmak,
vs. Fakat her öge matrisi basit olacak.
Kaynaklar
[1] DistMesh, http://persson.berkeley.edu/distmesh/

2
Ders 1.27
Bu derse vereceğim ödevi tarif ederek başlayayım, ödevde Poisson denkleminin
çözümünü, ama sınırları kare değil çember olan bir ızgarada çözmenizi isteyeceğim.
Çözülecek denklem

−uxx − uyy = 4

Eşitliğin sağ tarafı f, ve bu f sabit olduğu için v ile çarpım sonrası alınacak en-
tegraller daha basit oluyor tabii, sabit çarpı deneme fonksiyonu, kolay hesap.
Sınırda, çember üzerinde, u = 0 şartını koyuyoruz. Bu sistemi çözeceğiz. Anal-
itik çözümün ne olduğunu görmek zor değil, u = 1 − x2 − y2 . Yerine koyarsak
doğrulaması kolay, iki kere x türevi 2, y türevi 2, toplam 4.
Çember içindeki ızgaraya önce bir poligonla başlıyorum. Bu arada araştırma
sorusu bağlamında aklımdaki sorulardan biri hesabın ortaya çıkaracağı hata mik-
tarı. Bazı ızgaralar diğerlerinden daha iyi olabilir.

Neyse, sınır şartımızı hatırlarsak düz çizgilerin çembere değdiği noktalarda u =


0. M tane köşe olsun, ve orta noktadan köşelere çizgiler çekerek üçgenler oluşturalım,
altta üçgenlerden biri görülüyor,

Üçgenin alt iki köşesinde tabii ki u = 0 şartı geçerli. İki üçgen arasındaki sınırda
ise doğal sınır şartı denilen Neumann şartı geçerli olacak, eğimin sıfır olma şartı,
yani du/ dn = 0. Orijinde ne yapmamız gerektiğini şimdilik bilmiyoruz.
Gerçek bir problem işte burada. Muhakkak problem biraz yapay, çünkü anali-
tik çözümün ne olduğunu biliyoruz, ama mesela bu problemde hesap yapmak,
hatanın ne olacağını düşünmek, bunlar hala ilginç sorular ve ciddi işler.
Bu problemi çözerken parçasal lineer öğeler (piecewise linear elements) kullan-

1
manızı isteyeceğim, daha önce bahsettiğim piramitler bunlar. Ama bazılarınız
karesel (quadratic) öğeler kullanmak isterse buna hayır demem. Bu öğeler daha
hassas / doğru sonuçlar verecektir.
Şimdi ızgarayı daha detaylı şekilde yaratalım. Bir liste yaratacağız, bu listede
ızgara noktaları olacak, bu liste çözüm algoritmasına verilecek ve algoritma oradan
devam edecek. Çember içinde daha önce yarattığımız üçgenlerden iki tanesini
yanyana düşünelim, en sağ üstteki nokta nerededir? (cos π/8, sin π/8) değil mi?
Sonra en soldan en sağa N tane (resimde N = 4) düğüm daha koyarız, her
aralık yatay eksende h büyüklüğünde olabilir, ve Nh = cos π/8 tabii ki. Sonra
dörtgenleri ortadan kesen çizgiler de ekliyorum ve alttaki şekil ortaya çıkıyor,

Izgara düğüm noktalarına indis atamak iyi olur, soldan sağa önce orta çizgi üzerinde
1,2,3,4,5 diye gideriz, sonra üst kenar, ardından alt, 13 tane düğüm olur. Üçgenlere
de indis atarız, 14 tane üçgen var. Düğüm noktalarının listesi (0,0), (h,0), (2h,0), ..
diye gidecek. Peki üçgenler? Onları köşe indisleriyle belirtebiliriz, her üçgen için
üç tane.
Bu listeleri alan kod bir K matrisi oluşturur, matris eşsiz (singular) olur çünkü
sınır şartları daha içinde yok. En sağ üç nokta sıfırlandıktan sonra (sınır şartı
onları etkiliyor) matris tersi çevrilebilir hale gelir, ve Ku = f çözülür. Kodun
yaptığı K ve f’yi oluşturmak.
Üçgen şekilleri hakkında; üçgenlerin açıları ufak olmayacak şekilde seçin dedik
fakat probleme göre bu değisebilir, mesela bir uçak kanadının aerodinamik simülasyonu
için FEM kullanıyorsanız, havanın akışı yönünde ince ince üçgenler koymak gereke-
bilir çünkü ilginç olan fiziki fenomen o boyutta vuku bulmaktadır.
Şimdi bir adım geriye atıp resme bir daha bakalım. Matrisi oluştururken temel
aldığımız formül Poisson / Laplace denklemlerini zayıf formu. Güçlü formdan
başlayalım,

−uxx − uyy = f(x, y)

Zayıf forma geçmek için iki tarafı bir deneme fonksiyonu ile çarpıyorum, ve tüm
alan üzerinden entegralini alıyorum,

2
ZZ ZZ
(−uxx − uyy )v(x, y) dx dy = f(x, y)v(x, y) dx dy (1)

Üstteki “tüm mümkün (admissable)” v(x, y)’ler için yapılır. Ana fikir şu eğer
üstteki geniş bir v ailesi için doğruysa bunun olmasının tek yolu sol tarafta çarpılanların
sağ tarafta çarpılanlara eşit olması, çıtlatılan temel yardımcı önerim (lemma) bu..
Burada sözel olarak belirttik daha kuramsal şekilde de ispatı var ama, ana fikir
güçlü formun zayıf forma olan eşitliği.
Sonraki adım nedir? Eşitliğin sağ tarafı iyi ama sol taraf daha iyi olabilir, sol
tarafta ikinci türev var, ve benim piramit fonksiyonlarımın ikinci türevleri yok. O
zaman parçalı entegrasyon tekniğini uygularım, böylece türevi u’dan v’ye geçirebilirim,
u’da tek türev kalır ve piramitlerimi kullanabilirim.
Parçalı entegrasyon tekniğinin iki boyutlu versiyonunu kullanmam lazım. Green’in
formülü gerekli, ya da Gauss-Green formülü [2]. Şimdi (1)’de eşitliğin sol tarafını
alttaki gibi yazayım,
ZZ
− div(grad u)v dx dy

Bu formülde div v’ye gidince artı oluyor, devriği alınıyor grad oluyor,
ZZ I
= (grad u)(grad v) dx dy + (grad u · n)v (2)

Ya da farklı bir formda şöyle yazabilirim,

ZZ  ZZ
du dv du dv
+ = f(x, y)v(x, y) dx dy
dx dx dy dy

Bizim örneklerimizde, bu derste deneme, test fonksiyonları sürekli, kesintili süreksiz


değil. O durumda matematikte bambaşka bir aleme giriyoruz, “süreksiz (discon-
tinuous) Galerkin” denen alan bu, kendi uzmanları var, vs. Biz sürekli (continu-
ous) Galerkin, CG yapıyoruz.
Ve FEM’in özüne geliyoruz artık, iyi huylu, güzel polinomlardan oluşan φ’ler ile,

U = U1 φ1 (x, y) + ... + UN φN (x, y)

Resimde görülen ızgaradaki her düğüm için bir φ, 13 tane olacak yani, sonra
v ile φ’yi aynı seçeceğim, ve böylece sonsuz boyut yerine 13 boyutta çalışıyor
olacağım. Sonra üstteki az boyuttaki alt uzayı, FEM uzayını, yani formülünü
alıyorum ve zayıf forma sokuyorum, ve onu 13 tane v ile ayrı ayrı ilintilendirip
’test ediyorum’. Sokma işlemini yapalım,

3
ZZ  ZZ
dU dV dU dV
+ = fV dx dy
dx dx dy dy

Bu entegral tüm alan üzerinden. Kullandığım U bilinen fonksiyonların bir kom-


binasyonu, ve V’ler kombine edilen aynı fonksiyonlardan seçilecek (Galerkin
yöntemi olduğu için).
Tek boyut örneğine kıyasla hala yeni bir fikir eklemiş olmadık. Tek boyutta
yanyana düşen iki şapka fonksiyon türevlerinin entegralini almaktan bahsettik,
bir alternatif ise bir bölge seçip ona dokunan deneme fonksiyonlarından bir 2
x 2 öğe matrisi yaratmaktı. İki boyutta bu yöntem doğru yöntem. Seçilen alan
üçgen tabii ki, yani kod her üçgene teker teker bakacak ve onlardan ayrı matrisler
oluşturacak. Yani üstteki entegral her üçgen için oluşturulacak .
Başta P1 öğeleri kullanacağız demiştik, yani tek derece polinom. Her üçgen için
P1 öğesi nasıl oluştururuz?

Üstteki üçgende tepe noktada U1 yüksekliği, alt solda U2 alt sağda U3 yüksekliği
var. Düğümlerdeki değerler bunlar. Üçgenin ortasında, yani o düz yüzeyde
(düz çünkü 1’inci derece polinom bunu verir) U değeri U = a + bx + cy. O
zaman U1 , U2 , U3 değerlerini biliyorsam a, b, c katsayılarını da biliyorum demek-
tir (düzlem formülünde köşe noktaları düzlem formülünü belirler), diğer yönde
doğru muhakkak. Bu geçişi yapan bir 3 x 3 boyutunda bir matris var yani (3 x 1
vektör alan ve 3 x 1 vektör döndüren bir hesap doğal olarak o boyutta).
Düğüm değerleri ile katsayılar arasında bir tercüme yapıyoruz, bu gerekli çünkü
bilinmeyenler düğüm değerleri.. bilinmeyenler piramit fonksiyonunu çarpan
değerler, mesela üst köşede 1 yüksekliğindeki piramit fonksiyonunu başta U1
ile çarpıyoruz, piramit o noktada 1’den başlayıp diğer köşelerde 0’a inen bir şey
hatırlarsak, aynı şekilde U2 kendi köşesinde 1’den başlayıp diğerlerinde 0’a inen
piramiti çarpıyor, U3 de öyle. Ortadaki o düzlük te verilen a+bx+cy formülünde.
U1 ,U2 ,U3 noktalarının nerede olduğunu biliyoruz, değil mi, onları ızgarayı oluştururken
biz seçtik. Bu noktalardan bir 3 x 3 matrisi oluşturacağız, ki böylece a, b, c kat-
sayılarına geçiş yapabilelim.
Katsayılar niye lazım? Çünkü entegrasyon işlemini yaparken o katsayılar bize
lazım, dU/ dx, dU/ dy türevleri için.
P2 için formül

4
U = a + bc + cy + dx2 + exy + fy2

şekline geliyor. Katsayı sayısı arttı, 6 tane oldu. 6 tane bilinmeyen için 6 tane
bilinen gerekir o zaman üçgen üzerinde 3 yerine 6 noktadan değer almam lazım,

Bazı noktalar üçgenin uçlarında, diğerleri ortalarda. Izgara içindeki diğer üçgenleri
de unutmayalım,

Onların da benzer orta noktaları olacak, ve dikkat, bu noktalar, aynen köşe nok-
talar gibi diğer üçgenler ile paylaşılıyor olacak. O paylaşım metotun önemli bir
özelliği.
Bu büyük ızgarada 16 düğüm var. Ve her üçgen içinde üstteki yeni U formülü
işlemde. Bu durumda, bilinmeyen 6 değeri bilinen 6 değere ilintilendirmek için
bize bir 6 x 6 boyutunda matris gerekecek.
Peki her üçgen için çatı neye benzer? Hafiften eğimli olur değil mi? İki boyutlu
parabol şeklinde yani. Bir soru daha soralım, mesela sol üst üçgenin bu eğimli
parabolu ile üst sağ üçgenin parabol çatısı birbiri ile bağlantılı olur mu? Bir
süreklilik var mıdır? Evet, çünkü dikkat edersek bu iki üçgen arasında paylaşılan
bir kenar var, orada üç tane nokta ortak. Sürekliliği sağlamak için bu üç nokta
yeterli mi? Bu sorunun cevabı FEM’i batıran ya da çıkartan cevap olacak, ama
cevap evet. Dikkat edersek iki parabol yüzey arasındaki çizginin formülü nedir?
Tek boyutlu parabol! Bu tür eğrilerin formülünü belirtmek için üç tane katsayı
yeterli değil mi? Cevap evet. Demek ki o üç bağlantı noktası yeterli.

5
Küpsel öğeler peki? Onlar için 4 tane daha katsayı lazım, o zaman 4 tane daha
düğüm eklemem lazım. Yeni düğüm noktaları alttaki gibi dağıtılabilir,

Bu sefer üçgen ortasına da bir nokta koyduk, kalan noktalar kenarlarda 4’er tane,
ki bu 4 nokta daha önceki örnekte olduğu gibi geçişlilik için yeterli.
Ekler
Hocanın formülü (2)’yi türetmek için [2]’deki Gauss-Green formülünden başlarsak,
ZZ ZZ Z
grad v · w dx dy = v(− div w) dx dy + vw · n ds
R R C

Ya da
ZZ ZZ Z
v(− div w) dx dy = grad v · w dx dy − vw · n ds
R R C

w için grad u sokuyoruz,

ZZ ZZ Z
− div(grad u)v dx dy = grad v · grad u dx dy − (grad u · n)v ds
R R C

En sağdaki terimde eksi işaret var, hocada yok, derste bir yanlış yapılmış olabilir.
Kod
[3]’te alınan Python kodu femcode2.py içinde bulunabilir.
Kaynaklar
[1] 18.085 SUMMER 2012 Site, https://math.mit.edu/classes/18.085/
2012summer.html
[2] Bayramlı, Hesapsal Bilim, Ders 1.22
[3] Bueler, https://github.com/bueler/py_fem_distmesh2d

6
Ayrıksal Fourier Transformu (Discrete Fourier Transform -DFT-)
Frekans Analizi, Periyodik Sinyaller
Bir periyodik sinyali nasıl analiz ederiz? Kendimiz bir sinyal oluşturmak istesek
bunu nasıl yapacağımızı düşünelim; sin ya da cos fonksiyonlarının bir periy-
otu vardır, 0, 2π arasındaki değerler 2π, 4π arasında tekrar eder, vs.. Bazı ek
özellikler; mesela cos sıfır noktasında 1 değerine sahip, fakat elimizdeki zaman
serisi sağa ya da sola “kaymış” olabilir, buna faz kayması (phase shift) deniyor,
yani sıfır noktasında değer 1 olmayabilir. Ayrıca -1,+1 arasında gidip gelmek yer-
ine mesela -10,+10 arasında gidip gelinebilir, buna genlik deniyor (amplitude).
Bir diğer özellik 0, 2π arasında tek bir periyot yerine birden fazla periyot ola-
bilmesi (frekans değişimi).
Frekans ile başlayalım, önce normal bir kosinüs sinyali,

t = np.linspace(0,10,100)
plt.plot(t, np.cos(t))
plt.xlim(0,10)
plt.savefig('compscieng_1_30_04.png')

Her π noktasını gösterelim,

plt.plot(t, np.cos(t))
plt.axvline(0,lw='1',ls='dashed',color='r')
plt.axvline(np.pi,lw='1',ls='dashed',color='r')
plt.axvline(2*np.pi,lw='1',ls='dashed',color='r')
plt.axvline(3*np.pi,lw='1',ls='dashed',color='r')
plt.xlim(0,10)
plt.savefig('compscieng_1_30_05.png')

1
Bu sinyalde cos’a verilen t değerlerini iki ile çarpsam ne olur? 0, 2π arasında bir
periyot için daha önceki t’lerin yarısı ile bu iş yapılabilir, demek ki önceki tek
periyot içinde şimdi sinyal iki kez tur atacaktır. O zaman cos içinde bir sabit ile
çarpım yapmak ile frekansı o kadar arttırmış oldum,

plt.plot(t, np.cos(2*t))
plt.axvline(0,lw='1',ls='dashed',color='r')
plt.axvline(np.pi,lw='1',ls='dashed',color='r')
plt.axvline(2*np.pi,lw='1',ls='dashed',color='r')
plt.axvline(3*np.pi,lw='1',ls='dashed',color='r')
plt.xlim(0,10)
plt.savefig('compscieng_1_30_06.png')

-1/+1 arasında gidip gelmeyi arttırmak en kolayı, cos hesabından elde edilen
değeri mesela 10 ile çarparsam genlik o kadar artar. Faz kaydırma cos içinde bir
toplam olabilir. Tüm resmi göstermek gerekirse, A genlik, f0 frekans, faz kayması
φ olacak şekilde,

x(t) = A cos(2πf0 t − φ)

Bu formülün grafiği,

2
Direk formüle bakarak A hemen anlaşılabiliyor. Frekans t’yi çarpan değerle orantılı,
yanlız dikkat, bu değer her zaman 2π’ye oranlı bir şey, yani formül cos(10t) gibi
bir ifade içeriyorsa, 10/2π ile f0 ’yi çıkartmamız gerekir. Eğer t saniye birimine
sahipse, bir periyot T0 = 1/f0 = 0.5 saniyedir, ve frekans 2 Hertz olacaktır. Eğer
frekans w0 = 2πfo formunda gösterilirse, o zaman birim radyan / saniye olur.
Faz kayması φ sebebiyle tepe noktanın nerede olduğu da direk formülden anlaşılamıyor,
biraz ek hesap lazım, üstteki örnekte 3/16, bunu bulmak için “kosinüse geçilen
değerin sıfır olduğu yer” gerekli,

0 = 2π · 2 · t − 3π/4 =⇒ t = 3π/(4 · 4π) =⇒ t = 3/16

Fakat hala faz kayması 3π/4 diyebiliriz.


Örneklemek (Sampling)
Sayısal, yani bilgisayar ortamında bilgiler ayrıksaldır, kimse bize üstteki sürekli
formül formatıyla sinyal parametrelerini vermez. Diyelim ki bir sinyalin saniyede
10 tane örneklemini alıyoruz. O zaman 3 saniye sonra elimizde 30 veri noktası
olacak. Fakat her örneklem frekansı gerçek sinyali anlamak için yeterli değildir.
Nyquist teorisine göre örneklem gerçek frekansın en az iki katı olmalıdır. Altta
bazı örnekler görülüyor, en alttaki örneklem frekansı dalga frekansı ile aynı, ve
bu sinyali anlamak için yeterli değil. Veri noktalarına bakarak onların ilk üç nok-
tada bir düz çizgi oluşturduğunu zannedebilirdik.

3
Tabii sadece ayrıksal frekansa bakarak sinyalin frekansının ne olduğunu anlamak
ta mümkün degil. Eğer bir şekilde gercek sinyalin kaç örneklemde bir tekrar
ettiğini bulursak, o zaman yaklaşık bir frekans bulabiliriz; mesela bir sinüssel
sinyalin 20 ölçümde bir tekrar ettiğini bulduk, ve örneklem periyotu 0.05 mil-
isaniye / örneklem ise (her iki örneklem arası geçen zaman), o zaman

20 örneklem 0.05 milisaniye


sinüs dalgası periyotu = = 1milisaniye
periyot örneklem

Demek ki periyot 1 / 1 milisaniye = 1 Khz. Ya örneklem periyotu 2 milisaniye ol-


saydı? O zaman sinüs dalga periyotu 40 milisaniye olurdu, ve gerçek frekans 25
Hz olurdu. Söylemek istediğimiz ayrıksal durumda Hz. bazında gerçek frekansın
hesabı her zaman örneklem frekansına fs ’e bağlıdır,

fs = 1/ts

Ayrıksal Fourier Transformu


[4]’te sürekli Fourier Transformunu gördük,
Z∞
X(f) = x(t)ej2πft dt
−∞

ki x(t) zaman bazlı sürekli bir sinyaldir. Bilgisayarlar sayesinde üstteki işlemi
ayrıksal olarak yapabiliyoruz [2, sf. 46],

X
N−1
X(m) = x(n)e−j2πnm/N
n=0

x(n) her n anında, bir n indisiyle erişilen, bir anlamda x(t)’den “örneklenmiş”

sinyal verisi olacaktır, e tabii ki doğal logaritma bazı, j ise hayali sayı j = −1.
Euler ilişkisi e−jφ = cos(φ) − j sin(φ)’den hareketle üstteki ayrıksal denklem
alttakine eşittir,

X
N−1
X(m) = x(n)[cos(2πnm/N) − j sin(2πnm/N)] (1)
n=0

X(m): m’inci DFT bileşeni / katsayısı - X(0), X(1), .. diye gidiyor


m: Frekans yöresindeki (domain) DFT çıktısının katsayı indisi
x(n): Zaman yöresindeki bilginin ayrıksal verisi
n: Zaman verisi indisi
N: Giriş verisinden ve çıktı frekans noktalarından kaç tane olduğu

4
Örnek
Diyelim ki elimizde biri 1 kHz ve diğeri 2 kHz’lük frekanslardan oluşan bir sinyal
var, bu sinyalin sürekli hali şöyle,

x(t) = sin(2π · 1000 · t) + 0.5 sin(2π · t + 3π/4)

Sinyali örnekleme oranımız fs = 8000, her saniye fs kadar örneklem alıyoruz,


her veri nokta arasındaki zaman farkı ts = 1/fs . Elimizdeki bu hızda ardı ardına
alınmış 8 tane veri noktası olsun, yani N = 8. Ayrıksal formül,

x(n) = sin(2π · 1000 · nts ) + 0.5 sin(2π · nts + 3π/4)

Bu noktalarda x(n) değerleri

fs = 8000.; ts = 1/fs
def x(n):
return np.sin(2*np.pi*1000*n*ts) + 0.5*np.sin(2*np.pi*2000*n*ts + 3*np.pi / 4)

for n in range(8): print np.round(x(n),4),

0.3536 0.3536 0.6464 1.0607 0.3536 -1.0607 -1.3536 -0.3536

Şimdi x(n) girdisine DFT uygulayacağız. Eğer 1 kHz’un Fourier katsayılarını


merak ediyorsak, X(1) hesaplarız, yani (1) formülü kullanılacak, ki formül şuna
benzer,

X
7
X(1) = x(n) cos(2πn/8) − jx(n) sin(2πn/8)
n=0

Genel kodla gösterelim,

def X(m):
real = 0.0; imag = 0.0
for n in range(8):
real += x(n)*np.cos(2*np.pi*m*n/8.)
imag -= x(n)*np.sin(2*np.pi*m*n/8.)
return np.round(real,4), imag

print X(1)

(-0.0, -4.0)

2 kHz için ne olur?

print X(2)

(1.4141999999999999, 1.4142135623730947)

5
Bu sonuçlarda 1. kısım sayının reel tarafı, 2. kısmı pür kompleks tarafı. Çoğunlukla
bu elde edilen X(m) sayısının büyüklüğü (magnitude) ile ilgileniriz, bu hesap

q
Xbüyüklük = |X(m)| = Xreel (m)2 + Xkompleks (m)2

olarak yapılıyor. numpy.abs çağrısı bu hesabı hayali sayılar üzerinde otomatik


olarak yapar.

r,i = X(2)
print res, u'büyüklük', np.abs(complex(r,i))

-5.55111512313e-17j büyüklük 1.99999040998

Büyüklüğe bakılırsa 2 Khz frekansının katsayısı ufak değil, demek ki bu frekans


sinyal içinde var / önemli. 3 Khz’e bakalım,

r,i = X(3)
print res, u'büyüklük', np.abs(complex(r,i))

-5.55111512313e-17j büyüklük 5.55111512313e-17

Çok ufak, demek ki bu frekans sinyal içinde mevcut değil.


Örnekte sürekli bir formül kullanarak x(n) hesabı yapılmış olması ayrıksallığın
nerede başlayıp bittiği hakkında kafa karışıklığı yaratmasın; analitik formül iki
yöre arasında gidiş / geliş nasıl oluyor bunu göstermek için verildi. Çoğunlukla
elimizde sadece bir tek boyutlu bir dizi içinde bir veri serisi olur, bu verinin hangi
analitik formülden geldiğini bilmeyiz (Fourier analizini onun için yapıyoruz za-
ten!), veri hakkında eldeki diğer tek bilgi onun örneklem frekansı olur.
Bir örnek üzerinde daha görelim [3, sf. 152], bu sefer kütüphane çağrısı scipy.fft
ile analiz yapalım,

import scipy

N = 64; n = np.arange(N) - 1; T = 0.05;


t = n*T; xbn = np.sin(w1*t)+ 0.5*np.sin(w2*t);
plt.stem(t,xbn)
plt.savefig('compscieng_1_30_08.png')
k = np.arange(N) - 1
Xb = scipy.fft(xbn);
plt.figure()
plt.stem(k,abs(Xb))
plt.savefig('compscieng_1_30_09.png')

6
Üst sağdaki frekans analizine göre k = 2 ve 5’te büyüklük var, bu değerler kω0 =
2πk/NT ile π bazına çevirilebilir, k = 2 için 2πk/3.2 = 1.25π olur, k = 5 için
3.125π elde ederiz.
Ders 15
[Strang hocanın notlarından. Üstteki DFT yöntemi toplamlar, döngüler, belli in-
disler kullanarak yapılıyor. Altta Strang’in anlattığı yaklaşımla, bir sinyalin belli
frekansların katsayılarla ağırlıklanmış toplamı olduğu temel Fourier formülüyle
başlarız, fakat diğer yöne gitmek için pür lineer cebir kullanırız, böylece katsayı
hesabı bir matris tersi alma işlemi haline gelir].
Ayrıksal (discrete) olarak Fourier modellemesi yapmak istiyorsak, elimizde de-
vamlı (continuous) f(x) fonksiyonu olmayacak, bir f(x) fonksiyonun belli nokta-
larındaki değerleri (olduğunu farzettiğimiz) verileri içeren bir vektör olacak. Bu
vektörün N elemanı var diyelim. Fonksiyon periyodik olduğuna göre, x için 2π’i
N eşit parçaya böleriz (tahtadan alınan resim altta). Bunu söylemekle fonksiy-
onun periyotunun N olduğunu farz etmiş oluyoruz, bir anlamda diyoruz ki eğer
elimizde N tane daha nokta olsaydı, onlar elimizde olan değerlerle tıpatıp aynı
olacaktı. Örneğimizde N=4 olsun.

Ayrıca F(x) formülü biraz değişecek. Elimizde sonsuz tane nokta olmadığına
göre

X
N
F(x) = cn einx
n=0

olması lazım. Şimdi, eğer bütün ck değerlerini biliyor olsaydık, bu fonksiyon,


x=0 noktasında hangi değere sahip olurdu?

7
f(0) = c0 + c1 + c2 + c3 + c4 = Y0

Sonraki x değerleri 2π/N, 4π/N, .. için (çünkü her parça 2π/N, bir sonraki parça
2π/N + 2π/N, bir kere topluyoruz, yani parçayı 2 ile çarpıyoruz, sonra 3 ile, vs)
aşağıdaki gibi devam edeceğiz, ama ondan önce bir w değişkeni tanımlayalım,
bu değişkeni w = e2πi/N olarak alalım. Böylece w2 dediğimizde üstel işlemlerde
çarpım işlemi toplama işlemine dönüşeceği için e4iπ/N değeri elde edilebilir, w3
ile e6iπ/N elde edilir, vs. Bu değerler bize lazım olacak değerler, w sayesinde
formüller daha temiz olacak. F(2π/N) içindeki 3. terim (n = 2) nedir? cn einx =
c2 e2i2π/N = c2 e4iπ/N = c2 w2 . O zaman

f(2π/N) = co + wc1 + w2 c2 + w3 c3 = Y1

Devam edelim:

f(4π/N) = co + w2 c1 + w4 c2 + w6 c3 = Y2

f(6π/N) = co + w3 c1 + w6 c2 + w9 c3 = Y3

Elimizdeki dört toplam işlemine bakınca, bu toplamlar ve çarpımların aslında


lineer cebir üzerinden matrisler ile gösterilebildiğini farkedebiliriz.

    
Y0 1 1 1 1 c0
 Y1   1 w w2 w3   c1 
 Y2  =  1 w2 w4 w6   c2
    

Y3 1 w3 w6 w9 c3

Her matris için bir değişken kullanırsak

Y = WC

F(x)’ten (yani Y’den) C’ye gitmek istersek, elimizde Yn değerleri var, w değerleri
zaten sabittir, W bu sabit değere göre oluşturulur, o zaman, cn sayılarını nasıl
buluruz?

Y = WC

W −1 Y = W −1 WC

W −1 Y = C

8
Yani W matrisinin tersini (inverse) alıp, onu Y ile çarpınca elimize C değerleri
geçecek [1, sf. 340-370].
Güneş Benekleri
Güneşte periyodik olarak olan benekler, aşağı yukarı 11 senede bir ortaya çıkarlar.
Bu benekler uzun süredir gözlenmekte ve ölçülmektedir, şiddetlerine göre, sunspots.dat
adlı dosyada bulabiliriz.

tempdata = np.loadtxt('sunspots.dat')
year=tempdata[:,0]; sunspots=tempdata[:,1]
year=year[year<2001]; sunspots=sunspots[year<2001]
plt.plot(year,sunspots)
plt.title(u'Güneş Benekleri')
plt.savefig('compscieng_1_30_03.png')

Benek verisindeki periyodik oluşu Fourier transformu ile analiz edelim. Alttaki
kod w, W’yi kullanarak üstteki çarpımlarla C vektörünü bulacak. Bu vektör
içindeki sayılar Fourier analizindeki belli frekanslara, harmoniklere tekabül ediyor
olacaklar. Bu C değerlerinde bazıları diğerlerinden daha güçlü bir etkidir, mesela
11 senelik periyot C içinde daha belirgin olarak çıkmalı.

import scipy

tempdata = np.loadtxt("sunspots.dat")

year=tempdata[:,0]

Y=tempdata[:,1]

N = len(Y)

w = np.exp((2*np.pi*1j)/N)

W = np.zeros((N,N), complex)
for i in range(N):
for k in range(N):

9
W[i,k] = w**(i*k)

C = np.dot(np.linalg.inv(W), Y)

Periyotların grafiği,

n=len(Y); print 'n=',n


power = np.abs(C[0:int(n/2)])**2
nyquist = 1./2
freq = np.array(map(float, np.array(arange(0,int(n/2))))) / (n/2)*nyquist
print 'len(freq)=',len(freq)
period=1./freq;
plt.plot(period,power)
plt.xlim(0,30)
plt.savefig('compscieng_1_30_02.png')

n= 305
len(freq)= 152

11 sene civarında belirgin bir frekans olduğunu görebiliyoruz.


FFT
Bitirmeden önce FFT konusundan bahsedelim. DFT algoritması kodda görüldüğü
gibi bir W matrisi ortaya çıkarır ve önce tersini alma, sonra bu ters ile bir çarpım
işlemi yaparak C sonucunu üretir. O notasyonunu kullanırsak DFT’nin karmaşıklığı
O(N2 )’dir. Bu iyi bir hızdır.
FFT algoritması üstteki çarpımın bazı özelliklerini kullanarak DFT’yi daha da
hızlandırır ve O( 21 Nlog2 N) hızına getirir. FFT’den bu makalede bahsetmeyeceğiz,
aklımızda olsun, scipy.fft çağrısı bu algoritmayı kullanır, örnek:

C = scipy.fft(Y)
print C[:3]

[ 15318.00000000 +0.j 1153.09522938 +866.74784921j


-72.35158374+1347.22954505j]

Soru

10
FFT yaklaşıksal bir algoritma mıdır? Yani DFT’nin elde değerlere “yakın” değerler
daha hızlı mı hesaplanıyor?
Cevap
FFT ile DFT tıpatıp aynı katsayıları hesaplıyorlar, FFT sadece bu hesabı daha hızlı
yapıyor.
Lomb-Scargle
Daha önceki bir yazida güneş beneklerinin ortaya çıkışı verisinde periyotlar bul-
mak için Fourier analizi kullanmıştık. Bu analizin eksik bir tarafı istatistiki önemlilik
(significance) hesabını göstermemesi. Daha iyi bir yöntem Lomb-Scargle yöntemi,
ki bu yönteme göre periyot bulmak pek çok sinüs eğrisinin hangilerinin veriye
daha iyi uyduğunu bulma problemine çeviriliyor, problem bir tür en az kareler
çözümü haline geliyor, arka planda FFT kullanılıyor fakat problemin ana modeli
artık FFT değil. Güneş benekleri,

tempdata = np.loadtxt('sunspots.dat')
year=tempdata[:,0]; sunspots=tempdata[:,1]
year=year[year<2001]; sunspots=sunspots[year<2001]
plt.plot(year,sunspots)
plt.title(u'Güneş Benekleri')
plt.savefig('tser_ar_06.png')

from astroML.time_series import lomb_scargle


omega = np.linspace(1, 40, 200)

dy = 0.5 + 0.5 * np.random.random(len(sunspots))


sig = np.array([0.1, 0.01, 0.001])
PS, z = lomb_scargle(year, sunspots, dy, omega, generalized=True, significance=sig)

plt.plot(omega,PS)

11
plt.hold(True)

xlim = (omega[0], omega[-1])


for zi, pi in zip(z, sig):
plt.plot(xlim, (zi, zi), ':k', lw=1)
plt.text(xlim[-1] - 0.001, zi - 0.02, "$%.1g$" % pi, ha='right', va='top')
plt.hold(True)
plt.title(u'Güneş Benekleri Periyotları')
plt.savefig('tser_ar_07.png')

Grafikte 0.1, 0.01, 0.001 önemliliğini yatay çizgiler olarak görüyoruz; bu çizgilerin
üzerindeki her tepe noktası önemli bir periyottur.
Bir diğer örnek: Altta dünyada 500 kusur milyon yıl geriye giden canlı tükenme
yüzde grafiği görülüyor [7]. Mesela yaklaşık 66 milyon sene önce bir göktaşı
çarpmasıyla müthiş bir tükeniş yaşandı, zaten dinazorların yokolması bu olay ile
oldu. Bu olay grafikte açık bir şekilde görülüyor.

import pandas as pd
ext = pd.DataFrame(pd.read_csv('extinct.csv',header=None))
ext2 = ext.set_index(np.linspace(542,1,len(ext)))
ext2[0].plot()
ext = ext[0]
plt.savefig('tser_ar_09.png')

12
Soru şu: acaba bu verideki periyotlar hangileri? Tükenişte belli periyotlar var
mı?

from astroML.time_series import lomb_scargle

dy = 0.5 + 0.5 * np.random.random(len(ext))


omega = np.linspace(10, 100, 1000)
sig = np.array([0.1, 0.01, 0.001])
PS, z = lomb_scargle(ext.index, ext, dy, omega, generalized=True, significance=sig)

plt.plot(omega,PS)
plt.hold(True)

xlim = (omega[0], omega[-1])


for zi, pi in zip(z, sig):
plt.plot(xlim, (zi, zi), ':k', lw=1)
plt.text(xlim[-1] - 0.001, zi - 0.02, "$%.1g$" % pi, ha='right', va='top')
plt.hold(True)
plt.title(u'Canlıların Tükenme Periyotları')
plt.savefig('tser_ar_08.png')

13
Grafiğe göre yaklaşık 25 milyon, 70 milyon yılda bir rutin tükenişler görülüyor.
Kaynaklar
[1] Strang, Computational Science and Engineering
[2] Lyons, Understanding Digital Signal Processing, 2nd Edition
[3] Wang, Applied Numerical Methods Using Matlab
[4] Bayramli, Diferansiyel Denklemler, Ders 15
[7] Bayramlı, Grafikten Veri Çıkartmak, https://burakbayramli.github.io/
dersblog/sk/2017/01/grafikten-veri-cikartmak.html

14
Evrişim (Convolution)
Evrişim iki fonksiyon f, g üzerinde tanımlı bir operasyondur, bu operasyon iki
fonksiyondan üçüncü bir fonksiyon yaratır. Operasyon bir entegral üzerinden
tanımlıdır, g’nin aynı görüntüsü / ters çevrilmiş halinin alınıp, soldan (negatif
sonsuzluk) sağa doğru kaydırılırken f ile üst üste gelen bölgenin alanını her
t için alınması durumudur, bu açıdan evrişim bir tür ağırlıklı ortalama olarak
görülebilir, f’in ağırlıklı ortalaması g üzerinden alınmaktadır. Matematiksel olarak,
Z∞
f∗g≡ f(τ)g(t − τ) dτ
−∞

Evrişim sırabağımsızdır, yani f ∗ g = g ∗ f, o zaman


Z∞
f∗g≡ f(t − τ)g(τ) dτ
−∞

ifadesi de doğrudur. Örnek f, g üzerine görelim,

Her iki fonksiyonu bir geçici değişken τ üzerinden tanımlayabiliriz, Sonra g’nin
ayna görüntüsünü alırız, g(τ) → g(−τ)

Şimdi bir zaman kaydırma faktörü t ekleyebiliriz, bir g(t − τ) elde ederiz, bunun
etkisi her t için g’yi istediğimiz noktaya kaydırabilmektir. Bunu yaparken, mesela
negatif sonsuzluktan pozitif sonsuzluğa kaydırırken, her t anında alınan ente-
gralin sonuçları bize evrişimi verir. Dikkat, kaydırma entegralin sonucu değil,
sadece “her t için” vurgusu amacıyla bu kaydırma görüntüsü veriliyor, her t nok-
tasında, kaydırma nereye olursa olsun, −∞, ∞ arasında entegral alınmaktadır.

1
Ayrıksal olarak,

X

(f ∗ g)[n] ≡ f[m]g[n − m]
m=−∞

Farklı fonksiyonlar üzerinde görelim, mesela kare fonksiyonunu kendisiyle evrişimi,


f mavi, g kırmızı, sarı bölgeler çakışma olan yerler, g’nin her t için evrişim ente-
gral sonucu ise siyah çizgi ile gösteriliyor,

Şimdi f kavisli bir fonksiyon, g hala kare,

2
Evrişim ile çapraz korelasyon (cross-correlation) arasında bağlantılar var, t − τ
yerine t + τ kullanılırsa çapraz korelasyon elde ediliyor.

Örnek

import scipy.signal
f = [1,2,3,4,5,6]
g = [5,4,3,2,1]
print scipy.signal.convolve(a,b)
[ 5 14 26 40 55 70 50 32 17 6]

X + Y Dağılımı
Çoğu zaman X, Y’in bağımsız olduğu durumda bu rasgele değişkenlerin toplamının
dağılımını hesaplamak gerekir [2, sf 56]. Kümülatif fonksiyon F ile

FZ+Y = P(X + Y 6 a)

ZZ
= f(x)g(y) dx dy
x+y6a

f(x)g(y) kullanabildik çünkü X, Y bağımsız. Alt sınırda bir değişiklik yapalım,


x + y 6 a, o zaman x 6 a − y. Demek ki

3
Z ∞ Z a−y
= f(x)g(y) dx dy
−∞ −∞

Entegralleri gruplayabiliriz,

Z ∞  Z a−y 
= f(x) dx g(y) dy
−∞ −∞

Z∞
= FX (a − y)g(y) dy
−∞

Yoğunluğu almak için kümülatif fonksiyonun türevini alırsak,


Z∞
d
fX+Y (a) = FX (a − y)g(y) dy
da −∞

Z∞
d
= FX (a − y)g(y) dy
−∞ da
Z∞
= fX (a − y)g(y) dy
−∞

Üstteki ifade bir evrişim operasyonu! Yani iki bağımsız rasgele değişkenin toplamının
yoğunluğu, değişkenlerin yoğunluklarının evrişimine eşittir!
[1, sf. 365]’de ayrıksal olarak üstteki hesaba değiniliyor, elde iki zar var, zarın
her yüzünün gelme ihtimali pi = 1/6, bu iki zarın mümkün her türlü toplamının
hesabı bir evrişim, p ∗ p,

import scipy.signal
d = 1/6. * np.array([1.0,1.0,1.0,1.0,1.0,1.0])
print scipy.signal.convolve(d,d)
print scipy.signal.convolve(d,d) * 36.

[ 0.02777778 0.05555556 0.08333333 0.11111111 0.13888889 0.16666667


0.13888889 0.11111111 0.08333333 0.05555556 0.02777778]
[ 1. 2. 3. 4. 5. 6. 5. 4. 3. 2. 1.]

Sonuca göre toplam 12 gelme ihtimali 1/36 (en baştaki), 11 gelme ihtimali 2/36,
vs.
Ek bilgiler için bkz [4] notları.
Kaynaklar
[1] Strang, Computational Science and Engineering
[2] Wikipedia, Convolution, https://en.wikipedia.org/wiki/Convolution

4
[3] Ross, Introduction to Probability Models 10th Edition
[4] Bayramli, Diferansiyel Denklemler, Ders 21

5
Ders 2.3
Her hesapsal yöntemin doğruluğu ve stabilitesini bilmek isteriz. En basit başlangıç
değer problemi (initial value problem -IVP-) ile başlayalım,

∂u ∂u
=c (1)
∂t ∂x

Buna tek yön dalga denklemi diyebiliriz, iki yönlü dalga denklemi için üstteki
formülde ikinci türevlerin olması gerekirdi, o tür denklemde dalgalar iki yöne
de giderdi. Üstteki tek yöne dalga gönderiyor, basit, temiz bir denklem, birinci
derece, hız bağlamında sabit katsayılı. Başlangıç değer problemi için başlangıç
değeri u(x, 0) ile verilmiş olsun, ve benim ilgilendiğim u(x, t) çözümü.
Bu çözümü bulmak zor olmaz, mesela ilk aklıma gelen pür üsteller, eikx . Bu
çözümün bir özelliği sabit katsayısı var, sınırı yok, o zaman çözüm eikx ’in bir
katı olacak, bu demektir ki değişken ayırma tekniğini uygulayabilirim, ve u =
G(x, t)eikx şeklinde bir çözüm bekleyebilirim. Nasıl değişkenler ayrıldı görüyoruz,
G içinde x, t’den ayrıldı, ve frekans k büyüme faktörü G’yi tanımlıyor.
Çözümü bulmak için içinde G’yi içeren u formülünü ana türevsel denklem (1)’e
sokarım, ve t’li çözümü elde ederim, çünkü eikx iptal olacak. Formüle sokayım,

dG ikx
e = ikcGeikx
dt

Ustelli kismi iptal ederim, o terimler hic sifir olmazlar nasilsa,

dG ikx
e


eikx
= ikcG 

dt

Böylece G için basit bir denkleme erişiyorum,

dG
= ikcG
dt

Sonuç sabit bir katsayıya dayaniyor, ick katsayısına. Nihai denklemin bir basit
diferansiyel denklem olduğunu da farkediyoruz, o zaman çözüm yine bir üstel,
G = eikct . Bu G’yi u çözümü içine koyunca,

u = G(x, t)eikx

u = eikct eikx = eik(x+ct)

Çözüm bu işte. Değişkenleri ayırdık, büyüme faktörüne baktık, bir üsteli denedik,
farklılık (difference) metotları için de aynısını yapacağız. Von Neumann’ın dahice

1
fikri buydu, üstelleri takip et. Her frekansa bak, ve eikx ’in katlarına neler olduğuna
bak.
İlginç bir şey, tüm frekanslar x + ct kombinasyonunu ortaya çıkarıyor. Fourier’in
de söylediği bu değil miydi? eikx kombinasyonlarını alın, onların çözümü eik(x+ct) ’lerin
kombinasyonu olacak. Yani x’ler x + ct oluyor bir bakıma. O zaman çözüm

u(x, t) = u(x + ct, 0)

Bu her u için.
Bu çözümün ne olduğunu sezgisel olarak rahatça anlayabiliriz tabii, bu tek yöne
giden bir dalga. Cebirde açıkca görülüyor. x, t düzleminde bir resim çizince daha
da iyi görülebilir. Bu resmi anlamak önemli çünkü farklılık yöntemi ile üstteki
denklemi çözmeye uğraşıyoruz.

Şimdi u’nun (0, 0) noktasındaki değerini düşünelim. Zaman geçtikten sonra x+ct
çizgisindeki herhangi bir yerde, P’de olduğumuzu düşünelim, orada çözüm hep
aynı. Başlangıçtaki değer ne ise o çizgi (üstteki grafikte solda görülen) üzerinde
seyahat ediyor, u değeri (0, 0)’da ne P’de de o.
Üstte sağdaki çizgi aynı şekilde, orada da X ile işaretli bir sabit değerde başlayan
değer çizgi üzerinde yukarı taşınacak, Q’da aynı u değeri olacak. [Dikkat, x eks-
enindeki X değeri x + ct = X çizgisiyle temsil edilir denmiyor, x eksenindeki bir
değer ile .. = X şeklindeki bir çizginin cebirsel bağlantısı yok, ax + by + c = 0
denklemindeki sabitler grafiksel kesim noktalarına tekabül etmezler].
Bu çizgilere karakteristik çizgiler (characteristic lines) ismi veriliyor.
Gördüklerimiz dalga denklemlerine has bir özellik, işi denklemlerinde mesela
aynı durum görülmüyor. Tek boyuttayız tabii bunu unutmayalım, oldukca basitleşitirilmiş
bir ortam bu. Üç boyutta karakteristik köni var. Üç boyutta düşünürsek, mesela
bir ses çıkartıyorum, bir kelime telafuz ediyorum, benim sesim bir ses dalgası bir
üç boyuttaki dalga denklemini çözer, ya da parmağımı sıklatsam mesela o ses
başlangıç noktasından etrafa yayılır, bu yayılma karakteristikler üzerinden olur.
Yayılma pek çok yöne doğru muhakkak, tek boyuttaki gibi tek çizgi değil, yüksek
boyutlarda resim biraz daha çetrefil hale geliyor, fakat ana fikri tek boyutta çok
iyi görebiliyoruz.
Çözümün kendisinin, yani u’nun grafiğini de göstermek faydalı olabilir. Diyelim

2
ki başlangıçta duvar gibi duran, bir su kütlesi var, kabaca onu bir adım (step)
fonksiyonu ile gösterebiliriz, x = 0 solunda 1 değerinde sağında 0 değerinde. Bu
IVP’ler için tipik bir başlangıç stili sayılabilir.

Bu grafikte çözümü nasıl gösterirdik? Yani u(x, t) çözümü, grafiği nedir? Grafik
üstteki şeklin sola doğru hareket etmesiir. Dalga sola doğru c hızıyla gidiyor yani
(c pozitif ise). Dalga denkleminin her çözümü bu şekilde davranır, bu örnekte bir
su duvarı düşündük, ve o duvar sola doğru hareket etti. Önemli nokta şu kütlesi
bu hareket sırasında şekil değiştirmeyecektir, saçılma (dışpersion) kelimesini kul-
lanmak belki de doğru, o yoktür yani. Hareket esnasında her frekans (eğer o su
duvarını, dalgayı, bir kaç pür üstelin toplamı olarak düşünürsem, ki bu tür bir
Fourier’den biliyoruz ki mümkündür) aynı hızda hareket ediyor, bu sebeple tüm
dalga da o hızda hareket etmiş oluyor.
[gerisi atlandı]

3
Ders 2.8
[Lineer problemler atlandı]
Şimdi gayrı lineer problemlere gelelim. Alttaki model denkleme bakalım,

ut + uux = 0 (1)

Bu denklem ile daha önce gördüğümüz alttaki denklem arasındaki fark bariz,

ut = cux

Üstteki yatay iletim (advection) denkleminde sabit bir hız var, c. Ama iki üstteki
durumda hız −u, ya da c’nin yerine −u koymuş oluyoruz. O gayrı lineer den-
klemi analiz etmek istiyoruz, daha önce olduğu gibi analitik olarak çözmek is-
teriz, eğer mümkünse bir formüle erişmek isteriz.. Karakteristik çizgiler bağlamında
neler olduğuna bakmak isteriz.. Sonuçta tek bir uzay değişkeni ve tek bir den-
klem var, buradan karakteristiklere bakarak işin özünü görmek mümkün olmalı.
Ana denkleme eşdeğer olan bir form görelim,

u2
 
∂u ∂
+ =0 (2)
∂t ∂x 2
| {z }
f(u)

Hatta üstteki forma daha “doğru” form ismi verilebilir, eğer onu açsak (1)’e erişirdik
fakat üstteki denklemdeki parantez içindeki kısmın fiziksel bir anlamı var, o kısma
akış (flux) ismi veriliyor.
Fakat göreceğiz ki bu diferansiyel denklem aynı noktada iki tane çözüm ortaya
çıkartabiliyor, ve onlardan birini seçmemiz gerekiyor. Diğer bir deyişle çözüm
süreksiz (discontinuous) hale gelebiliyor. Mükemmel pürüzsüz bir başlangıç
fonksiyonu bir süre sonra süreksiz oluyor. Sürekli başlıyoruz, çözüm karakter-
istik çizgiler üzerinde sabit, fakat iki karakteristik çizgi birbiriyle çakıştığında ne
olur? Daha önce çakışma olmadı çünkü ana denklem o türde değildi. Burada
mümkün!
O durumu alta çizdim,

1
Bakıyoruz sol taraftaki o kısımda başlangıç değerleri 1, onlar sabit c durumunda
olduğu gibi problemsiz sağ yukarı doğru gidiyorlar. Ama sağ kısma bakarsak,
u0 = 0 durumu için, bu karakteristik çizgilerle bağlantılı hız sıfır, orada dalga
hareket etmiyor yani, karakteristik orada direk yukarı çıkıyor, çünkü hiçbir şey
olmuyor, u değeri olduğu haliyle yukarı taşınıyor, sağa, sola gidiş yok. Ama o
orta kısımda bir şeyler oluyor, karalanmış kısımdan bahsediyorum. Burada neler
olduğunu iyi anlamamız gerekiyor.
Cebire girmeden belki grafikleyerek bir şeyler anlayabilirim, orta bölgedeki karak-
teristik çizgilerin eğimi sıfır ile bir arasında, yani, şimdi u0 (x)’i t = 0 için grafik-
lersem,

Sol kısımda sabit 1’de gidiyorum, sağ kısımda sabit 0’da gidiyorum. Arada li-
neer bir düşüş var. Üstteki grafikte değer 1, 1 − x, 0 değerlerinde.. Bu değerler iki
üstteki grafikte yatay eksenın bölümlerine tekabül ediyor. İki üstte x, t uzayındayız
dikkat, bir üstte ise x, u uzayında.
Yani t = 1 noktasına kadar karakteristikler tüm hikayeyi anlatıyorlar. u’nun
nerede sıfır olduğunu, nerede 1 olduğunu biliyorum. t = 1 noktasına kadar
diferansiyel denklem için durum iyi. Mesela t = 1/2’de durum nedir?

Bu durumda dalga biraz daha ilerlemiş durumdadır, iniş daha dik hale gelmiştir.
t = 1’de tabii ki grafik tam dik hale gelmiş olacaktır.
Fakat t = 1 sonrası için düşünürsek şimdi, aynı noktadan birden fazla karakter-
istik geçiyor olacak. Orada 0’dan mı yoksa 1’den gelen değerleri mi baz almak
lazım? O çakışma bölgesinde neler oluyor? İşler karıştı çünkü benim karakter-
istik takip etme kuralım bana iki tane sonuç verdi. Bize bir cevap lazım, daha
önemlisi, fiziksel olarak anlamlı bir cevap lazım.
Ortada bir şok dalgası, sok çizgisi var, fakat onun hakkında karakteristiklerden
iyi bilgi gelmiyor. Merak ettiğimiz şok cizgisi neye benzer, gidiş yolu nedir, eğimi
nedir? Onu ne kontrol eder? Ne yazık ki diferansiyel denklem bize burada dert
oluyor. Olanları anlamak için denklemin entegral formuna gitmek daha doğru
olabilir.

2
Z xR
d
u dx + [f(uright ) − f(uleft )] = 0 (3)
dt xL

Tabii entegral alınca her şeyi daha pürüzsüz hale getirmiş oluyorum, ama aynı
anda muhafaza fiziksel kanununa sadık kalmış oluyorum. Formülün nereden
geldiğini görmek zor değil, (2)’nin x üzerinden entegral alınmış hali aslında, sol
terimdeki zamansal türev hala orada, ama ikinci terimdeki yer türevi yok olacak,
ve entegral sınırları olarak bir noktadan diğerine diyelim şimdilik, bunlar xleft ,
ve xright , akış fonksiyonu için uleft ve uright .
Bu entegral muhafaza kanunu ne diyor? Entegral derken (2)’deki entegral ter-
imden bahsediyorum, o entegralin muhafazasından bahsediyoruz, diyor ki o en-
tegralde değişim var ise, o değişim sağdan dışarı çıkan ya da soldan içeri giren
akışla mümkün olabilir / onların toplamıdır. Tüm bunlar sıfıra eşit olduğu için
bir muhafaza beyanı oluyor bunlar.
(1) formülüne bu arada Burgers’in denklemi (Burgers’ equation) ismi veriliyor.
Fakat aslında tüm ismi ağdasız (inviscid) Burgers’in denklemi, çünkü denklem
sıfıra eşit. Bu formül ve tarihi hakkında birkaç kelime edelim, Cole adli bilimci
eşitliğin sağında bir uxx kullanmıştı ilk önce, taşınım uu+x üzerinden, hala gayrı
lineerdi. Bunlar Navier-Stokes denkleminde gördüğümüz türden şeyler değil
mi? NS’te de daha genel durumda tabii, ama orada da bir gayrı lineerlik var.
Burger’in formülünde bu daha basitleştirilmiş bir durumda tabii.
Neyse, bu basit formda gayrı lineer olsa da Cole (1)’i çözmeyi başardı. Bir değişken
değişim tekniği kullandı, aynı zamanda Hopf ta bu yaklaşımı keşfetmişti. Bu
değişken değişimi ile formül lineer hale geldi, ve çözüm böylece yapıldı. Ardından
bilimciler yayınım katsayısının sıfıra gitmesine izin verdiler, böylece limite giderken
ağdasız Burgers’ın denklemi elde edildi. Böylece çözüme bakılıp onun limit sıfıra
giderken nereye gittiği incelenebiliyordu, vs.
Doğru çözümü bulmanın bir diğer yolu buydu işte, ağdalık yöntemi denen şey
budur. Sok dalgaları birbirine girdiğinde, neyi seçeceğimizi bilmediğimiz du-
rumlardan kullanılan çok önemli temel bir metottur. Yani çok boyutta bile, gayrı
lineer ortamda kullanılabilecek iyi bir yöntem bu, azıcık ağdalık köy formüle
sonra limitte sıfıra gitmesine izin ver.
Çünkü

ut = cux + duxx

formunda düşünürsek, ikinci türev olduğu için duxx terimi, cux teriminden daha
baskın hale geliyor, çünkü ikinci türevli terim çözümü daha pürüzleştirir, ama
cux bildiğimiz gibi pürüzsüzlük getirmez, sadece taşınım yapar, çözümü bir yer-
den diğerine taşır. Neyse baskın tarafı sıfıra yaklaştırınca çözümü bulabilmiş
oluyoruz. Bu bir yöntem. Aslında sayisal hesapta sonlu farklılıklarla bu tekniği
bir anlamda kullanıyoruz, uzay değişkeni için bir ikinci farklılık ekleyip ∆t’yi
ufaltınca çözüme ulaşılabiliyor.

3
Herkesin sevdiği bir diğer örnek problem Trafik Akış problemi. Tek boyutta yine,
bu formülle trafik akışı modellenebiliyor. Modellenen ne olacak? Yoğunluk ola-
bilir, herhangi bir noktadaki yoğunluğu temsil edeceğiz, değişken u yerine ρ kul-
lanalım, çoğunlukla yoğunluk için bu kullanılır.
Tüm trafiğin akışı hızı v olsun, yoğunluk ile hız arasında bir ilişki olmalı muhakkak,
v(ρ) bize hızı versin o zaman. Aradaki ilişki ters yönde olacak herhalde, yoğunluk
artınca hız azalır, azalınca artar.

Trafik akış probleminde akış fonksiyonu nedir (ikisinde de ’akış’ kelimesi var,
ilginç oldu). Muhafaza kanunu arabaların muhafazası olacak, yolun bir parçasına
bakarsak, muhafaza kanunu diyecek ki oradaki araba sayısının değişimi, ki (3)’teki
ilk terim, o kısımdan çıkan ve oraya giren arabaların toplamına eşittir. O zaman
akış fonksiyonu f(ρ) = v(ρ)ρ olacak, hız çarpı yoğunluk bana arabaların nasıl
aktığını söyler.
Bu problemde daha önce gördüğümüz karakteristik çakışma problemini aynen
göreceğiz. Bu problemde de şoklar (shock) olacak, ve yayılma dalgaları da (fan)
olacak. Şoklar karakteristikler, arabalar biraraya geldiğinde, yayılma dalgaları
karakteristikler yayıldığında olur.
Aslında yayılmayı hemen gösterebilirim, iki tane başlangıç değeri olabilir mesela,
u0 = 0 ve u0 = 1. Bu tür problemlere Riemann problemi deniyor bu arada, ve
muhafaza kanunu teorisinin en temiz çözüm yöntemi denebilir, elde iki başlangıç
0 ve 1 olduğu durum. 1 ve 0 da olabilir, ama dikkat o zaman durum farklı.

Orta kısımda bir yayılma dalgası ortaya çıkıyor, ve profil 0’dan 1’e ortada pürüzsüz
bir şekilde çıkıyor.
Bir sonraki derste eğer varsa şok cizgisini bulacağım, ve şok mu yayılma mı
olduğunu ayırtetmeyi göstereceğim. Şok hızı s’yi bulmayı öğreneceğiz, ve şok
ile yayılma arasındaki seçim entropi hesabı üzerinden olacak.
[devam edecek]

4
Ders 2.9
Formüllerimizin tekrar üzerinden geçelim,

∂u ∂
+ f(u) = 0 (1)
∂t ∂x
Z xR
d
u dx + f(uR ) − f(uL ) = 0 (2)
dt xL

u(x, t) = u(x − f 0 (u)t, 0) (3)

İki formül tek sayısal, tek boyutta muhafaza kanununu gösteriyor. Yer tek boyutlu,
sadece x var. Akış fonksiyonu f(u). (1)’de diferansiyel form var ve gördük ki bu
form bir süreksiz (discontinuous) çözüm, süreksizlik ortaya çıkarıyor. Bu sebeple
denklemin entegre edilmiş formu (2) ile iş yapmaya karar verdik. Mesela u’da
yoğunluk olsaydı entegrasyon bize iki nokta arasındaki kütleyi verirdi (çünkü
kütle, yoğunluğun bir hacim üzerinden toplanmış halidir), o zaman (2)’deki en-
tegralin türevi kütlenin zamana göre değişimi olurdu, ve diğer iki terimi de göz
önüne alırsak, bu değişim sadece dışarı çıkan, eksi giren akışa eşit olurdu. Muhafaza
kanunu budur.
Diferansiyel denklemin çözümü (3) ile karakteristik çizgiler ortaya çıktı, onları
başlangıç zamanı t = 0’dan takip edebiliyorduk. Başlangıçtaki değerler çizgi
boyunca taşınıyordu, problem karakteristikler çakıştığında ya da aynı başlangıçtan
farklı yönlere yayıldığında / dağıldığında (fan out) ortaya çıkıyordu. Bu iki farklı
durumu altta görüyoruz.

İki farklı problem üsttekiler ve ikisinin de farklı tedavisi var. Soldaki trafik örneğinde
kırmızı ışık yandığındaki durum, ışığa gelen arabalar orada tıkanıyor, ışığın öteki
tarafında yoğunluk az, ama gerisinde durum farklı, ve arabalar hızlı bir şekilde
durmalılar. O soru işareti olan yeri düşünelim, aynı noktaya farklı yönlerden ge-
len iki değer nereye gider? Bu durumu halledecek bir kural lazım. Aynı şekilde
üst sağdaki durum için bir kural lazım. Orada soru işareti boşlukta, ama orası bir
değeri temsil ediyor, oraya nasıl gelinir, hiç bir karakteristik oraya gitmiyorsa?

1
Birinci duruma bakalım önce, o çakışan bölümü silelim, orada olan şudur, bir şok
oluşur (yeşil çizgi), ve o bölgedeki karakteristikler o çizgiye “akar”, enformasy-
onu ona aktarırlar. Bu önemli bir şey..

Peki şokun kendisinin özellikleri nedir? Ne hızda ilerler? Şok hızı nedir? Bu
şoku x, t düzleminde tanımlamak için (2)’deki entegral formu kullanmam lazım.
Entegral formu kullandım çünkü ortada bir süreksizlik var, o durumlarda difer-
ansiyel formlar anlamsız hale geliyor.
Aradığım şey şok anındaki zıplama koşulu (jump condition), ki bu koşul şokun
yerini bulmama yardım edecek. Bulmam gereken anahtar büyüklük şok hızı, s(t)
diyelim, onun sayesinde şokun nereye gittiğini hesaplayabilirim, zamana göre
nasıl yukarı gittiğini anlayabilirim.
Zıplama koşulunu şöyle gösteriyorum,

s[u] = [f(u)]

Bu ne demek? Köşeli parantez notasyonu kullandım, köşeli parantez zıplama


demek, onun da formülsel olarak nereden geldiğini sonra anlatacağım. Üstteki
denklem diyor ki, şok hızı s çarpı u’daki zıplama, f(u) içindeki zıplamaya eşittir.
Burgers’ın denklemini düşünürsek akış f(u) = u2 /2 idi, iyi huylu parabol bir
şekil, neyse, o zaman

s = [f(u)]/[u] = (u2R − u2L )/2(uR − uL ) = (uR + uL )/2

Üsttekileri açıklamak gerekirse, zıplama dediğimiz sağ değer eksi sol değer de-
mek, bu sebeple, mesela f(u)’daki zıplama, yani [f(u)] deyince, ve f(u) = u2 /2
olduğu için u2R /2 eksi u2L /2 diyoruz, biraraya koyunca (u2R − u2L )/2 oluyor. u
zıplaması [u] aynı şekilde uR − uL .
Elde ettiğim (uR +uL )/2 sonucu bana diyor ki şok hızı uR , uL ’in ortalaması, Burg-
ers’ın denkleminde bu sağdan gelen karakteristik hızı ile soldan gelen karakter-
istik hızının ortalaması demek.

2
Bu üstteki grafik, kabaca çizilmiş olsa da, doğru demek, yeşil çizgi tam yukarı
çıkıyor düşünsek bu her iki yandan karakteristiklerin ortasının gittiği yer olurdu.
Her iki tarafın ortası, bu çok önemli, bu demektir ki her yandan karakteristikler
şok çizgisine giriyorlar. Bu gayrı lineer ortamda şok cizgi bir anlamda iki yandan
enerjiyi emip azalıyor, entropiyi azaltıyor, birazdan göreceğimiz üzere toplam
varyasyonu azaltıyor.
Peki ziplama notasyonunun formulsel temeli nedir? Temeli (2)’deki entegral for-
mdur. Diyelim ki, (2)’ye bakarak soyluyorum, sokun biraz soluyla biraz sagi
arasindaki bolgede entegral aliyorum. Bu normal, sokun icerigini yakalamak /
kaydetmek icin o sekilde entegral siniri tanimlamam normal.
9:00 devam et
[devam edecek]

3
Ders 2.11
Konumuz kesit seviyeleri (level sets). Bu alanda Sethian ve Osher otorite sayılıyor,
80’li yıllarda yayınladıkları makale ve kitaplarda konuyu etraflıca işlediler.
Elimizde bir eğri var diyelim (altta resimde t = 0 anındaki)

ve bu “arayüz (interface)” ya da duvar, bu eğri hareket ediyor. İlerliyor. Bu il-


erlemenin kendi normali (yani eğrinin her noktasındaki teğetine dik) yönünde
olduğunu düşünelim. Bu ilerleme şeklini biz empoze ediyoruz, sonra formüllerin
buna göre nasıl şekillendiğini göreceğiz. Bu ilerleme sonunda mesela t = 0’da
görülen şekilden t = 1’deki şekle gelinmiş olacak. En ideal şartlarda hızın hiçbir
noktada değişmediğini düşünebiliriz, yani hız sabit. O zaman birim zamanda
sabit hızda (diyelim o da 1), mesafe 1 katedilmiş olur.
Eğrinin nasıl tarif edildiği anahtar. Eğriyi, o eğri üzerindeki belli yerlerde nok-
talar üzerinden mi temsil etsem? Ki o her nokta bir bilinmeyen / değişkenle
genel formüle dahil edilse? O noktaların her birinde ayrı bir normal diferansiyel
denklem (ordinary differential eqution) olabilirdi, o denklemi takip ederek bir
sonraki noktaya gidebilirdim, vs.
Fakat kesit seviyeleri böyle işlemiyor. Hatta ilk akla gelen (gayet doğal)parçacıklı
üstteki fikir sayısal hesaplarda çabucak bazı engellere tosluyor. Mesela üstteki
resimdeki örnek idealdi dedik, parçacıklar t = 1’da biraz yayılırlar, çok değil,
ama çok yayılıyor da olabilirlerdi. Ya da ters yönde eğime göre noktalar aynı
noktada toplanabilirdi, bu sayısal hesabı iyice bozardı çünkü noktalar üst üste
binerdi, aradaki farkları doğru dürüst hesaplayamazdık.
Peki o zaman kesit seviyeleri bu problemleri nasıl çözüyor? Ondan önce kesit se-
viyesi nedir? Kesit seviyesi bir ana fonksiyona göre tarif edilir, mesela Φ(x, y)’nin
kesit seviyesi. Bu seviye Φ(x, y) = 0 olabilir, yani Φ(x, y)’nin sıfırdaki kesit se-
viyesine bakabiliriz.
Kesitleri üç boyutlu yüzey üzerinde yapılan yatay kesitler olarak düşünebiliriz.
Üç boyutlu fonksiyonun o yatay düzlem üzerindeki hali, yansıması bu kesittir.
Birden fazla kesiti farklı kontur renkleri ile gösterebilirdik. Mesela yeryüzeyi x, y
kordinatlarındaki yükseklik (dağlar) verisini konturlar olarak göstermek klasik
bir topografi tekniğidir. Yapay bir veri üzerinde görelim, x, y ve yükseklik dey-

1
ince üç boyutlu bir fonksiyondan bahsediyoruz, onun ayrıksal halini mesela 10x10
boyutunda bir matris ile gösterebiliriz. Formül

Φ(x, y) = exp −2 log(2)((x − x0 )2 + (y − y0 )2 )/s2




from mpl_toolkits.mplot3d import Axes3D


from matplotlib import cm

def Phi(x, y):


s = 1.5; x1 = 5.0; y1 = 5.0
g = np.exp( -2 *np.log(2) * ((x-x1)**2+(y-y1)**2) / s**2)
return g

D = 10
x = np.linspace(0,10,D)
y = np.linspace(0,10,D)
xx,yy = np.meshgrid(x,y)
zz = Phi(xx,yy)

fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(xx, yy, zz, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
plt.savefig('2_11_02.png')

plt.figure()
contours = [0.1, 0.2, 0.3]
cs=plt.contour(xx,yy,zz,contours)
plt.clabel(cs,inline=1,fontsize=9)
plt.savefig('2_11_03.png')

Tam ortasına bir tepe koyduk, bir analitik fonksiyon kulladik ama bunu rahatlık
amacıyla yaptık, elle bazı değerleri matriste gerekli yerlere direk koysak aynı
sonucu elde ederdik. Üstteki matrisin değerlerini basarsak mesela şuna benzer,

np.set_printoptions(precision=3,suppress=True)
print (zz)

2
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]
[0. 0. 0. 0.002 0.005 0.005 0.002 0. 0. 0. ]
[0. 0. 0.005 0.026 0.062 0.062 0.026 0.005 0. 0. ]
[0. 0.002 0.026 0.146 0.343 0.343 0.146 0.026 0.002 0. ]
[0. 0.005 0.062 0.343 0.807 0.807 0.343 0.062 0.005 0. ]
[0. 0.005 0.062 0.343 0.807 0.807 0.343 0.062 0.005 0. ]
[0. 0.002 0.026 0.146 0.343 0.343 0.146 0.026 0.002 0. ]
[0. 0. 0.005 0.026 0.062 0.062 0.026 0.005 0. 0. ]
[0. 0. 0. 0.002 0.005 0.005 0.002 0. 0. 0. ]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]]

Kontur grafiğinde üç tane konturu gösterdik, contours değişkeni listesinde tanımlı.
Derse dönelim. Yani kesit seviyeleri bir eğriyi dolaylı (implicitely) tanımlamış
oluyor. İki boyutlu bir eğriyi bir sürü nokta üzerinden tanımlamak yerine, üç
boyutlu bir yüzeyin bir kesit üzerindeki yansıması üzerinden tanımlıyoruz, yani
Φ(x, y) = 0 gibi. Yani bir eğri, Φ(x, y) = 0 denklemini çözen x, y değerleri oluyor.
Basit bir örnek üzerinde görürsek, mesela Φ(x, y) = x2 +y2 . Bu fonksiyonun kesit
seviyelerini nasıl alırım? Φ’yi bir sabite eşitleyerek bu seviyeleri elde edebilirim,
Φ(x, y) = x2 + y2 = c. c pozitif olduğunda elde edilen sonuçlar çember olacaktır
tabii, bu formül klasik, ünlü bir formül.
Üç boyutta z = Φ(x, y) x, y, z kordinatında bir yüzeydir, bir kap şekli, onu z = c
düzlemi ile kesersek o düzleme yansıyan eğri kesit seviyesi, bir çember. Onu x, y
düzlemine indirirsek orada da bir çember görürüz.

Kesit seviyelerin önemli bir avantajı üç boyuttaki tek fonksiyonu manipüle etm-
eye izin vermesi, bu rahat, tek Φ ile mesela iki tane ayrı çember elde edebilirdim.

3
Eğriyi ilerletmek için gradyan yönünü seçiyoruz. Bu yön eğrinin birim normali,

grad Φ
~ =
n
| grad Φ|

Gradyanın 1 olduğu özel durum için, yani | grad Φ| = 1, üstteki formül basitleşir.
Eğrinin hareketini tanımlayan bir diğer faktör eğriye etki eden hız alanı, yani v.
Bu alan her x, y noktasında tanımlı v(x, y) olarak gösterilebilir. Hepsi bir arada
olursa,

∂Φ
+ v · grad Φ = 0 (1)
∂t

Üstteki formülasyonun detaylı türetilmesi için bkz [3].


v bir alandır, her x, y için farklı olabilir. Φ’nin bir fonksiyonu da olabilir. Yani hız
eğrinin ne durumda olduğuyla bağlantılı olabilir, Çoğunlukla v mesela eğrinin
kavisliliğine (curvature) bağlantılandırılır.
(1)’i şu şekilde tekrar yazarsak,

∂Φ grad Φ
+v· | grad Φ| = 0
∂t | grad Φ|

grad Φ/| grad Φ| ifadesi egrinin normali n


~ , o zaman

∂Φ
+ v · n| grad Φ| = 0
∂t

elde ediyoruz, v · n’e yeni bir isim verebilirim, ona hız diyelim. Normal yöndeki
hız, F, ve grad yerine ∇ kullanırsak,

∂Φ
+ F|∇Φ| = 0
∂t

4
Bu hız normal yöndedir. Ünlü kesit seviyesi formülü budur. Eğer F sabit ise biraz
önce bahsettiğimiz yangının yayılma durumu ortaya çıkar. Ateş bildiğimiz gibi
yakabildiği her yere gitmek ister, sürekli ileri doğru ilerler. F’nin illa sabit olması
gerekmez, ∇Φ’nin bir fonksiyonu bile olabilir, o zaman onu F(∇Φ) yapardım.
Mesela
 
grad Φ
κ = div
| grad Φ|

Bu bir F(∇Φ) örneği, ∇Φ’nin bir fonksiyonu. Lineer değil doğal olarak, gayrı
lineer işlemler var.
Üstteki formül eğrinin kavisliliğiyle bir alaka kuruyor. Kavislilik üzerinden eğri
hareketi ilginç bir şey; mesela bir elipsi düşünelim, ve hareket içeri doğru olsun.

Elipsin üst, kavisin daha az olduğu yerlerde içeri hareket (hızı) daha az, çok
olduğu yerlerde daha fazla ise, o zaman değişim ardından bir çembere ulaşılacaktır.
Hatta aslında hangi ilk şekilden başlarsak başlayalım, gidişat aynı şekilde mükemmel
bir çembere doğru olacaktır.
Şimdiye kadar gördüklerimiz kesit seviyeleri. Bu denklemlerin bir de hesap-
sal olarak sonlu farklar (finite difference) yöntemiyle çözüm formülleri var. Bu
formüller oldukca çetrefil.
Şimdi hızlı marş (fast marching) kouşuna gelelim. Hızlı marş eğri ilerletmenin
çok hızlı bir çözümü olduğu durumlar için. Çünkü bu özel durumda “dalga”
on kısmı hep aynı şekilde ilerliyor. F’nin işareti hiç değişmiyor, yani hareket hep
aynı genel yönde. Bu durumda kesit seviyeleri formülü, sonlu farklar hesabı
yerine hızlı marş yöntemi kullanılabiliyor, çünkü çok farklı hareket şekli yok,
eğri gelip kendi üstüne dönemiyor, vs.
Hızlı mars yöntemi aslında geliş zamanı bazlı başka bir formülasyonu çözüyor.

|∇T |F = 1

Eğer T (x, y) fonksiyonunu yayılan dalga önünün x, y noktasına geliş zamanını


temsil ettiğini düşünürsek, tek boyutta katedilen mesafe x = FT , bu basit bir
mesafe eşittir hız çarpı zaman sonucu. Mesafeye göre türev alırsak,

5
dT
1=F
dx

Çok boyuttaki ∇T kullanılabilir, çünkü gradyan T ’nin kesit seviyelerine dikgendir.


O zaman

1
= |∇T |
F
denebilir. ya da

|∇T |T = 1

Hızlı marşı nasıl kodlarım? Eğri ilerleme hesabını eğriden ileri gidişin mesafesi
hesabına çevirebilirim. Eğriyi için alacak şekilde bir izgara yaratabilirim,

Bu ızgarayı baz alarak eğriye olan bir uzaklığın fonksiyonu d(x, y)’i bulmak is-
tiyorum. Eğri içini hesaba katalım, orada eğriden geriye bir uzaklık olacak, orada
eksi, dışarıda artı.
Uzaklığı her izgara köşesi için hesaplamak istersem, ne yaparım?
Altta kısayol bulmak için hızlı marş yöntemini görüyoruz, kod [1,2]’yi baz aldı.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage
import util

def perform_fm(W, pstart, niter=np.inf, bound='sym', svg_rate=10):


n = W.shape[0]
neigh = np.array([[1, -1, 0, 0], [0, 0, 1, -1]])

def symmetrize(x,n):
if (x<0):
x = -x;
elif (x>=n):
x = 2*(n-1)-x

6
return x

if bound=='per':
boundary = lambda x: np.mod(x,n)
else:
boundary = lambda x: [symmetrize(x[0],n), symmetrize(x[1],n)] # todo

ind2sub1 = lambda k: [int( (k-np.fmod(k,n))/n ), np.fmod(k,n)]


sub2ind1 = lambda u: int( u[0]*n + u[1] )
Neigh = lambda k,i: sub2ind1(boundary(ind2sub1(k) + neigh[:,i]))
extract = lambda x,I: x[I]
extract1d = lambda x,I: extract(x.flatten(),I)

nstart = pstart.shape[1]
I = list( np.zeros( (nstart, 1) ) )
for i in np.arange(0, nstart):
I[i] = int( sub2ind1(pstart[:,i]) )

D = np.zeros( (n,n) ) + np.inf # current distance


for i in np.arange(0, nstart):
D[pstart[0,i],pstart[1,i]] = 0

S = np.zeros( (n,n) )
for i in np.arange(0, nstart):
S[pstart[0,i],pstart[1,i]] = 1 # open

iter = 0
q = 100 # maximum number of saves
Dsvg = np.zeros( (n,n,q) )
Ssvg = np.zeros( (n,n,q) )
while ( not(I==[]) & (iter<=niter) ):
iter = iter+1;
if iter==niter:
break
j = np.argsort( extract1d(D,I) )
if np.ndim(j)==0:
j = [j]
j = j[0]
i = I[j]
a = I.pop(j)
u = ind2sub1(i);
S[u[0],u[1]] = -1
J = []
for k in np.arange(0,4):
j = Neigh(i,k)
if extract1d(S,j)!=-1:
J.append(j)
if extract1d(S,j)==0:
u = ind2sub1(j)
S[u[0],u[1]] = 1
I.append(j)
DNeigh = lambda D,k: extract1d(D,Neigh(j,k))
for j in J:
dx = min(DNeigh(D,0), DNeigh(D,1))
dy = min(DNeigh(D,2), DNeigh(D,3))

7
u = ind2sub1(j)
w = extract1d(W,j);
Delta = 2*w - (dx-dy)**2
if (Delta>=0):
D[u[0],u[1]] = (dx + dy + np.sqrt(Delta))/ 2
else:
D[u[0],u[1]] = min(dx + w, dy + w)
t = iter/svg_rate
if (np.mod(iter,svg_rate)==0) & (t<q):
print (t)
Dsvg[:,:,int(t-1)] = D
Ssvg[:,:,int(t-1)] = S

Dsvg = Dsvg[:,:,:int(t-1)]
Ssvg = Ssvg[:,:,:int(t-1)]
return (D,Dsvg,Ssvg);

def exo2(x0,W):
n = W.shape[0]
pstart = np.transpose(np.array([x0]))
[D,Dsvg,Ssvg] = perform_fm(W, pstart, np.inf, 'sym',n*6)
plt.figure();
for i in np.arange(0,4):
plt.subplot(2, 2, i+1)
d = Dsvg[:,:,i]
d[d==np.inf] = 0
util.imageplot(d)
plt.set_cmap('jet')
plt.savefig('out-450.png')
return D

n = 40
W = np.ones( (n,n) )
x0 = [int(n/2), int(n/2)]

D = exo2(x0,W)

plt.figure()
displ = lambda D: np.cos(2*np.pi*5*D/np.max(D.flatten()) )
util.imageplot(displ(D))
plt.savefig('out-480.png')

1.0
2.0
3.0
4.0
5.0
6.0

8
def exo3(x0,W):
n = W.shape[0]
pstart = np.transpose(np.array([x0]))
[D,Dsvg,Ssvg] = perform_fm(W, pstart, np.inf, 'sym',n*6)
# display
k = 8
displ = lambda D: np.cos(2*np.pi*k*D / np.max(D.flatten()))
plt.figure()
util.imageplot(displ(D))
plt.set_cmap('jet')
plt.savefig('out-560.png')
return D

n = 100
x = np.linspace(-1, 1, n)
[Y, X] = np.meshgrid(x, x)
sigma = .2
W = 1 + 8 * np.exp(-(X**2 + Y**2)/ (2*sigma**2))
util.imageplot(W)
plt.savefig('out-520.png')

x0 = [round(.1*n), round(.1*n)]

9
res = exo3(x0,W)

1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
10.0
11.0
12.0
13.0
14.0
15.0
16.0

def exo4(tau,x0,x1,G):
n = G.shape[0]
Geval = lambda G,x: util.bilinear_interpolate(G[:,:,0], np.imag(x), np.real(x) ) +
niter = 1.5*n/tau;
# init gamma

10
gamma = [x1]
xtgt = x0[0] + 1j*x0[1]
for i in np.arange(0,niter):
g = Geval(G, gamma[-1] )
gamma.append( gamma[-1] - tau*g )
if abs(gamma[-1]-xtgt)<1:
break
gamma.append( xtgt )
return gamma

n = 100
x = np.linspace(-1, 1, n)
[Y, X] = np.meshgrid(x, x)
sigma = .2
W = 1 + 8 * np.exp(-(X**2 + Y**2)/ (2*sigma**2))
x0 = [round(.1*n), round(.1*n)]
D = exo3(x0,W)

G0 = util.grad(D)
d = np.sqrt(np.sum(G0**2, axis=2))
U = np.zeros((n,n,2))
U[:,:,0] = d
U[:,:,1] = d
G = G0 / U
tau = .8
x1 = round(.9*n) + 1j*round(.88*n)
gamma = [x1]

Geval = lambda G,x: util.bilinear_interpolate(G[:,:,0], np.imag(x), np.real(x) ) + 1j


g = Geval(G, gamma[-1] )
gamma.append( gamma[-1] - tau*g )
gamma = exo4(tau,x0,x1,G)

util.imageplot(W)
plt.set_cmap('gray')
h = plt.plot(np.imag(gamma), np.real(gamma), '.b', linewidth=2)
h = plt.plot(x0[1], x0[0], '.r', markersize=20)
h = plt.plot(np.imag(x1), np.real(x1), '.g', markersize=20)
plt.savefig('out-760.png')

1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
10.0
11.0
12.0
13.0
14.0
15.0
16.0

11
Kaynaklar
[1] Peyre, Dijkstra and Fast Marching Algorithms, https://nbviewer.jupyter.
org/github/gpeyre/numerical-tours/blob/master/python/fastmarching_
0_implementing.ipynb
[2] Peyre, https://github/gpeyre/numerical-tours
[3] Bayramli, Kısmi Türevsel Denklemler, Kesit Seviyeleri

12
Ders 15
Konumuz çok, çok büyük ve seyrek matrisler üzerinden Ax = b çözümü. Çok
büyük boyutlarda A’nin tersini almak pahalı bir işlem olacaktır. Standart teknik
Gauss Eliminiasyon tekniği de yüksek boyutlarda pahalı bir işlem olur. Pahalı
olmayan işlem nedir? A’yi bir vektör ile çarpmaktır mesela. Bu işlemin nasıl
devreye gireceğini göreceğiz.
Genel ismiyle daha hızlı olacak genel kategori özyineli (iterative) metotlardır. Bu
yöntemlerde en iyi cevaba erişmeyiz, ama yeterince yaklaşırız, ve daha önemlisi
bu işi çok hızlı bir şekilde yapabiliriz. Bu metotlarda iyi bir önkoşullandırıcı (pre-
conditioner) matris P’yi seçmek önemlidir. P, A’yi temel alan ve bazı işlemleri
kolaylaştıran bir yapı olacaktır.
Özyineli tekniklerden en iyi bilinenlerden biri eşlenik gradyan tekniğidir. Bu
yöntem için A’nin simetrik, pozitif kesin olması gerekir.
Özyineli metotlarda bir başlangıç x0 değeri vardır, ve oradan xk+1 elde edilir. Li-
neer metotlar için başlangıcın nerede olduğu önemli değildir, sıfırda bile başlanabilir.
Gayrılineer (nonlinear), “Newton” metotlarında sonuca yakın bir yerde olmak
önemlidir, bunun için uğraşılır.
Çözmek istediğimiz

Ax = b

Bunu şöyle de yazabilirim

x = x − Ax + b

x = (I − A)x + b

Şimdi bu denklemi alıp sağ tarafı “eski” sol tarafı “yeni” olarak temsil edersek,

xk+1 = (I − A)xk + b

elde ederiz. Bu önkoşulsuz, basit bir özyinelemedir. Önkoşul P istersek,

Ax = b

0 = −Ax + b

Px = Px − Ax + b

1
Px = (P − A)x + b

Pxk+1 = (P − A)xk + b

Eğer P = A olsaydı, o zaman direk eski denklemi çözüyor olurduk. Biz P ≈ A


dedik, “yakın ama aynı olmayan bir P” istiyoruz, özellikle. Bu P’nin işlerimizi
kolaylaştıracağını umuyoruz çünkü.
Bazı P örnekleri şunlardır: Jacobi A’nin sadece çaprazındaki değerleri alıp P’ye
koyar. Gauss-Seidel yaklaşımı [1], hem çaprazı, hem alt üçgensel (lower triangu-
lar) kısmı alıp P’ye koyar.
Not: İlginç bir tarihi anektod, Gauss Eliminasyon yöntemini keşfeden bizzat
Gauss’un kendisi bile bu yöntemi kullanmak istememişti, büyük matrislerde elim-
inasyon işinin özellikle hesabın elle yapıldığı eski yılllarda çok külfet getiriyordu.
Özyineli ilk metotlardan Gauss-Seidel tekniği Gauss’u çok memnun etti, ve kendi
hesaplarında bu tekniği kullandı.
Diğer yaklaşımlar fazla rahatlatma (overrelaxation), ve tamamlanmamış (incom-
plete) LU gibi yaklaşımlar. Ben üstlisans yaparken bu son iki yöntem Jacobi,
Gauss-Seidel’den bir adım ileri gitme yönündeki denemelerin başlangıcıydı.
Peki x’lerin doğru cevaba erişip erişmediğini nereden anlarız? Hata hesabı için
bir formüle ihtiyacım var. Alttaki formüllerde 2. formülü 1. formülden çıkartırsam,
ve ek = x − xk ise

xk+1 = (I − A)xk + b

xk = (I − A)x + b

Şunu elde ederim,

Pek+1 = (P − A)ek

İki tarafı P−1 ile çarparsam,

ek+1 = (I − P−1 A)ek = Mek

O zaman hata hesabı için her özyineleme adımında üstteki hesabı yaparım. Paran-
tez içindeki büyük ifadeye M ismi verdim, buna özyineleme matrisi de diyebili-
riz.
Değerlere yakında bakarsak, P’nin A’ya yakın olmasını istiyoruz demiştik, o za-
man P−1 A, I’ya yakın olacaktır, ve bu I’ya yakın olan şey I’dan çıkartılınca sonuç
sıfıra yakın olacaktır. Hatanın ufak olmasını istediğimize göre bu mantıklı.

2
Her adımda M ile çarptığımıza göre,

ek = Mk e0

Üstteki sıfıra gider mi? Giderse ne kadar hızlı gider? Bunun olması için M’nin
hangi öğesine bakmak gerekir? En büyük özdeğerine bakmak gerekir. Genel
olarak şunu söyleyebiliriz, her |λ(M)| < 1 olması gerekir. Notasyonel olarak en
büyük özdeğer ρ(M)’dir, |ρ(M)| ise spektral yarıçapı (spectral radius) olarak ad-
landırılır.
Bazı örnekler



2 −1
 2 −1 
K=A=



−1 2

Özdeğerler λj (A) = 2 − 2 cos θj


PJacobi = 2I

M = I − P−1 A

Sonuç

1
0
 
2
1 1
 2
0 2

.. .. 
 
 1 . . 
 2
..
. 0

Boş olan yerlerde sıfır değerleri var.


Yani P−1 = 1/2

1
M=I− A
2

1 jπ
λj (M) = 1 − λj (A) = cos
2 N+1

O zaman yaklaşıksallama olacak. En büyük özdeğer

π
ρ = cos
N+1

3
Eğer her döngüde bir şeyleri grafiklemek istesem, neyi seçerdim? Her döngüdeki
hatayı, “artığı (residual)” grafikleyebilirdim. Tam denklem

Ax = b

Axk gerçeğe “yakın”, o zaman artık değer r bu ikisi arasındaki fark olabilir,

r = Ax − Axk

r = Aek

[hata grafikleme atlandı]


Örnek Jacobi kodları
Kod #1

import scipy.linalg as lin

A = np.array([[6.,1.,1.],
[1.,7.,1.],
[1.,1.,8.]])
b = [1.,1.,1.]

xreal = lin.solve(A, b); print "solution", xreal

P = np.diag(np.diag(A)); print "P",P


x = np.zeros(A.shape[0]); print x
T = P - A
for i in range(10):
x = lin.solve(P, b+np.dot(T,x))
print x

solution [ 0.13249211 0.11041009 0.09463722]


P [[ 6. 0. 0.]
[ 0. 7. 0.]
[ 0. 0. 8.]]
[ 0. 0. 0.]
[ 0.16666667 0.14285714 0.125 ]
[ 0.12202381 0.10119048 0.08630952]
[ 0.13541667 0.11309524 0.09709821]
[ 0.13163442 0.10964073 0.09393601]
[ 0.13273721 0.11063279 0.09484061]
[ 0.1324211 0.11034603 0.09457875]
[ 0.13251254 0.11042859 0.09465411]
[ 0.13248622 0.11040476 0.09463236]
[ 0.13249381 0.11041163 0.09463863]
[ 0.13249162 0.11040965 0.09463682]

Kod #2

4
A = np.array([[6.,1.,1.],
[1.,7.,1.],
[1.,1.,8.]])

b = [1.,1.,1.]

xreal = lin.solve(A, b); print "solution", xreal

P = np.diag(np.diag(A)); print "P",P


x = np.zeros(A.shape[0]); print x
J = lin.solve(P,P-A)
c = lin.solve(P,b)
for i in range(10):
x = np.dot(J,x) + c
print x

solution [ 0.13249211 0.11041009 0.09463722]


P [[ 6. 0. 0.]
[ 0. 7. 0.]
[ 0. 0. 8.]]
[ 0. 0. 0.]
[ 0.16666667 0.14285714 0.125 ]
[ 0.12202381 0.10119048 0.08630952]
[ 0.13541667 0.11309524 0.09709821]
[ 0.13163442 0.10964073 0.09393601]
[ 0.13273721 0.11063279 0.09484061]
[ 0.1324211 0.11034603 0.09457875]
[ 0.13251254 0.11042859 0.09465411]
[ 0.13248622 0.11040476 0.09463236]
[ 0.13249381 0.11041163 0.09463863]
[ 0.13249162 0.11040965 0.09463682]

Bu kodların ikisi de özyineli Jacobi hesabı yapıyor. Birincisi her döngüde solve
işlemi yapıyor. Fakat daha önce belirttiğimiz gibi, her döngüde çarpım işlemi
yapmak çok daha optimal olur. İkinci kod [1]

Pxk+1 = (P − A)xk + b

işlemini iki parçaya ayırmış, P, P − A ve P, b sistemlerini ayrı ayrı çözerek, döngü


içinde Jx+c ile sadece çarpma ve toplama kullanmayı başarmış. Bu parçalamanın
yapılabilmesinin sebebi tabii ki bir lineer sistemle çalışıyor olmamız. Çok akıllıca
bir teknik.
Kaynaklar
[1] Olver, A Basic Introduction to Matlab, http://www.math.umn.edu/˜olver/
matlab.html

5
Ders 18
[bazı multigrid yorumları atlandı]
Krylov Matrisleri
Bu matrislerden K olarak bahsedeceğiz ve bu yöntem bağlamında

Ax = b

sistemini çözüyor olacağız. Krylov matrisleri şöyle yaratılır

 
Kj = b Ab A2 b .. Aj−1 b

Krylov altuzayı K ise üstteki kolonların lineer kombinasyonudur (span), ya da


üstteki matrisin kolon uzayıdır da denebilir. Bu tür bir matrisle niye ilgilenirim?
Jacobi işlemi aslında bu kolonların kombinasyonlarından birini her adımda yavaş
yavaş seçer, yani aslında Krylov altuzayının bir parçasında çalışır. Daha doğrusu
ufak ufak başlar, o altuzayda yavaş yavaş büyür.
Jacobi sürekli bir kombinasyon seçimi yapar, tabii bu seçimin en iyi seçim olduğu
söylenemez. Seçimin en iyisini yapsak daha iyi olmaz mı?
En iyiyi seçmek için kullanılacak metot eşlenik gradyan (conjugate gradient) ola-
cak. Bu metot K içinde xj ’yi seçer.
K uzayı yaklaşıksal çözümümüzü aradığımız yer tabii ki. Bu arada üstteki K
matrisinin elemanlarını yaratmak çok kolay, matris çarpımı yapıyoruz, ve bir son-
raki eleman bir öncekinin A katıdır, ve A çoğunlukla seyrektir (sparse), bazen de
simetriktir (eşlenik gradyan metotu için A simetrik, pozitif kesin olmalı).
Ama EG metotundan önce Arnoldi kavramını görmemiz lazım.
Uygulamalı Matematikte sürekli bir şeyler “seçeriz”, ve çoğunlukla baz vektörleri
seçeriz ve birkaç özellik ararız. Aradığımız özellikler öncelikle hızdır, yukarıda
gördüğümüz gibi, matris çarpımı var, bu çok hızlı. Bir diğer özellik bağımsızlık.
Bir diğeri baz vektörlerinin birimdik (orthonormal) olması. Bu son özellik elde
edilebilirse en iyisidir. Üstteki K pek iyi bir baz değildir. Arnoldi’nin amacı
Krylov bazını dikgenleştirmektir. b, Ab, ..’yi alıp q1 , q2 , .., qj oluşturmaktır. Koda
bakalım,
Algoritma arnoldi

1. q1 = b/||b||, normalize et

2. Her j = 1, .., n − 1 için qj+1 ’i hesaplamaya başla

• t = A ∗ qj
• Her i = 1, .., j için t, Kj+1 uzayında

1
– hij = qTi t, hij qi , t’nin qi ’ye yansıması
– t = t − hij qi , yansımayı çıkart

3. // t, q1 , .., qj ’ye dikgen oldu

4. hj+1,j = ||t||, t’nin büyüklüğünü hesapla

5. // qj+1 = t/hj+1,j q1 , .., qj birimdik

Fikir Gram-Schmidt fikriyle çok benzer. 1. satırda ilk vektörü olduğu gibi alıyoruz,
sadece normalize ediyoruz. Sonra 3. satırda bir deneme amaçlı bir vektör t’ye
bakıyoruz. Bu vektör ilk baştaki b’ye dikgen olmayacak muhakkak. O zaman 5.
satırda bir iç çarpım (inner product) sonrası, 6. satırda t’den çıkartıyoruz. 8 ve 9.
satırlarda bu vektörü normalize ediyoruz.
Eğer A simetrik ise, hij hij−1 çarpımını birkaç kere çıkartmam yeterlidir.
Örnek

     
1 1 1 1 1 1
 2   1   1 2 4 8
 , b =   , K4 = 

A= 
 3   1   1 3 9 27 
4 1 1 4 16 64

A hem simetrik, onun ötesinde köşegen, ayrıca oldukça seyrek. Krylov matrisi
de üstte. İlk kolonu b ile aynı. 2. kolon için A ile çarpmışız. 3. için bir daha A ile
çarpmışsız, 4. için bir daha.
K eğer bir baz ise, temsil ettiği uzay tüm R4 ’tür. Üstteki örnekte j = n = 4, tüm
değerleri işledik. Eğer n çok büyük bir sayi ise mesela 105 gibi, j << n yani sona
gelmeden çok önce durmak isteriz. Eşlenik gradyan bunu başarıyor.
K formatındaki bir matrise Vondermonde matrisi de denir, bu tür matrislerde ilk
kolon sabit, 3., 4., .. kolonlar ikincinin üstel halidir.
Vondermond matrisleri pek iyi koşullandırılmış (conditioned) matrisler değildir.
Alakalı bir soru: iyi, kötü koşullandırılmış matrisi nasıl anlarız? Matris eşsiz
(singular) değil. Determinanti hesaplasak sıfır çıkmaz. Ama neredeyse “eşsiz
olmaya yakın”. Bunun testini nasıl yaparız?
Matris eşsiz değil, o zaman özdeğerleri hesaplamak akla gelebilir, oradan λmin ,
λmaks ’i kontrol etmek.. Fakat simetrik olmayan matrislerin özdeğerlerini hesapla-
mak hoş değildir, “güvenilir” hesaplar değildirler. Çok kötü koşullandırılmış
ama tüm özdeğerleri 1 olan matrisler olabilir mesela, çaprazında 1’ler olur, çaprazın
üstünden katrilyonlar olabilir..
Bu işi doğru yapmanın yolu V T V’ye bakmak. Yani genel kural, matris simetrik
değilse, devriği ile kendisini çarp, sonucun özdeğerleri hep pozitif olur. V T V’nin
i’inci özdeğeri, V’nin i’inci özdeğerinin karesi olacaktır.

2
Bu arada V T V matrisine Gram matrisi denir.
Eğer QT Q olsaydı koşullandırma sayısı (condition number), yani en büyük / en
küçük özdeğer ne olurdu? QT Q = I o zaman çaprazda hep 1 var, 1/1 = 1. Bu en
iyi koşullandırma sayısıdır.
Şimdi şu çok önemli formül için gerekli her bileşene sahibiz.

AQ = QH

A bize verilen -diyelim ki- simetrik matris. Q Arnoldi’den gelen baz. H ise kodda
görülen çarpan değerleri. Yani QH bir nevi Gram-Schmidt’teki gibi, hatırlarsak
Gram-Schmidt QR ile temsil ediliyordu. Q yine birimdik, Gram-Schmidt’te R üst
köşegen.
H hesaplanırsa

 p 
p5/2 5/2 p
 5/2 5/2 4/5 p 
H= p 
 4/5 p 5/2 9/20 
9/20 5/2

H simetrik ve üçlü köşegen (tridiagonal). Üçlü köşegenlik bize ne söyler? Tekrarın


(recurrence) kısa olduğunu.

AQ = QH

formülüne dönelim, kolonsal olarak üstteki çarpımı nasıl gösteririz?


5 5
Aq1 = q1 + q2
2 2
Tek bir kalemde eğer A simetrik ise H’in de simetrik olduğunu nasıl gösteririm?
H’nin formülü lazım,

H = Q−1 AQ

Q−1 nedir? Q’nun dikgen olduğunu hatırlayalım, o zaman Q−1 = QT . Üstte


yerine koyalım,

H = QT AQ

Buna bakarak H kesin simetriktir diyebiliriz, simetrik matrisler aynen üstteki gibi
yaratılır zaten, ortaya bir simetrik matris koyarsın, sağdan herhangi bir matris,
soldan onun devriği ile çarparsın, ve yeni bir simetrik matris ortaya çıkar.

3
Yani vardığımız sonuç Krylov bazının hızlı, basit şekilde dikgen hale getirilebileceğidir.

4
Ders 19
Eşlenik Gradyan (Conjugate Gradient) Yöntemi
Arnoldi metotu Gram-Schmidt’e benzeyen bir yöntemdir ve bir dikgen baz or-
taya çıkartır. Bu baz, Krylov altuzayının bazidir, ki bu altuzaydaki her yeni baz
vektör, e’nin başka bir üstü alınıp çarpılarak elde edilir. Fakat bu pek iyi bir baz
değildir, bazların dikgenleştirilmesi gerekir, ve Arnoldi’nin yaptığı budur.
Arnoldi-Lanczos yöntemi özdeğerler (eigenvalue) bulmak için de kullanılır.

AQ = QH

eşitliğindeki H matrisinin alt-matrisine bakılırsa, aranılan özdeğerler buradan


okunabilir. Bu alt-matris simetrik ve üst köşegendir. (upperdiagonal).

H = Q−1 AQ

formülünde H, A matrisleri birbirine benzerdir (similar) ve benzer matrislerin


özdeğerleri aynıdır.
Bu kavramlardan şöyle bir bahsetmek istedim, belki günün birinde çok büyük
bir matrisin özdeğerlerini bulmak gerekir, akılda olsun. Yazılım arpack bunun
için kullanılabiliyor. Bahsi yaptık bir diğer sebep lineer cebirin yarısı lineer sis-
temlerse, diğer yarısı özdeğer problemleridir denebilir. Buraya gelmişken üstteki
özdeğer yönteminden bahsetmemek olmazdı.
Konumuza dönelim.
A pozitif kesin ve simetrik olmalı. Eğer değilse birazdan gösgtereceğimiz formülleri
kullanmak biraz riskli olur, işleyebilirler ama garanti olmaz.
rK = b − Axk , Kk ’ye dikgen, xk ∈ KK .
Demek ki xk ’yi özyineli olarak yaratabiliriz, ve her adımda sadece A ile çarpmamız
gerekir. Üstteki formülde A ile çarpım olduğuna göre, rK bir sonraki uzay k + 1
içinde olacaktır. Arnoldi’den biliyoruz ki qk+1 aynı uzay içindedir. O zaman
rk , qk+1 ’in bir katıdır. Yani r ile gösterilen “artıklar (residuals)” birbirine dikgen.
Yani

rTi rk = 0, i < k

Artıkların birbirine dikgen olmasının sebebi içlerinde A olması.


Başlangıç değerleri

d0 = b

1
x0 = 0

r0 = b − Ax0 = b

Simetrik Pozitif Kesin A İçin Eşlenik Gradyan Metodu


Algoritma eslenik_gradyan

1. αk = rTk−1 rk−1 /dTk−1 Adk−1

2. αk = αk−1 + αk dk−1

3. rk = rk−1 − αk Adk−1

4. βk = rTk rk /rTk−1 rk−1

5. dk = rk + βk dk−1

d “arama yönüdür”, optimizasyon ilerlerken gideceğimiz istikamettir. 2. adımda


güncellemeyi yapıyorum. Peki bir sonraki yönüm ne olmalı?
Her Döngüde:
- Ad çarpımını görüyoruz, çünkü A ile çarpım bize yeni Krylov altuzayını veriyor.
- 2 içsel çarpım
- 2 ya da 3 vektör güncellemesi
Peki k adım sonra hata ||ek || nedir ve ilk baştaki hata ||e0 || ile bağlantısı nedir?

√ k
λmaks − λmin
||ek || 6 2 ||e0 ||
λmaks + λmin

Hala bir kelimeye açıklık getirmedik; gradyan. Niye bir “gradyan” kelimesi kul-
lanıyoruz, neyin gradyanından bahsediyoruz, bu teknik için gradyanlar ne an-
lama geliyor?
Lineer problemlerde Ax = b eşitliği vardır ve bu eşitlik enerjinin gradyanından
gelir. Yani

1
E(x) = xT Ax − bT x
2

enerjisinin gradyanından. Üstteki formül nereden geldik diye düşünebilirsiniz,


hep lineer sistemlerden bahsettik, ve bu sistemlerde her şey Ax = b formatına
uyar. Şimdi birdenbire matematiğin farklı bir koluna geçiyorum sanki, üstteki
formülü minimize etmeye uğraşıyorum, yani optimizasyona giriyorum. Fakat
cebirsel olarak düşünürsek,

2
∂E
grad E = [ ] = Ax − b
∂x

olacaktır. Minimumda üstteki sıfır olacağına göre

Ax − b = 0

Ax = b

Yani karesel enerjinin lineer gradyanı vardır, ve onun minimumu Ax = b’dir.


Bu demektir ki lineer denklemi çözmek ve enerjiyi minimize etmek aslında aynı
şeydir! Minimum kelimesini kullanabiliyorum bu arada, çünkü A’nin pozitif
kesin olduğunu biliyorum.
Minimize işlemi nasıl yapılır? Diyelim ki alttaki gibi bir E(x)’im var, kap şeklinin
herhangi bir noktasındayım, ve aşağı inmem lazım. En fazla artış gradyan g ise,
dibe inmek için −g yönünde gidebilirim.

Bu yön doğal bir yöndür, ilk akla gelen fikirdir ve mantıklıdır. Fakat en iyi
yön değildir. Şimdi minimizasyon çözümü olarak eşlenik gradyan açısından
bakıyoruz olaya, işin gradyan tarafı da böylelikle açıklığa kavuşacak.
Negatif gradyanın aynı zamanda artığın da (residual) negatif yönüdür. Artığın
yönünde hareket etmek iyi midir? Negatif gradyanı takip etmenin bir diğer ismi
“en dik iniş (steepest descent)”tir. Fakat, başlangıç noktasına göre bu değişir ama,
çok fazla iniş çıkış ta yaşanabilir.
r’ler hesapsal bilimde çok aranan bir özelliğe sahip değildir, dikgenlik. Bir şekilde
dikgenlik her zaman doğru yönde hareket ettiğimizin garantisidir. Gidilmesi
gereken doğru yön, üstteki kodda 5. satırda hesaplanan yöndür. Bu yöne “A-
dikgen” denir.
Bir resimle göstermek gerekirse, alta bakalım, soldaki en dik iniş, sağdaki eşlenik
gradyan. Enerji fonksiyonunu kesit seviyesinden (level set), kontur (contour)
olarak gösteriyoruz, her kontur bir enerji seviyesine tekabül edecek, mesela en
dıştaki kontur 5, bir içerideki 4 olabilir, ve en ortadaki nokta tam sıfır olabilir,
çünkü en düşüktür.

3
Her iki tekniğin gidişatı resimde görülmektedir.
[gerisi atlandı]
Ekler
Üstteki anlatımda Krylov altuzaylarının eşlenik gradyan metotunun işleyişinde
tam olarak nasıl rol oynadığı belirtilmemiş. Aslında Krylov altuzayları gerek-
tirmeden bu metotu anlatmak mümkün.
İki vektör u, v birbirine A-dikgendir eğer

uT Av = 0

işe. Dikkat, bu iki vektör, tek başlarına, uT v olarak birbirine dikgen olmayabilir,
ama ortada A olduğu halde çarpım sıfır çıkarsa dikgen olmasalar da A-dikgen
olurlar. Bu dikgenliğin bir diğer ismi eşlenik (conjugate) olmaktır.
Şimdi diyelim ki elimizde herbiri birbirine dikgen olan n tane {dk } yönü / vektörü
var. O zaman dk Rn için bir baz oluşturur ve biz de Ax = b denkleminin çözümü
x∗ ’i bu bazı temel alarak temsil ederiz. Yani baz vektörlerini çarpan bazı kat-
sayılar vardır, ve bu çarpımların toplamı x∗ olur.

X
n
x∗ = αi di
i=1

Böylece Ax = b’yi çözmek için bir metot elde ediyoruz, eğer n tane eşlenik yön
bulabilirsek, α değerlerini hemen hesaplayabiliriz. Ayrıca eğer eşlenik vektörler
dk ’leri dikkatlice seçersek, yaklaşık çözüm x∗ için hepsine ihtiyacımız olmaz.
Özyineli x formülünü kullanabiliriz,

xk+1 = xk + αk dk+1 (1)

Bu formül niye mantıklı? Eğer çözüm x∗ dikgen dk vektörlerinin bir lineer kom-
binasyonu ise, çözüm vektörleri birbiri ardına dizilmiş ve “bir yere giden” bir
zincir olarak görülebilir. Üstteki formül sadece bu zinciri yavaş yavaş kurmakta..

4
İlk önce özyineli olarak artıklar rk arasında bir ilişki kuralım, (1)’nin iki tarafı A
ile çarpıp, b’den çıkartalım (çünkü ri = b − Axi ’a erişmek istiyoruz),

b − Axk+1 = b − Axk + αk Adk

rk+1 = rk + αk Adk

rk+1 = rk + αk Adk (8)

Şimdi hata terimini hesaplayalım. ei , yani i’inci tahminin hatası,

ei = x − xi

İki tarafı A ile çarpalım

Aei = Ax − Axi

Aei = b − Axi

Sağ taraf ri tanımının aynısı değil mi? O zaman

Aei = ri (5)

e’yi özyineli olarak temsil etmek te mümkündür, (1)’nin her iki tarafından x
çıkartırsam,

xk+1 − x = xk − x + αk dk

ek+1 = ek + αk dk (2)

Bu her adımı αk ’ye bağlı özyineli bir tanımdır.


α katsayılarını bulmak için bir sonraki yönden gelen hatanın önceki tüm arama
yönlerine, özelde bir önceki arama yönüne A-dikgen olmasını istiyoruz. Yani

dTi Aei+1 = 0

olmalı.

5
dTi A(xi+1 − x) = 0

dTi A(xi + αi di − x) = 0

dTi A(ei + αi di ) = 0

dTi ri + αi dTi Adi = 0

dTi ri
αi = − T (6)
di Adi

Şimdi hata terimine dönelim, diyelim ki e0 vektörü, bu vektör, diğer her vektör
gibi içinde olduğumuz uzayın bazlarının bir kombinasyonu olarak temsil edilebilir.
Bizim bazlarımız dj olduğuna göre,

X
n−1
e0 = δj d j
j=0

Katsayı olarak δj seçtik, α ile karışıklık olmasın diye. Şimdi iki tarafı dTk A ile
çarpalım,

X
n−1
dTk Ae0 = δj dTk Adj
j=0

Yine aynı dikgenlik numarası, toplam içinde j olmayan tüm diğer p çarpımları
sıfırdır,

dTk Ae0 = δj dTj Adj

dTk Ae0
δj = (4)
dTj Adj

Şimdi e0 ’in yerine (2)’teki özyineli tanımdan türeteceğim bir şey koymak istiyo-
rum. Diyelim ki e0 ’dan başlayıp teker teker bir sonraki e’yi hesaplayıp alt alta
yazdım, ve topladım

e1 = e0
 + α0 d0

6
e2 = 
 e1 + α1 d1

...

ek−1
ek =   + αk−1 dk−1

Sağ kalan tek terimler

X
k−1
ek = e0 + αj dj
j=0

(4) içinde e0 yerine koyalım

Pk−1  
dTk Aek −  αj d T
k Ad j
δj =  j=0

T
dj Adj

Niye iptal? Yine A-dikgenliği. Dikkat edilirse j’ler k − 1’e kadar çıkıyor, k’ye bile
erişmiyor, çarpım hep sıfır. Kalanlar,

dTk Aek
=
dTj Adj

(5)’i kullanırsak,

dTk rk
δj =
dTj Adj

(6) ile bu formülün benzerliği bariz, sadece eksi işareti farklı. O zaman

δk = −αk

diyebiliriz. Bu demektir ki hata formülünde α yerine δ kullanabiliriz,

X
n−1
e0 = − αj dj
j=0

Hataların özyineli denklemi (2)’yi üste uygularsak,

X
n−1
ei = − αj dj (3)
j=i

7
Şimdi artıkların ve önceki gidiş yönlerinin dikgen olduklarını gösterelim. (3)’u
dTk A ile çarpalım,

X
n−1
dTk Aei =− αj dTk Adj
j=i

X
n−1
dTk ri =− αj dTk Adj
j=i

d’ler arasındaki A-ortogonallik sayesinde ve k < i için

dTk ri = 0 (9)

Madem ki eski yönler ve artıklar birbirine dikgen, Gram-Schmidt işleminin A-


dikgen halini artıklardan yön üretmek için kullanabiliriz. Her artığı alıp, içinden
ona dikgen bir yön çıkartmak mümkün.

X
i−1
di = ri + βi,j dj (10)
j=0

rTi Adj
βi,j = −
dTj Adj

Yani Gram-Schmidt formülasyonunun A-dikgenlik kullanan hali (bkz Lineer Ce-


bir Ders 17 notları). Ama üstteki ifadeyi daha da basitleştirebiliriz, ve verimli
hale getirebiliriz. Üstteki yöntemde tüm vektörleri etrafta tutmamız gerekiyor,
ayrıca A’lardan kurtulmak iyi olur.
Kurtulmak için rTi Adj ifadesine içinde ulaşmaya çalışacağız, ve eşitliğin diğer
tarafında içinde A olmayan bir ifade olmasına gayret göstereceğiz. rTi rj+1 ile
başlayalım, ve rj+1 üzerinde özyineli denklem (8)’i uygulayalım.

rTi rj+1 = rTi (ri + αk Adk ) = rTi rj + αi rTi Adj

rTi rj+1 − rTi rj


= = rTi Adj
αj

Eşitliğin sağındaki ifadenin βi,j ifadesinin bölünen kısmı ile aynı olduğuna dikkat,
ve eşitliğin sol tarafında A yok. Yerine koyalım,

1 rTi rj+1 − rTi rj


βi,j = −
αj dTj Adj

8
j = i − 1, yani βi,i−1 için

1 rTi ri
βi,i−1 = −
αj−1 dTi−1 Adi−1

rTi rj terimi rTi ri−1 olunca sıfır oldu, çünkü artıklar birbirine dikgen. Dikkat bu
sefer dikgen, A-dikgen değil. Bunu nasıl ispat ederiz? (10)’u alıp rk ile çarpalım,
ve k, i indislerini değiştirelim

X
i−1
dTk ri = rTk ri + βk,j dTj ri = 0
j=0

Sıfıra eşitlik (9) sayesinde. Ama bu sıfır durumu toplam içindekiler için de geçerli,
çünkü toplamın üst sınırı i − 1, ve en yüksek indisli yön dj−1 olabilir, o zaman
toplam da sıfırdır. Yani

rTk ri = 0

β ile işimize devam edelim. Bölen kısmında hala bir A var, onu yokedelim. Önce
(6)’daki α tanımının i − 1 indisli haline bakalım, ve tersine çevirelim,

1 dTi−1 Adi−1
=−
αi−1 dTi−1 ri−1

Son β formülünde yerine koyalım

rT ri dT rTi ri

Ad
i−1
βi,i−1 = T i  i−1 =
di−1
  Adi−1 dTi−1 ri−1 dTi−1 ri−1

Son bir eşitlik daha var, bu da di−1 = ri−1 eşitliği, nereden geliyor? j < i − 1 için
rTi rj+1 ve rTi rj çarpımlarının ikisi de sıfırdır, o zaman (10) formülü

di = ri + βi,j dj

haline gelir çünkü pek çok değer için βi,j = 0 olacaktır. Şimdi üsttekini bir önceki
indis değerleri için tekrar yazalım,

di−1 = ri−1 + βi−1,i−2 di−2

Yine dikgenlik sayesinde β değeri iptal olur, ve geriye sadece

di−1 = ri−1

9
kalır. Böylece son formül

rTi ri
βi,i−1 =
rTi−1 ri−1

haline geliyor, ve kodlama çok temizleşiyor.

import scipy.linalg as lin

A = np.array([[6.,1.,1.],
[1.,7.,1.],
[1.,1.,8.]])

b = np.array([1.,1.,1.])

xreal = lin.solve(A, b); print "solution", xreal

p = b
r = b
x = b*0;
r2 = np.dot(r.T,r)
for i in range(5):
Ap = np.dot(A,p)
alpha = r2 / np.dot(p.T,Ap)
x = x + np.dot(alpha,p)
r = r-np.dot(alpha,Ap)
r2old = r2
r2 = np.dot(r.T,r)
beta = r2 / r2old
p = r + np.dot(beta,p)
print x

solution [ 0.13249211 0.11041009 0.09463722]


[ 0.11111111 0.11111111 0.11111111]
[ 0.13125 0.1125 0.09375]
[ 0.13249211 0.11041009 0.09463722]
[ 0.13249211 0.11041009 0.09463722]
[ 0.13249211 0.11041009 0.09463722]

10
Sayısal Entegrasyon (Numerical Integration) ve Sonlu Farklılıklar ile Sayısal Türev
(Differentiation with Finite Differences)
Sayısal Türev
Sonlu farklılıklar (finite differences) ile yaklaşık türev almak için, herhangi bir x
noktasında

f(x + ) − f(x)
f 0 (x) =

hesabını yapabiliriz. Tek boyutta tek sayı  ile adım atılıp f üzerindeki değişiklik
üzerinden hesap yapılır, çok boyutlu durumda birer birer her kordinatta  kadar
adım atılır, ve bu
 adım üzerinden
 f türevi alınıp o kordinat için kısmı türev olarak
kaydedilir, x = x0 ... xn için

   
f [ x0 +  ... xn ] −f(x)
  
0
f (x) = 
 .. 
 
. 


f [ x0 ... xn +  ] −f(x)


Alttaki kod [3]’teki approx_fprime metotunu baz almıştır,

eps = np.sqrt(np.finfo(float).eps)

def _approx_fprime_helper(xk, f, epsilon):


f0 = f(xk)
grad = np.zeros((len(xk),), float)
ei = np.zeros((len(xk),), float)
for k in range(len(xk)):
ei[k] = 1.0
d = epsilon * ei
df = (f(xk + d) - f0) / d[k]
if not np.isscalar(df):
try:
df = df.item()
except (ValueError, AttributeError):
raise ValueError("The user-provided "
"objective function must "
"return a scalar value.")
grad[k] = df
ei[k] = 0.0
return grad

Test olarak optimizasyonda bolca kullanılan Rosenbrock fonksiyonunu kullan-


abiliriz. Altta hem analitik olarak hem de sayısal olarak hesaplanmış türev sonuçlarını
görebiliyoruz,

rosen = lambda x: (1-x[0])**2 + 100*(x[1]-x[0]**2)**2

1
def rosen_d(x):
return np.array([2*100*(x[1] - x[0]**2)*(-2*x[0]) - 2*(1.-x[0]), 2*100*(x[1]-x[0]*

x = [0.5, 0.5]
res = _approx_fprime_helper(x, rosen, eps)
print ('analitik', res, 'sayisal', rosen_d(x))

x = [-0.5, 0.5]
res = _approx_fprime_helper(x, rosen, eps)
print ('analitik', res, 'sayisal', rosen_d(x))

analitik [-50.99999928 50.00000149] sayisal [-51. 50.]


analitik [47.00000072 50.00000143] sayisal [47. 50.]

Sayısal Entegrasyon
Trapezoid Bazlı
F(x) fonksiyonunu bazen sembolik olarak entegre etmek zor olabilir. Bu durum-
larda sayısal çözüm daha kullanışlı olabilir. Mesela F(x)’in x0 ve x1 arasındaki en-
tegrali aslında bir alan hesabıdır, ve bu alanı, x aralığını ufak parçalara bölerek,
ve bu parçaları kullanarak yaklaşık bir alan hesabı yapıp sonuçları toplayarak
elde edebiliriz.
x0 ve x1 arasını N parçaya bölelim.
Artık entegrali yaklaşık olarak

Z x1 X
N
F(x) dx ≈ F(xi )
x0 i=1

hesaplayabiliriz. N arttırıldıkça dikdörtgenler daha fazlalaşacak, ve gerçek alana


daha fazla yaklaşacağız.
Üstteki metot Euler’in metotu olarak biliniyor, ve anlatması, kodlaması en rahat
olan yöntem bu. Bir diğer yöntem, trapezoid yöntemi olarak bilinir, ve daha iyi
yaklaşıksal yeteneğinin olduğu bilimektedir. Bu yöntemle pek çok dikdörtgen
alanı yerine pek çok trapezoid alanı hesaplıyoruz [1, sf. 279].

2
X
N
1
∆x [F(xi ) + F(xi+1 )]
i=1
2

Bu formül iki kenarı a, b olan ve genişliği ∆x olan trapezoid’in alanının 1/2(a +


b)∆x olmasından ileri geliyor.
Örnek
F(x) = 3xe−0.7x ’in x0 = 0.5 ve x1 = 5 arasındaki entegralini hesaplayalım,
Rutin trapz ile bunu yapabiliriz,

x = np.linspace(0.5,5.0,1000)
y = 3.0*x*np.exp(-0.7*xval)
W = np.trapz(y,x=x)
print (W)

4.99249134896902

Trapezoidsel hesabı elle yapmak isteyenler için bazı kolaylaştırıcı ek formüller [2,
sf. 605] alttadır,

3
Trapezoidsel entegral T ve yi = f(xi ) için

1 1 1 1
T = (y0 + y1 )∆x + (y1 + y2 )∆x + ... + (yn−2 + yn−1 )∆x + (yn−1 + yn )∆x
2 2 2 2

1 1
= ∆x( y0 + y1 + y2 + ... + yn−1 + yn )
2 2

∆x
= (y0 + 2y1 + 2y2 + ... + 2yn−1 + yn )
2

Örnek
R2
n = 4 ile 1 x2 dx hesabını yapalım.
∆x = 1/4 olur,

∆x
T= (y0 + 2y1 + 2y2 + 2y3 + y4 )
2

1 25 36 49
= (1 + 2( ) + 2( ) + 2( ) + 4)
8 16 16 16

75
= = 2.34375
32

Çağrı trapz ile

x = np.linspace(1.0,2.0,4)
y = x**2
T = np.trapz(y,x=x)
print (T)

4
2.351851851851852

Üstteki hesap tabii ki analitik şekilde de çok rahat yapılabilir,

Z2 2
2 x3 8 1 7
x dx = = − =
1 3 1 3 3 3

print (7./3)

2.3333333333333335

Kaynaklar
[1] Sorenssen, Elementary Mechanics Using Python
[2] Thomas, Thomas’s Calculus
[3] Scipy, https://github.com/scipy/scipy/blob/master/scipy/optimize/
optimize.py

5
İki Nokta Sınır Değerli Problemler (Two-Point Boundary Value Problems -TPBVP-
)
BVP problemleri şu genel formda olan problemlerdir [1, sf. 287],

x 00 (t) = f(t, x(t), x 0 (t)))

x(t0 ) = x0 , x(tf ) = xf

İkinci satır sınır şartlarını belirtiyor, zaman için t0 , t1 , ...tf indisleri kullanılır, yani
sistemin konumu x(t)’in başlangıçta x0 bitişte xf noktasında olması isteniyor (bun-
lar gerçek tek sayı değerleri olacak). Bilinmeyen bir başlangıç şartı var, bu x 0 (0)
şartı, diyelim x 0 (0) = z. Bilinmeyen z’yi nasıl bulacağız? Genel yaklaşım olarak
bilinen az sayıda değişkeni ileri doğru entegre ederek sonda gelinen noktaya
bakılır, eldeki kısmı son nokta verisiyle karşılaştırılarak bir hata üzerinden başlangıç
düzeltilmeye uğraşılır, bu özyineli şekilde devam eder. Çözüm yöntemi olarak
ateş etme yöntemi (the shooting method) vardır, farklı paketler farklı yaklaşımlar
kullanabilir.
Paket İle

dy Sy
= f(x, y, p) +
dx x−a

a 6 x 6 b, bc(y(a), y(b), p) = 0

ki x tek boyutlu bağımsız değişken, y(x) n-boyutlu vektör değerli fonksiyon, p


k boyutlu bilinmeyen parametrelerin vektörü, ki onu y(x)’yi bulurken aynı anda
bulmak gerekiyor. bc ile sınır şartları tanımlanıyor.
Bratu Problemi
Paket çözümleri de kullanılabilir [2, sf. 396]. Mesela scipy. Bratu problemi

y 00 + k + exp(y) = 0

y(0) = y(1) = 0

Bu sistemi 1. derece bir denklemler sistemine değiştirelim,

y10 = y2

y20 = − exp(y1 )

1
def fun(x, y):
# k=1 farz edildi
return np.vstack((y[1], -np.exp(y[0])))

def bc(ya, yb):


return np.array([ya[0], yb[0]])

x = np.linspace(0, 1, 5)

Çağrı bc içinde sınır şartlarının artığı, hatası döndürülüyor. Daha doğrusu bc’ye
verilen iki parametre içinde başta ve sonda olmak üzere y = [y1 , y2 ] formatında
artık değerler var. Bu artıklardan hangisinin belirlediğimiz sınır şartına ait olanı
biz seçiyoruz. Mesela ya[0] ve yb[0] ile içinde y1 ’in başta ve sondaki değerini
seçmiş oluyoruz, ki zaten problemin sınır şartları onlar üzerinden tanımlanmıştı.
Eğer y10 , yani y2 üzerinde bir son şart olsaydı o zaman yb 1. indisteki değeri
döndürürdük. Ayrıca artıkler hep sıfıra eşitlik üzerinden tanımlanır, eğer y1 (0) =
k gibi bir sınır değeri var ise, ya[0] − k döndürmemiz gerekir.
Bu problemin iki farklı çözümü var. Her iki çözümü de elde etmek için y için
farklı başlangıç noktaları deneyeceğiz, bu seçenekleri 1 ve 2 olarak işaretleyelim,

y_1 = np.zeros((2, x.size))


y_2 = np.zeros((2, x.size))
y_2[0] = 3

from scipy.integrate import solve_bvp


res_1 = solve_bvp(fun, bc, x, y_1)
res_2 = solve_bvp(fun, bc, x, y_2)

x_plot = np.linspace(0, 1, 100)


y_plot_1 = res_1.sol(x_plot)[0]
y_plot_2 = res_2.sol(x_plot)[0]

plt.plot(x_plot, y_plot_1, label='y_a')


plt.plot(x_plot, y_plot_2, label='y_b')
plt.legend()
plt.xlabel("x")
plt.ylabel("y")
plt.savefig('compscieng_app10boundary_03.png')

2
Top Atışı Metotu (Shooting Method)
Bir diğer çözüm yöntemi top atışı (silah anlamında) problemidir, güllenin nere-
den atıldığı bilinir, düşmesi istenen bir yer vardır, ama hangi açıyla (burada x 0 (0))
yukarı doğru tutulacağı bilinmez.

Bilinmeyen başlangıç şartlarından birini bulmak için bir yöntem tüm bilinenleri
kullanıp, bilinmeyen için bir tahmin yerine koymak, ve bu sistemi entegre ed-
erek sonuca gelmek. Sonuca gelindiğinde xf ’e ne kadar yakın olunduğuna göre
bir hata gradyanı oluşturup bu gradyanı x 0 (0)’te düzeltme yapmak için kullan-
mak, ve süreci tekrarlamak. Bu işlem ardı ardına yapılır ve istenen bitiş değerine
gelince durulur. Bu yönteme ilham aldığı temel örnekten hareketle atış metotu
(the shooting method) adı veriliyor.
Gradyanı hesaplamak ve düzeltmede kullanmak için Sekant Yöntemini kullan-
abiliriz [10]. Hata fonksiyonu z’nin fonksiyonudur,

e(z) = x(tf ) − xf

İstediğimiz e(z)’nin minimal olması, yani sıfıra eşit olması, e(z) = 0. Bu durumda
bir kök bulma problemi ortaya çıkıyor,

e(zn )
zn+1 = zn − de(zn )
dzn

3
Sekant yöntemi için

e(zn )
zn+1 = zn −
e(zn ) − e(zn−1 )
zn − zn−1

Örnek

x 00 (t) = 2x2 (t) + 4tx(t)x 0 (t)

1 1
x(0) = , x(1) =
4 3

Bu problemin analitik çözümü aslında biliniyor,

1 2t
x(t) = , x 0 (t) = = 2tx2 (t)
4 − t2 (4 − t2 )2

Ama bilmeseydik nasıl çözerdik? Alttaki gibi. Önce x10 (t) için yeni bir değişken
tanımlayalım, x10 (t) = x2 (t) olsun, o zaman x20 (t) ana ODE denklemimiz olabilir,
çok boyutlu olarak

x10 (t)
   
x2 (t)
=
x20 (t) 2x21 (t) + 4t · x1 (t)x2 (t)

Sınır şartları

   
x1 (0) x0 = 1/4
=
x2 (0) xf = 1/3

Kod,

import scipy as sp import numpy.linalg as lin from


scipy.integrate.odepack import odeint

def rhs(u,t):
x1, x2, = u
return [x2, (2*x1 + 4*t*x2)*x1]

def bvp_shoot(t0,tf,x0,xf,N,tol,kmax):
dx0 = np.zeros(kmax)
e = np.zeros(kmax)
dx0[0]= (xf-x0)/(tf-t0);
t=np.linspace(t0,tf,100.0)
for k in range(1,kmax-1):
x=odeint(rhs,[x0, dx0[k]], t)

4
e[k]=x[-1,0]-xf
ddx= dx0[k]-dx0[k-1]
if np.abs(e[k])<tol or np.abs(ddx)<tol: break
deddx= (e[k]-e[k-1])/ddx;
dx0[k+1] = dx0[k]-e[k]/deddx;
return t, x

t0 = 0.; tf = 1.; x0 = 1/4.; xf = 1/3.;


N = 100.; tol = 1e-8; kmax = 10;

t,x = bvp_shoot(t0,tf,x0,xf,N,tol,kmax)
xo = 1.0 /(4.0 - t**2); err = lin.norm(x[:,0] - xo)/(N + 1.0)

plt.plot(t,x[:,0],'g') # bizim hesap


plt.plot(t,xo,'--r') # analitik bilinen
plt.savefig('compscieng_app10boundary_01.png')

Grafikte görüldüğü gibi iki çözüm birbirinin tıpkı aynısı.


Sturm-Liouville
Yine paket ile devam edelim. Sturm-Liouville adlı bir problemi çözelim,

y 00 + ky = 0

y(0) = y(1) = 0

Bu problemin n bir tam sayı olmak üzere k = nπ için bariz / önemsiz olmayan bir
çözümünün y = A sin(kx) olduğu biliniyor. A = 1 ile normalizasyon sağlamak
için bir sınır şart daha ekliyoruz,

y 0 (0) = k

Çünkü y = A sin(kx) → y 0 = Ak cos(kx), ve y 0 (0) dersek y 0 (0) = Ak cos(0)) =


Ak olacaktır, o zaman y 0 (0) = k şartını koyarsak A = 1’i zorlamış oluruz.

5
1. derece sisteme çevirirsek,

y10 = y2

y20 = −k2 y1

Ayrıca kπ için bir çözüm aradığımız için y değerlerinin aşağı yukarı sin(2πx)’yi
takip etmesini sağlıyoruz,

from scipy.integrate import solve_bvp

def fun(x, y, p):


k = p[0]
return np.vstack((y[1], -k**2 * y[0]))

def bc(ya, yb, p):


k = p[0]
return np.array([ya[0], yb[0], ya[1] - k])

x = np.linspace(0, 1, 5)
y = np.zeros((2, x.size))
y[0, 1] = 1
y[0, 3] = -1

sol = solve_bvp(fun, bc, x, y, p=[6])


print (sol.p)

[6.2832946]

k’nin aşağı yukarı doğru değerde olduğunu görüyoruz. Tüm çözümü grafikley-
ince beklenen sinüs eğrisini de göreceğiz,

x_plot = np.linspace(0, 1, 100)


y_plot = sol.sol(x_plot)[0]
plt.plot(x_plot, y_plot)
plt.xlabel("x")
plt.ylabel("y")
plt.savefig('compscieng_app10boundary_04.png')

6
Bilinmeyen Sabit Durumları
Her TPBVP problemi üstte görülen yazılımlara direk, olduğu gibi aktarılacak du-
rumda olmayabilir. Ama bu problemleri de bazı numaralar kullanarak çözüm
yazılımının beklediği hale çevirebiliriz.
Mesela çoğu sınır değeri problemi bilinmeyen sabitler içerirler, ki çözüm içi bu
sabitlerin bilinmesi gereklidir. Bu tür problemler üstteki yöntemlerle direk çözülemez.
Ama bilinmeyen sabitleri de birer değişken olarak kabul edersek, bu engelin
etrafından dolaşabiliriz. Bu “değişkenin” ilk türevi tabii ki sıfır olacaktır, ve bu
türevin sıfıra eşit olma hali üzerinden sabiti diferansiyel denklem sistemimize
dahil edebiliriz.
Elastiklik (elastica) problemi mekanik alanında standart bir problem [3, sf. 221, 4,
pg. 87]. İki ucundan kuvvet uygulanan bir esnek çubuğun nasıl büküldüğünü
modelliyor. Sabiti dahil etmeden ana sistem şöyle,

x 0 = cos(φ)

y 0 = sin(φ)

φ0 = κ

κ 0 = F cos(φ)

Bilinmeyen sabit F. Sınır değerleri,

x(0) = 0

y(0) = 0

7
κ(0) = 0

y(0.5) = 0

φ(0.5) = −π/2

Görülen beş tane sınır değişkeniyle aslında problemi tamamen tanımlanmış oluyor.
Entegrasyondan ortaya çıkan dört tane sabit olacak, üstte beş tane değer var.
Hatta F’yi de bir sınır değeri olarak dahil edince hala çözüm için yeterli öğe elim-
izde oluyor. Yeni sınır değeri

F0 = 0

Dikkat, yani F’nin türevi her yerde sıfır olmalı (çünkü sabit).

# x,y,\phi,\kappa, F
from scipy.integrate import solve_bvp

def fun(x, y):


return np.vstack(( np.cos(y[2]),
np.sin(y[2]),
y[3],
y[4]*np.cos(y[2]),
np.zeros(x.shape[0]) ))

def bc(ya, yb):


return np.array([ ya[0],
ya[1],
ya[3],
yb[1],
yb[2]+(np.pi/2) ])

x = np.linspace(0, 0.5, 400)


y = np.zeros((5, x.size))
sol = solve_bvp(fun, bc, x, y)
print (sol.y[4,0])

-21.54910449259776

F sabitinin degeri ustte goruluyor.


Dikkat edilirse fun içinde F’ye sıfır değeri vermek için np.zeros(x.shape[0])
değeri tanımlandı, yani bir sıfır vektörü tanımlandı.
Çözüm sonucu elde edilen y değerlerini grafikleyelim,

plt.plot(x,sol.y[1])
plt.title('y')
plt.savefig('compscieng_app10boundary_05.png')

8
Kızamık (Measles) Problemi
Problem [3, sf. 223, 5, 6, 7, sf. 13]’de görülebilir, nüfusta bir salgının yayılması
modellenmiştir. Nüfus dört farklı grup altında incelenir, bu gruplar bağışıklı
olanlar (immunes), I, bağışıksızlar (susceptible) S, bulaştırmayan hasta (latents)
L, ve bulaştıran hasta (infectives), I. Toplam nufus sabit N olsun, o zaman

S(t) + I(t) + L(t) + M(t) = N, t ∈ [0, 1]

Model her grubun izafi oranını bağışıksızlar y1 = S/N, bulaştırmayan hasta y2 =


L/N, ve hasta olanlar y3 = I/N olarak tanımlar. Hastalığın yayılma dinamiği
şöyle tanımlanabilir,

y10 = µ − βy1 y3

y20 = βy1 y3 − y2 /λ

y30 = y2 λ − y3 /η

β bulaştırma oranı (sabiti). Bulaştırma oranını sezona bağlı olabileceği için onu
bir kosinüs fonksiyonu ile tanımlarız,

β = β0 (1 + cos(2πt))

ki β0 = 1575, diğer sabitler ise µ = 0.02, λ = 0.0279, η = 0.01. Sinir sartlari

y(1) = y(0)

Tabii y bir vektör, y = [y1 , y2 , y3 ]. Bu sınır şartının tanımlanmasının sebebi periyo-


dik bir çözüm arıyor olmamız. Bu tür sınır şartı biraz garip olabilir, ve her sayısal

9
paket bu tür şartın tanımlanmasına izin vermeyebilir, fakat scipy izin veriyor.
Verilmiyorsa [3] kaynağında anlatılan ekstra değişkenler ve sabit tanımlama nu-
marasını kullanmak gerekiyor.

from scipy.integrate import solve_bvp

mu = 0.02
l = 0.0279
eta = 0.01
def fun_measles(x, y):
beta = 1575 * (1 + np.cos(2 * np.pi * x))
return np.vstack((
mu - beta * y[0] * y[2],
beta * y[0] * y[2] - y[1] / l,
y[1] / l - y[2] / eta
))

def bc_measles(ya, yb):


return ya - yb

x_measles = np.linspace(0, 1, 5)
y_measles = np.full((3, x_measles.shape[0]), 0.01)

res_measles = solve_bvp(fun_measles, bc_measles, x_measles, y_measles)

plt.figure(figsize=(14, 5))
x_measles_plot = np.linspace(0, 1, 100)
y_measles_plot = res_measles.sol(x_measles_plot)
plt.subplot(131)
plt.plot(x_measles_plot, y_measles_plot[0], label='$y_1$')
plt.subplot(132)
plt.plot(x_measles_plot, y_measles_plot[1], label='$y_2$')
plt.subplot(133)
plt.plot(x_measles_plot, y_measles_plot[2], label='$y_3$')
plt.savefig('compscieng_app10boundary_06.png')

Sinir Sistemi Tepkisi (Nerve Impulse)


Tekrar eden sınır şart durumunu bilinmeyen entegral limiti durumu ile birleştiren
bir problemi göreceğiz şimdi [8, sf. 27, 3, sf. 225, 6, 5, sf. 173]. Bilinmeyen sınır

10
şartı için bir numara yapabiliriz; Yeni bir değişken τ tanımlıyoruz, ve bu değişken
sadece [0, 1] aralığına kısıtlanıyor. Bağımsız değişken x. Şimdi τ = t/b, ki b bilin-
meyen entegral sınırı,

dy
= f(t, y)
dx
yerine

dy
= bf(t, y)

db
=0

Bu nasıl oldu?
t = τb ise dx/ dτ = b.

dy dy dt
= = bf(x, y)
dτ dt dτ

Problem sorusuna gelelim. Diyelim ki hücre zar potansiyeli y1 , geçirgenlik y2 , ve

y10 = 3(y1 + y2 − 1/3y31 − 1.3)

y20 = −(y1 − 0.7 + 0.8y2 )/3

Bu problem [0, T ] zaman diliminde tanımlanmıştır. Fakat bir problem şu, T ’nin ne
olduğunu bilmiiyoruz, ve aynı T bilinmeyeni sınır şartlarının tanımlanmasında
kullanılmış.

y1 (0) = y1 (T ), y2 (0) = y2 (T )

Ana denklem,

y10 = 3T (y1 + y2 − 1/3y31 − 1.3)

y20 = −T (y1 − 0.7 + 0.8y2 )/3

Böylece problem [0, 1] arasında tanımlanmış oldu. Sınır şartları böylece t = 0, 1


üzerinden tanımlanabilir. Fakat üçüncü bir sınır şartı daha lazım. Farklı bir

11
açıdan eğer çözüm parçalarından birine bir değer atamak, mesela y1 (0) = 0. O
zaman y1 (0) = y1 (T ) yerine y1 (T ) = 0 da kullanabiliriz. Böylece sınır şartları,

y1 (0) = 0, y1 (1) = 0, y2 (0) = y2 (1)

haline geldi. Bu problemi ekstra parametre seçeneğini kullanarak, bölmeden


(non-seperated) halde çözebiliriz [9, sf. 173].

from scipy.integrate import solve_bvp

def fun(x, y, p):


T = p[0]
return np.vstack((
3.0 * T * (y[0] + y[1] - (y[0]**3)/3.0 - 1.3),
-T / 3.0 * (y[0] - 0.7 + 0.8*y[1])
))

def bc(ya, yb, p):


return np.array( [ ya[0], yb[0], ya[1]-yb[1] ] )

x = np.linspace(0, 1, 5)
y = np.zeros((2, x.size))
y[0] = np.sin(2 * np.pi * x)
y[1] = np.cos(2 * np.pi * x)
sol = solve_bvp(fun, bc, x, y, p=[2*np.pi])
print (sol.p)

[10.71071556]

Üstteki T değeri [9]’da bulunan ile aynı.


Kaynaklar
[1] Yang, Applied Numerical Methods using Matlab
[2] Scipy, Scipy Reference, 0.18.1
[3] Cash, Solving Differential Equations in R
[4] Greenhill, The applications of elliptic functions
[5] Shampine, A BVP Solver Based on Residual Control and the Matlab PSE, http:
//www.orcca.on.ca/TechReports/TechReports/2001/TR-01-02.pdf
[6] Mayorov, Github, https://gist.github.com/nmayorov/f8af5ca956c6a7f75ecdb578
[7] Ascher, Numerical Solution of BVPs for ODEs
[8] Seydel, From equilibrium to chaos
[9] Shampine, Solving ODEs in Matlab
[10] Bayramli, Diferansiyel Denklemler, Kök Bulmak

12
Isı Denklemi (Heat Equation)

∂u ∂2 u
=
∂t ∂x2

olarak gösterilen denklem fizikte ısı denklemi olarak bilinir [1], u fonksiyonu iki
değişkenlidir u(x, t). Örnek için bu denklemin çözümünü tek boyutta göstereceğiz,
yani bir genişliği önemli olmayan bir demir çubuğu üzerinde ısının dağılması
konusuna bakacağız, boyutu temsil için x değişkeni kullanılacak. t değişkeni
zamanı temsil ediyor olacak. Başlangıç şartları (initial conditions) olarak ısının
t=0 anında demir çubuk üzerinde x’e bağlı bir sinüs fonksiyonu ile dağıldığını
farzedeceğiz, sınır şartları ise (boundary conditions) çubuğun iki ucunun sıfır
derecede tutulması olacak. Sonuçta ısının nereye gideceğini tahmin ederek te
söyleyebiliriz – ısı demirin iki ucundan kaçarak tüm çubuk boyunca sıfır derec-
eye inecektir.
Üstteki denklem bir kısmi diferansiyel denklemdir (partial differential equation).
Elimizde model olarak bir diferansiyel denklem varsa çözüm bulmak demek
bir fonksiyon bulmak demektir, bir sayı değil. Ayrıca çözüm için analitik değil
yaklaşıksal bir metot kullanacağız; yani öyle bir u fonksiyonu bulacağız ki, test /
belli noktalarda gerçek fonksiyonla olabildiğince aynı sonuçlar verecek.
Çözümde sınırlı farklar (finite differences) denen bir metot kullanılacak. Bu yaklaşıksal
metotta calculus’un sonsuz ufaklıklar için kullanılan türevleri, bildiğimiz sayısal
çıkartma işlemi üzerinden tanımlanan “farklılıklara” dönüşecekler. Mesela d2 /dx2
nedir? x’e göre türevin türevidir, hesapsal olarak ise farkın farkıdır. Sonsuzluktan
yaklaşığa şöyle geçeriz: Eğer uj,i bir 2 boyutlu dizin üzerinde u fonksiyonunun
sayısal değerlerini taşıyor olsaydı, ve j, i indis değerleri t, x’i temsil ediyorlar ise,
x üzerinden birinci türev yani birinci fark (first difference) şöyle olur:

uj,i+1 − uj,i
h

h hangi değişkenin farkını alıyorsak, o farkın büyüklüğünü tanımlayan aralık


değeridir, h = ∆x, ve uj,ı+1 = u(t, x + ∆x).
İkinci fark, farkın farkıdır:
   
1 uj,i+1 − uj,i uj,i − uj,i−1

h h h

uj,i+1 − 2uj,i + uj,i−1


= (1)
h2

Bu çarpımı tüm i değerleri için ve matris üzerinden temsil etmenin yolu şudur:
Bir ikinci farklılıklar matrisi A yaratırız:

1
 
−2 1 0 0...0 0 0
 1 −2 1 0...0 0 0
1 
.. .. .. .. ..

..
A=
 
∆x2

 . . . . . .


 0 0 0 0 . . . 1 −2 1 
0 0 0 0 . . . 0 1 −2

Ve u değerlerini bir vektör içine çekeriz:


 
uj,0

 uj,1 

Uj = 
 uj,2 

 .. 
 . 
uj,n

AUj çarpımının (1) denklemindeki toplamları her u için teker teker vereceğini
görebiliriz. İndislerden j zaman, i mesafedir, yani üstteki denklem şimdilik sadece
mesafeyi yani x’i parçalara bölmüştür.
Zamanı da modele dahil edelim ve çözümü elde etmeye uğraşalım. Isı den-
kleminin tamamını şimdiye kadar elde ettiklerimizi kullanarak ve ayrıksal olarak
yazalım:

Uj+1 − Uj
= AUj (2)
∆t
∂2 u
∂x2
≈ AUj , ve ∂u
∂t
≈ (Uj+1 − Uj )/∆t olarak alındı. Uj tanımındaki j indisi zaman
için kullanılıyor, mesafe yani x’i temsil eden indislerin tamamı U’nun içinde var
zaten.
Yaklaşıksal tekniklerden Crank-Nicholson’a göre AUj ’i ardı ardına iki zaman in-
disi üzerinden hesaplanan bir ortalama olarak temsil edebiliriz, yani

1
AUj ≈ (AUj+1 + AUj )
2
Niye bu açılım yapıldı? Çünkü elimizde Uj+1 ve Uj değerleri var, bu değerleri
tekrar ortaya çıkararak bir ”denklem sistemi” yaratmış olacağız, iki bilinmeyen
için iki formül yanyana gelebilecek ve çözüme erişilebilecek.
Üstteki formülü (2) denklemindeki AUj değerleri için kullanalım ve tekrar düzenleyelim.

∆t ∆t
AUj+1 + AUj = Ui+1 − Ui
2 2

∆t ∆t
Ui+1 − AUj+1 = Ui + AUj
2 2

2
∆t ∆t
(I − A)Uj+1 = (I + A)Ui
2 2

Artık bu formülü lineer cebirden bilinen Ax = b formuna sokarak çözebiliriz.


Forma göre formülün sağ tarafı b olur, sol tarafta parantez içi A olacak, Uj+1 ise
bilinmeyen x olacak (bizim x’ten farklı). Hesapsal kodlar bir döngü içinde, her
zaman dilimi için bilinmeyen Uj+1 değerini bulacak. Döngünün sonunda yeni
Uj+1 eski Uj olacak ve hesap devam edecek.
Sınır Şartları
Her iki uçta u’nun sıfır olma şartı uygulamalı matematikte Dirichlet sınır şartı
olarak biliniyor. Bu şart A matrisinin oluşturulması sırasında kendiliğinden oluşuyor.
Ufaltılmış bir matris üzerinde göstermek gerekirse,

 
1 −2 1 0 0
 0 1 −2 1 0 
0 0 1 −2 1

değerlerinin her satırının (1) denklemini temsil ettiğini söylemiştik. Eğer şartlarımızdan
biri u1 ve u5 ’un sıfır olması ise, çarpım sırasında ona tekabül eden üstteki matrisin
en soldaki ve en sağdaki kolonlarını tamamen sıfır yapmamız yeterli olurdu,
çünkü çarpım sırasında Uj içinde o kolonlar u1 ve u5 ile çarpılıp onu sıfır ya-
parlardı. O zaman yeni matris şöyle olurdu:

 
0 −2 1 0 0
 0 1 −2 1 0 
0 0 1 −2 0

Bu işler. Alternatif olarak sıfır kolon yerine, o kolonları tamamen matristen ata-
bilirdik, aynı şekilde u değerlerini üretirken birinci ve sonuncu değerleri de at-
mamız gerekirdi, nasıl olsa onlar ”bilinmeyen” değişken değiller. Bu yeni matris
şöyle olurdu:

 
−2 1 0
 1 −2 1 
0 1 −2

Alttaki kod içinde x = x[1:-1] ibaresi x ve dolaylı olarak u’nun ilk ve son değerlerini
atmak için kullanılmakta.
Seyrek (sparse) matrisler kullanarak çözüm altta.

"""
This program solves the heat equation
u_t = u_xx
with dirichlet boundary condition

3
u(0,t) = u(1,t) = 0
with the Initial Conditions
u(x,0) = 10*sin( pi*x )
over the domain x = [0, 1]

The program solves the heat equation using a finite difference


method where we use a center difference method in space and
Crank-Nicolson in time.
"""
import scipy as sc
import scipy.sparse as sparse
import scipy.sparse.linalg
f, ax = plt.subplots()

# Number of internal points


N = 200

# Calculate Spatial Step-Size


h = 1/(N+1.0)

# Create Temporal Step-Size, TFinal, Number of Time-Steps


k = h/2
TFinal = 1
NumOfTimeSteps = 120

# Create grid-points on x axis


x = np.linspace(0,1,N+2)
x = x[1:-1]

# Initial Conditions
u = np.transpose(np.mat(10*np.sin(np.pi*x)))

# Second-Derivative Matrix
data = np.ones((3, N))
data[1] = -2*data[1]
diags = [-1,0,1]
D2 = sparse.spdiags(data,diags,N,N)/(h**2)

# Identity Matrix
I = sparse.identity(N)

# Data for each time-step


data = []

for i in range(NumOfTimeSteps):
# Solve the System:
#
# (I - k/2*D2) u_new = (I + k/2*D2)*u_old
#
A = (I -k/2*D2)
b = ( I + k/2*D2 )*u
u = np.transpose(np.mat(sparse.linalg.spsolve(A, b)))
if i % 20 == 0:
plt.plot(x, u)

4
plt.axis((0,1,0,10.1))
plt.savefig("heat-" + str(i))
plt.hold(False)

5
Seyrek matrislerden olmadan, normal matris kullanarak olan çözüm altta.

import scipy.linalg
f, ax = plt.subplots()

# Number of internal points


N = 200

# Calculate Spatial Step-Size


h = 1/(N+1.0)
k = h/2

x = np.linspace(0,1,N+2)
x = x[1:-1] # get rid of the '0' and '1' at each end

# Initial Conditions
u = np.transpose(np.mat(10*np.sin(np.pi*x)))

# second derivative matrix


I2 = -2*np.eye(N)
E = np.diag(np.ones((N-1)), k=1)
D2 = (I2 + E + E.T)/(h**2)

I = np.eye(N)

TFinal = 1
NumOfTimeSteps = 100

for i in range(NumOfTimeSteps):
# Solve the System:
# (I - k/2*D2) u_new = (I + k/2*D2)*u_old
A = (I - k/2*D2)
b = np.dot((I + k/2*D2), u)
u = scipy.linalg.solve(A, b)
if i % 20 == 0:
plt.plot(x, u)
plt.axis((0,1,0,10.1))
plt.savefig("heat-2-" + str(i))
plt.hold(False)

6
Kaynaklar
[1] Bayramlı, Fizik, Isı Denklemi

7
Dalga Denklemi (Wave Equation)
Denklem [1],

∂2 y 1 ∂2 y
= 2 2
∂x2 c ∂t

Denkleme yakından bakarsak onun bir kısmı türevsel denklem (PDE) olduğunu
görürüz. İki tane bağımsız değişken temel alınıyor, x, t. Ayrıca denklem 2. derece,
çünkü ikinci türevi içeriyor. Bu bilgiler denklemi çözmek için önemli [2].
Çözümde bir başlangıç şartı gerekli çünkü diferansiyel denklemleri “entegre ed-
erken” daha doğrusu ileri doğru geçen zamanda hesaplarken bir başlangıç nok-
tası gerekiyor, bunun için bir teli kaldırıp (geçici bir süre üçgen haline getirip)
oradan bıraktığımızı düşünebiliriz, ki bu üçgen şekli alttaki gibi modellenebilir,

1.25x/L, x 6 0.8L,
y(x, t = 0) =
(5 − 5x/L), x > 0.8L,

İkinci bir başlangıç şartı daha lazım, 2. derece başlangıç şartı bu. Teli, ipi gerip
üçgen yaptım ama sonra durup tekrar bıraktım, bu da bir başlangıç şartı, durağan
durumdan başlama şartı.

∂y
(x, t = 0) = 0
∂t

Çözüme bu şartlarla başlayabilirdik ama baştaki problem tanımını hatırlarsak ek


bazı şartlar daha koymuştuk, bu şartlar, kısıtlamalar her an için geçerli, ipler iki
ucundan (hareket etmeyen) duvarlara bağlı.

y(0, t) ≡ 0, y(L, t) ≡ 0

[analitik çözüm atlandı]


Yaklaşıksal hesap için x, t eksenleri düşünebiliriz, ve bu eksenlerde sadece belli
noktalardaki hesaplar yapılacak, x için aralıklar ∆x genişliğinde, t için ∆t genişliğinde,
aralık büyüklüğünü biz tanımlayacağız. Yani hesap noktaları i = 1, 2, 3, ... için
i∆t’de, x için j = 1, 2, .. ile j∆t’de.

1
Yaklaşıksallıkta bir diğer kullanılacak teknik merkezi farklılıklar, burada x için
sola/sağa, t için yukarı/aşağı olacak şekilde iki Taylor açılımı yapıyoruz,

∂U 1 ∂2 U
y(x + ∆x, t) = y(x, t) + ∆x + (∆x)2 + · · ·
∂x 2 ∂x2

∂U 1 ∂2 U
y(x − ∆x, t) = y(x, t) − ∆x + (∆x)2 − · · ·
∂x 2 ∂x2

∂U 1 ∂2 U
y(x, y + ∆t) = y(x, t) + ∆y + (∆t)2 + · · ·
∂t 2 ∂t2

∂U 1 ∂2 U
y(x, y − ∆t) = y(x, t) − ∆t + (∆t)2 − · · ·
∂t 2 ∂t2

Noktalı yerlerdeki terimleri yok sayıyoruz (2. derece yaklaşıklama yapmış olduk
yani, bu önemli, yaklaşık temsilin kuvvetini gösteriyor bir anlamda), sonra her
değişkenin iki açılımını birbiri ile topluyoruz. Toplama sonrası tek sayı terim-
lerinin iptal olduğunu görürüz, ve kalanlar,

∂2 y(x, t) y(x + ∆x, t) + y(x − ∆x, t) − 2y(x, t)


2
'
∂x (∆x)2

∂2 y(x, t) y(x, t + ∆t) + y(x, y − ∆t) − 2y(x, t)


2
'
∂t (∆t)2

olacaktır. İndisler üzerinden belirtirsek,

∂2 y yi,j+1 + yi,j−1 − 2yi,j ∂2 y yi+1,j + yi−1,j − 2yi,j


2
' , ' .
∂t (∆t)2 ∂x 2 (∆x)2

2
Üstteki formülleri dalga denklemindeki yerlerine koyarsak,

yi,j+1 + yi,j−1 − 2yi,j yi+1,j + yi−1,j − 2yi,j


2 2
= (2)
c (∆t) (∆x)2

Tabii dikkat edersek geçmiş j − 1 ve gelecek j + 1 birbirine karışmış durumda,


bize lazım olan geleceğin hesabının eşitliğin sol tarafında olması geri kalan her
şey sağda olacak şekilde tekrar düzenlersek,

c2 ∆x
yi,j+1 = 2yi,j − yi,j−1 + [yi+1,j + yi−1,j − 2yi,j ] , c 0= (1)
c 02 ∆t

Hesap için üstteki resmi hatırlayalım, i, j + 1 hücresine dört diğer hücreden ok


çizilmiş, aslında bu oklar üstteki formülün hesabını anlatıyor, o anki t zamanından
üç hesap ve geçmişten i, j − 1 hesabına bakarak gelecekteki değeri hesaplıyoruz.
Bu hesaplama çok verimli olacak çünkü herhangi bir anda hafızada tutulması
gereken y(i, j) haricinde sadece üç tane değer var.
Son bir problem başlangıç anı ile alakalı, resimdeki bilinmesi gereken o üç hücrenin
başlangıç j = 1 anında olduğunu düşünürsek, ve j = 2’yi hesaplamamız gerekiyor,
eksi zamana doğru bir gidişat lazım, yani j = −1 zamanı. Başlangıç bilgisi j = 1
var, ama j = −1 yok. Buradaki bilgiyi nasıl alacağız?
Denklemsel olarak bir ek koşul daha ekleyerek, ilk başta hem teli çekip üçgen ha-
line getirmiştik, bir de başlangıç anında telin hızı sıfırdır diyeceğiz. Bu mantıksız
değil, tel çekildi, tutuluyor.. hareket yok. Denklem olarak ∂y/∂t(x, 0) sıfır diyeceğiz.
Sonra bu denklemin merkezi farklılık açılımını yapacağız ve oradan gelen eşitlikleri
ana (1)’e sokarak sadece j = 2 için özel bir formül elde etmeyi umuyoruz.

∂y y(x, ∆t) − y(x, −∆t)


(x, 0) ' = 0, ⇒ yi,0 = yi,2
∂t 2∆t

(1)’e sokunca

c2
yi,2 = yi,1 + [yi+1,1 + yi−1,1 − 2yi,1 ]
c 02

Dikkat bu denklem sadece j = 2 için. Bundan sonraki her j için ana (1) formülü
işleyecektir.
Stabilite, von Neumann
Çözümün stabil olması için c 6 ∆x
∆t
şartının doğru olması gerekir, ve çoğunlukla
∆x bizim kontrolümüzde olmaz, problemin dayattığı bir büyüklük olur, c fiziki
modelin bir parçasıdır, o zaman ∆t’nin diğer verili parametrelere göre şarta uy-
gun seçilmesi gerekir. Şarta von Neumann ya da Courant stabilite şartı ismi ver-
iliyor.

3
Türetmek için alttaki gibi bir yaklaşım [3] kullanılabilir. Fakat ilerlemeden önce
Euler denkleminden türetilen bazı ek formülleri görelim, bu formüller birazdan
işimize yarayacak. Euler formülü hatırlarsak,

eix = cos(x) + i sin(x)

Üstteki formülü −x için yazarsak,

e−ix = cos(−x) + i sin(−x)

olur. Kosinüs’ün simetrik davranışı, yani cos(−x) = cos(x) ve − sin(x) = sin(−x)


olması sebebiyle, üstteki

= cos(x) − i sin(x)

olarak yazılabilir. Şimdi eğer eix ve e−ix ’i toplarsak, önceden gördüğümüz açılımlar
üzerinden,
eix + e−ix = 2 cos(x)
olur, çünkü eksi işaretli sin artı olanla beraber iptal olur. Tekrar düzenlersek,

1
cos(x) = (eix + e−ix ) (3)
2

Benzer bir eşitliği eix − e−ix üzerinden elde edebiliriz,

eix − e−ix = 2i sin(x)

Tekrar düzenleyince aynen biraz önce bir cos tanımı elde ettiğimiz gibi bir de sin
tanımı elde ederiz,

1 ix
sin(x) = (e − e−ix )
2i

Dalga kısmi denklemi ne idi?

∂2t y(x, t) = c(x)2 ∂2x y(x, t)

[2] notasyonu c yerine c(x) kullanmış. Şimdi stabilite şartını türetmek için çözümün
basit bir düzlem dalgası (plane wave) olduğunu farz edeceğiz [1], yani çözüm

y(x, t) = ei(kx−ωt)

4
formunda olacak. Bu formu ayrıksallaştırıp kısmı türevsel forma sokunca çıkan
eşitlikler üzerinden bir stabilite şartı elde etmek amacımız. [3] notasyonu yerine
[2]’imsi notasyon kullanacağız, yani x, t indisleri i, j yerine j, n, herhalde hayali
sayı i ile karışıklık olmasın diye böyle seçilmiş. O zaman x → j∆x, t → n∆t olur.
Alttaki analitik soldaki formül ayrıksal şu hale gelir,

y(x, t) = ei(kx−ωt) → yj,n = ei(kj∆x−ωn∆t)

Peki bu formülleri (2) bağlamında nasıl kullanacağız? Aslında bu çok basit.


Mesela yj+1,n için ayrıksal uzayda bir adım atmış oluyoruz, bu adımın basit dalga
formülünde karşılığı

yj+1,n = ei(k(j+1)∆x−ωn∆t)

Karışık gibi duruyor fakat e bazlı işlem yapmanın faydasını göreceğiz şimdi,

= eik∆x ei(kj∆x−ωn∆t)

Bir e bazlı terimi dışarı çekmiş olduk. Geri kalan sağdaki e bloğuna bakınca onun
yj,n olduğunu görüyoruz! O zaman

yj+1,n = eik∆x yj,n

Benzer bir işlemi yj−1,n için de gerçekleştirebiliriz,

yj−1,n = e−ik∆x ei(kj∆x−ωn∆t)

= e−ik∆x yj,n

Teknik ayrıksal zaman üzerinde de işliyor,

yj,n+1 = e−ik∆t yj,n

yj,n−1 = eik∆t yj,n

O zaman bu öğeleri dalga denklemi (2)’ye sokabiliriz. O denklemi [2]’ye göre


birazcık değiştirip tekrar verelim,
 
yj,n+1 − 2yj,n + yj,n−1 2 yj+1,n − 2yj,n + yj−1,n
= cj
∆t2 ∆x2

5
Şimdi üstteki formülde sonlu ayrıksal terimleri, yani yj,n+1 , yj,n−1 , yj+1,n , ve
yj−1,n terimlerini, biraz önce bulduğumuz üstel terimlerle değiştirelim,

eiω∆t − 2 + e−iω∆t
 ik∆x
− 2 + e−ik∆x i(kj∆x−ωn∆t)
  
i(kj∆x−ωn∆t) 2 e
e =c e
∆t2 ∆x2

cj → c geçişi her j∆x noktasına göre tanımlanıyor muhakkak.


Devam edelim, son formülde basitleştirme yapılabilir, en sol ve sağdaki terimler
iptal olabilir,

eiω∆t − 2 + e−iω∆t
 ik∆x
− 2 + e−ik∆x
  
2 e
=c
∆t2 ∆x2

Geri kalanları tekrar düzenleyelim,

2
iω∆t −iω∆t 2 ∆t
e +e −2=c [eik∆x − e−ik∆x − 2]
∆x2

Hayali terimlerden kurtulmak istiyoruz tabii, bu noktada (3)’teki kosinüs tanımını


tekrar hatırlayalım, onu kullanırsak, eşitliğin solundaki iki terim ve sağındaki iki
terim için ayrı ayrı,

∆t2
2 cos(ω∆t) − 2 = c2 (2 cos(k∆x) − 2)
∆x2

Herşeyi 2 ile bölelim,

∆t2
cos(ω∆t) − 1 = c2 (cos(k∆x) − 1) (4)
∆x2

Şimdi bir diğer trigonometrik eşitliği kullanacağız [4],

2 sin2 (x) = 1 − cos(2x)

Biraz degistirirsek,

p
sin(x) = 1 − cos(2x)

Ya da

x p
sin( ) = ± 1 − cos(x)
2

6
Bu eşitliğin (4) ifadesini nasıl basitleştireceğini görmek zor değil,

∆t ∆t2 ∆x
sin2 (ω ) = c2 2 sin2 (k )
r ∆x 2

Karelerden kurtulabiliriz,

∆t ∆t ∆x
sin(ω )=c sin(k )
r ∆x 2

İşte bu basit denklem sayısal analizin en temel bulgularından birine götürdü bizi.
Üstteki denklemin reel sonuçlara sahip olması için

∆t
c 61
∆x

olmalıdır. Bu koşul artık ünlü olan Courant-Friedrichs-Lewy (CFL) koşulu, ya da


kriteridir. Bu koşul iki tür hızın arasında bir ilişki kurar, biri fiziksel hız, ki fiziksel
ortamda dalganın yayılma hızı bu, diğeri ise “algoritmik hız” bir anlamda, bizim
tanımladığımız ızgaranın genişliği ∆x bölü yine bizim seçtiğimiz zaman aralığı
∆t.

rho = 0.01;
ten = 40.;
c = np.sqrt(ten/rho)
c1 = c;
ratio = c*c/(c1*c1) # CFL kriteri = 1
xi = np.zeros((101,3), float)
k = range(0,101)

for i in range(0, 81):


xi[i, 0] = 0.00125*i
for i in range (81, 101):
xi[i, 0] = 0.1 - 0.005*(i - 80)

fig = plt.figure()
for i in range(1,100):
xi[i,1] = xi[i,0] + 0.5*ratio*(xi[i+1,0] + xi[i-1,0] -2*xi[i,0])

for j in range(100):
for i in range(1, 100):
xi[i,2] = 2.*xi[i,1]-xi[i,0]+ratio*(xi[i+1,1]+xi[i-1,1]-2*xi[i,1])
if j % 5 == 0:
plt.grid(True)
plt.xlim(0, 101)
plt.ylim(-0.15, 0.15)
plt.plot(k,xi[k,2])
plt.savefig('/tmp/string-%02d.png' % j)
plt.clf()
for m in range (0,101):

7
xi[m, 0] = xi[m, 1]
xi[m, 1] = xi[m, 2]

! convert -loop 0 -delay 100 /tmp/string*.png string.gif

Animasyonlu sonucu [5]’te bulabiliriz.


[devam edecek]
Kaynaklar
[1] Bayramlı, Fizik, Isı ve Dalga Denklemleri
[2] Igel, Computers, Waves, Simulations, Coursera Lecture, Week 3, von Neumann
Analysis, https://www.coursera.org/learn/computers-waves-simulations
[3] Landau, Landau Computational Physics Course, Video Lectures, https://www.
youtube.com/playlist?list=PLnWQ_pnPVzmJnp794rQXIcwJIjwy7Nb2U
[4] Bayramlı, Diferansiyel Denklemler, Ekler, Trigonometri
[5] Bayramli, Animasyon, https://raw.githubusercontent.com/burakbayramli/
classnotes/master/compscieng/compscieng_app17wave/string.gif

8
Eğri Uydurma, Aradeğerleme (Interpolation) - 1
Diyelim ki elimizde alttaki veri var.

x = np.arange(1,7)
y = np.array([10, 5.49, 0.89, -0.14, -1.07, 0.84])
plt.plot(x,y,'.')
plt.ylim(-2,12)
plt.xlim(0,7)
plt.savefig('compscieng_1_21_01.png')

Bu veriye istediğimiz kadar bükümü olan bir eğri nasıl uydururuz? “İstediğimiz
kadar bükümü olan eğri” polinom çağrısı yapabilir.. Mesela bir polinom eğri,

y = c1 x3 + c2 x2 + c3 x + c4

olarak gösterilebilir. Mesela bazı gelişigüzel sabit değerler c1 = 1, c2 − 20, c3 =


1, c4 = −4 sabitlerinden alttaki görüntü çıkar,

x2 = np.linspace(0,10,1000)
c_1 = 2.; c_2 = -20.; c_3 = 1.; c_4 = -4
y2 = c_1*x**3 + c_2*x**2 + c_3*x + c_4
plt.plot(x2,y2)
plt.savefig('compscieng_1_21_02.png')

1
Eğri iki kere bükülebiliyor çünkü formül küpsel. Karesel olsa sadece bir kere
bükülebilirdi. Peki karesel, ya da küpsel ya da daha üst derecedeki polinom-
ları veriye nasıl uydururuz? Acaba lineer regresyonu bir şekilde kullanabilir
miyiz? Ama lineer regresyon, adı üstünde, “lineer”, yani doğrusal. Doğrusal ol-
mayan bir şeyi nasıl uyduracağız? Şimdi lineer regresyonun neyi uydurduğunu
hatırlayalım,

y = c1 z1 + c2 z2 + .. + cn zn

Bu çok boyutlu, her biri birer vektör olan z1 , .., zn ile tek vektör y ilişkisini girdi
olarak alıyor (üstteki formülü ya vektörsel işlem olarak ya da y, zi öğelerinin
teker teker formüle geçildiği şekilde görebiliriz).
Acaba şöyle bir numara yapamaz mıyız? Eğer elimizdeki tek boyutlu veriyi alıp,
onun tamamının bir kere karesini, bir kere küpünü, vs. ayrı ayrı alıp her sonucu
sanki ayrı bir boyutlarmış gibi lineer regresyona verirsek, otomatik olarak eğri
uydurmuş olmaz mıyız ?! Yani üstteki örnek için z1 = x3 , z2 = x2 , z3 = x, z4 = 1
olacak, matris formunda,
 
x31 x21 x1 1
 x32 x22 x2 1 
A=
 
.. .. .. .. 
 . . . . 
x3m x2m xm 1

ki xi , x vektörünün tek bir öğesini temsil ediyor. Gerisi bildiğimiz En Az Kareler


yöntemi ile Ax = b’yi, ya da üstteki notasyona göre Ac = y çözmek, (AT A)−1 AT c
ile (tabii QR kullanmak daha iyi ama bu basit örnek için önemli değil). Baştaki
örneği çözelim mesela

import scipy.linalg as lin


A = np.array([x**3, x**2, x, np.ones(len(x))]).T
res = np.dot(np.dot(lin.pinv(np.dot(A.T,A)),A.T),y)
print A, '\n\n', res

2
[[ 1. 1. 1. 1.]
[ 8. 4. 2. 1.]
[ 27. 9. 3. 1.]
[ 64. 16. 4. 1.]
[ 125. 25. 5. 1.]
[ 216. 36. 6. 1.]]

[ 0.03925926 0.42313492 -6.5032672 16.12666667]

Kütüphane çağrısı polyfit kullanırsak,

print np.polyfit(x,y,3)

[ 0.03925926 0.42313492 -6.5032672 16.12666667]

Tıpatıp aynı sonuç çıktı, çünkü büyük bir ihtimalle polyfit aynı tekniği kul-
lanıyor!

plt.plot(x,y,'.')
plt.ylim(-2,12)
plt.xlim(0,7)
yy = res[0]*x**3 + res[1]*x**2 + res[2]*x + res[3]
plt.plot(x,y,'.')
plt.hold(True)
plt.plot(x,yy)
plt.savefig('compscieng_1_21_03.png')

Uyum fena değil! Not: eğri kesikli çıktı çünkü çok az sayıda veri var.
Lagrange Aradeğerlemesi (Lagrange Interpolation)
En eski ve en yaygın uygulaması olan aradeğerleme fonksiyonlarından biri JL La-
grange tarafından yayınlanmış olandır. Pratik faydalarının yaninda bu tekniğin
önemli bazı teorik sonuçları var, bu sebeple yaklaşık ya da olmayan entegrasyon
ve türev alma teknikleri fonksiyonun Lagrange aradeğerlemesi ile temsilini baz
alıyor [1, sf. 268].
Lagrange tekniğinin önemli bir özelliği yaklaşık temsil edilecek fonksiyondan
seçilen değerler üzerinde, o noktalarda aynen verinin söylediği değerleri tekrar

3
üretebilmesi. Yani eğer f(x)’i bir fh (x) ile yaklaşık temsil etmişsek, ve eğer f(1) =
3 ise, aradeğerleme sonrası fh (1) = 3 olacaktır, ve bu üzerinden aradeğerleme
yapılmış tüm veri noktaları için doğru olacaktır. Ayrıca bir diğer özellik üzerinden
aradeğerleme yapılan x değerlerinin gelişigüzel seçilebilmesi, eşit aralıkta alınma
gibi bir zorunluluk yok.
Şimdi diyelim ki elde modellenen f(x) için elde n tane x1 , x2 , ..., xn değeri var, ki

f(xi ) = yi , i = 1, 2, .., n

Çözmek istediğimiz problem mümkün olan az derecede olan bir polinom Pm (x)
yaratmak öyle ki bu polinom eldeki (xi , yi ) veri noktalarını temsil edebilsin, yani

Pm (xi ) = yi , i = 1, 2, .., n

Burada m altsembolü dereceyi göstermek için kullanılıyor.


Daha önce söylediğimiz gibi veri noktalarında aradeğerleme ve veri aynı sonuçta
olmalı.
Bu amaçla n tane ayrı ayrı polinom pi (x) yaratacağız, ve bu polinomlar öyle
tasarlanacak ki xi noktasında biri aktif olacak, diğerleri yokolacak. Bu bize bir
delta fonksiyonunu hatırlatabilir, bu doğru, şu sonucu istiyoruz,


1 eğer j = i ise
pi (xj ) = δij =
0 eğer j 6= i ise

ki δij Kronecker delta fonksiyonu. Eger pi (x)’lerin j 6= i olacak sekilde xj nokta-


larında yokolmasını istiyorsak, onu (x − xj ) faktörlerinin bir çarpımı olarak yaz-
abiliriz,

Y
pi (x) = Ci (x − xj )
j6=i

Sabit Ci normalize edici bir değer. Üstteki çarpımda (x − xi ) yok, onu dışarıda
bırakarak pi elde ettik. Bir faktör hep dışarıda olacağı için pi (x) polinomunun
derecesi hep (n−1) olacaktır. Normalizasyon sabiti Ci hesaplamak Q için pi (xi ) = 1
olduğunu hatırlayalım ve bu değeri elde etmek için Ci = 1/ j6=i (xi − xj ) sabiti
gerekecektir, o zaman

Y
(x − xj )
j6=i
pi (x) = Y , i = 1, 2, .., n
(xi − xj )
j6=i

4
Her pi (x) polinomu xi haricinde diğer her noktada yokolacağı için Pm polinomu
pi (x)’lerin bir lineer kombinasyonu, toplamı olarak temsil edilebilir,

X
n
Pm (x) = pi (x)yi
i=1

Bir xj için hesap ne diyor?

X
n X
n
Pm (xj ) = pi (xj )yi = δij yi = yj
i=1 i=1

Doğru gözüküyor. Genel formda şunu yazabiliriz,

Y
(x − xj )
X
n
j6=i
Pm (x) = Y
i=1 (xi − xj )
j6=i

Eğer n = 2 olsaydı, eldeki iki tane (x1 , y1 ) ve (x2 , y2 ) için

(x − x2 ) (x − x1 )
P1 (x) = y1 + y2
(x1 − x2 ) (x2 − x1 )

Bu tabii ki iki noktadan geçen düz bir çizgiyi temsil ediyor.


Eğer n = 3 olsaydı, üç noktadan geçen bir parabol elde edilirdi,

(x − x2 )(x − x3 ) (x − x1 )(x − x3 ) (x − x1 )(x − x2 )


P2 (x) = y1 + y2 + y3
(x1 − x2 )(x1 − x3 ) (x2 − x1 )(x2 − x3 ) (x3 − x1 )(x3 − x2 )

Altta örnek olarak sin(5x)’ten alınmış 8 veri noktası ile aradeğerleme yapan bir
örnek görüyoruz,

def Lagrange(x, y, n, xi):


yi = 0e0
for i in range(1,n+1):
p = 1e0
for j in range(1,n+1):
if (j != i): p *= (xi - x[j])/(x[i] - x[j])
yi += p * y[i]

return yi

n = 8
ni = 100

5
x = [0]*(n+1)
y = [0]*(n+1)

# f(x) = sin(5*x), x degerleri gelisiguzel secilmis


x[1] = 0.15; x[2] = 0.2; x[3] = 0.3; x[4] = 0.5;
x[5] = 0.8 ; x[6] = 1.1; x[7] = 1.4; x[8] = 1.7
for i in range(1,n+1): y[i] = np.sin(5*x[i])

xx = []; yy = []; real = []


# x[1] ile x[8] arasinda esit aralikli x'ler yarat
# daha fazla nokta olsun
xis = np.linspace(x[1],x[-1],ni)
for i in range(1,ni+1):
xi = xis[i-1]
yi = Lagrange(x,y,n,xi)
xx.append(xi)
yy.append(yi)
real.append(np.sin(5*xi)+0.02)

xx = np.array(xx)
yy = np.array(yy)
real = np.array(real)

plt.plot(xx,yy)
plt.plot(x,y)
plt.plot(xx,real,'--')
plt.legend(['Lagrange',u'Seçilen Noktalar','Gerçek'])

plt.savefig('compscieng_app20cfit1_01.png')

Kaynaklar
[1] Beu, Introduction to Numerical Programming A Practical Guide for Scientists and
Engineers Using Python and C/C++

6
Eğri Uydurma, Aradeğerleme (Interpolation) - 2
[4], [5], yazılarındaki konuları genişletelim. Bu yazılardan biliyoruz ki basit re-
gresyon

yi = β0 + β1 xi + i

denklemini temel alıyor, onu veriye uyduruyor. Bu uydurma için kullandığımız


A, x, b matrisleri, vektörleri var. Sihirli formülü biliyoruz,

ŷ = X(XT X)−1 XT y

Şimdi bu formüldeki X içindeki değerleri farklı “bazlar” olarak görmek faydalı


olacaktır. Tek değişkenli durumda mesela bu baz
 
1 x1
X =  ... ... 
 
1 xn

Eğer karesel bir formülü uyduruyorsak, yani

yi = β0 + β1 xi + β2 x2i + i

baz
 
1 x1 x21
X =  ... ... .. 

. 
1 xn x2n

olur. Bu bakış açısını yorumlamak zor değil, regresyonun temeli değişkenlerin


katsayılarını bulmaktır, o zaman 1, x, x2 değişkenleri için de, ya da herhangi bir
başka baz bulmak için aynı teknik kullanılabilir çünkü karesel, küpsel bazlar kul-
lanıyor olsak bile bu değerleri önceden hesaplayıp matrise koyduğumuz için kul-
landığımız sihirli formül hala lineer bir problemi çözüyor. Hala değişkenler var,
onlar bazı katsayılar ile çarpılıp toplanarak veriye uydurulacak, ve sihirli formül
bu en optimal katsayıları bulacak.
Baz fikri ile devam edelim, alttaki veriye bakalım (gösterilen çizgilerin daha bulunmamış
olduğunu varsayalım),

1
Bu bir kırılmış değnek (broken stick) modeli, x = 0.6 öncesinde belli bir eğimi
olan bir düz çizgi var, sonrasında başka bir eğrisi olan bir düz çizgi var. Kırılma
noktasını biliyoruz, ya da regresyonun hangi noktadan geçmesini istediğimizi,
ilmik noktasını (knot) biliyoruz, bu durumda baz nedir?

(x − 0.6)+

fonksiyonudur. Tanımdaki altsimge + şunu ifade eder: herhangi bir sayı u eğer
pozitif ise u+ = u’dur, eğer değil ise u+ = 0 değerine sahiptir. Bunun amaçlarımız
için mükemmel bir baz fonksiyonu olacağını görebiliyoruz,

yi = β0 + β1 xi + β11 (xi − 0.6)+ + i

Bu fonksiyonun 0.6’ya kadar belli bir eğimi olacak, fakat 0.6 ardından bu eğime
bir “ek” yapılmaya başlanacak, β11 bu ekin ne kadar olacağını yakalayacak.
O zaman sihirli formüle verilecek matris
 
1 x1 (x1 − 0.6)+
X =  ... ... ..
 
. 
1 xn (xn − 0.6)+

Regresyon çözümü bize her baz için gerekli katsayıyı (kesiyi, eğimi) verecektir.
Daha abartarak (!) bir sürü ilmik üzerinden bir sürü baz tanımlayabilirdik, o
zaman ufak ufak pek çok düz çizgiyi veriye uydurmak mümkün olurdu, mesela
 
1 x1 (x1 − 0.5)+ (x1 − 0.55)+ . . . (x1 − 0.96)+
X =  ... ... .. .. ..
 
. . . 
1 x1 (x1 − 0.5)+ (x1 − 0.55)+ . . . (x1 − 0.96)+

2
(Resimde ilmikler 400,500,.. gibi değerlerde, yani bazlar (x1 − 500)+ şeklinde
olurdu)
Bilinen tek ilmik üzerinden en basit örneği görelim,

import statsmodels.formula.api as smf


import pandas as pd

df = pd.read_csv('../../tser/tser_chgpt/2inclines.csv')
reslin = smf.ols('y ˜ 1 + x + I((x-55)*(x>55))', data=df).fit()
print reslin.summary()
OLS Regression Results
==============================================================================
Dep. Variable: y R-squared: 0.957
Model: OLS Adj. R-squared: 0.956
Method: Least Squares F-statistic: 1081.
Date: Thu, 12 Jan 2017 Prob (F-statistic): 4.96e-67
Time: 14:27:42 Log-Likelihood: -243.44
No. Observations: 100 AIC: 492.9
Df Residuals: 97 BIC: 500.7
Df Model: 2
Covariance Type: nonrobust
======================================================================================
coef std err t P>|t| [95.0% Conf. I
--------------------------------------------------------------------------------------
Intercept 15.7364 0.701 22.447 0.000 14.345 17
x 0.2956 0.019 15.422 0.000 0.258 0
I((x - 55) * (x > 55)) 0.3530 0.040 8.926 0.000 0.275 0
==============================================================================
Omnibus: 15.710 Durbin-Watson: 2.312
Prob(Omnibus): 0.000 Jarque-Bera (JB): 4.411
Skew: -0.025 Prob(JB): 0.110
Kurtosis: 1.972 Cond. No. 148.
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly speci

df.set_index('x').y.plot()
plt.savefig('compscieng_app20_07.png')

3
Bulunan katsayılar üstteki grafiğe uyuyor.
İlmik Seçmek
[1, sf. 65] bu tekniği bir adım ilerletiyor; eğer ilmik seçmek isteseydik ne ya-
pardık? Bu durumda üstteki gibi pek çok mümkün bazı regresyona verirdik,
ama bu sefer regülarizasyon üzerinden eğer ise yaramayanları cezalandırırsak,
çok küçülen katsayılar bizim için önemsiz sayılacaktır ve katsayısı yüksek olan-
lar elde tutulabilir. Regularizasyon icin Istatistik, Regresyon, Ridge, Lasso, Çapraz
Sağlama, Regularize Etmek.
[1]’in cezalandırma formülasyonu bize bir Ridge regresyonu veriyor. Alttaki
veride denedik,

import pandas as pd
df = pd.read_csv('../../tser/tser_chgpt/cave.csv')
df.C.plot()
plt.savefig('compscieng_app20_06.png')

import statsmodels.formula.api as sm
f = "C ˜ 1 + Temp + I((Temp > 10)*(Temp-10)) + I((Temp > 15)*(Temp-15)) +" + \
"I((Temp > 20)*(Temp-20)) + I((Temp > 25)*(Temp-25)) +" + \

4
"I((Temp > 30)*(Temp-30)) + I((Temp > 35)*(Temp-35)) +" + \
"I((Temp > 40)*(Temp-40)) + I((Temp > 45)*(Temp-45)) +" + \
"I((Temp > 50)*(Temp-50)) + I((Temp > 55)*(Temp-55)) "
model = sm.ols(formula=f, data=df).fit_regularized(L1_wt=0.0)
print model.summary()

OLS Regression Results


==============================================================================
Dep. Variable: C R-squared: 0.962
Model: OLS Adj. R-squared: 0.956
Method: Least Squares F-statistic: 177.4
Date: Thu, 12 Jan 2017 Prob (F-statistic): 2.03e-50
Time: 13:13:45 Log-Likelihood: -185.82
No. Observations: 90 AIC: 395.6
Df Residuals: 78 BIC: 425.6
Df Model: 11
Covariance Type: nonrobust
======================================================================================
coef std err t P>|t| [95.0% C
--------------------------------------------------------------------------------------
Intercept 31.8192 1.354 23.494 0.000 29.123
Temp 0.3800 0.204 1.863 0.066 -0.026
I((Temp > 10) * (Temp - 10)) -0.0764 0.497 -0.154 0.878 -1.065
I((Temp > 15) * (Temp - 15)) -0.0524 0.651 -0.081 0.936 -1.348
I((Temp > 20) * (Temp - 20)) -0.0027 0.673 -0.004 0.997 -1.342
I((Temp > 25) * (Temp - 25)) -0.1210 0.674 -0.179 0.858 -1.463
I((Temp > 30) * (Temp - 30)) -0.3380 0.674 -0.501 0.618 -1.681
I((Temp > 35) * (Temp - 35)) -0.0869 0.674 -0.129 0.898 -1.429
I((Temp > 40) * (Temp - 40)) 0.1147 0.674 0.170 0.865 -1.227
I((Temp > 45) * (Temp - 45)) 0.0320 0.670 0.048 0.962 -1.302
I((Temp > 50) * (Temp - 50)) -0.0149 0.598 -0.025 0.980 -1.205
I((Temp > 55) * (Temp - 55)) -0.6336 0.295 -2.144 0.035 -1.222
==============================================================================
Omnibus: 7.572 Durbin-Watson: 1.924
Prob(Omnibus): 0.023 Jarque-Bera (JB): 7.180
Skew: -0.575 Prob(JB): 0.0276
Kurtosis: 3.770 Cond. No. 691.
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly speci

İstatistiki modelleri irdelemek bilimden ziyada biraz sanattır, fakat üstteki sonuçlarda
(Temp-30) katsayısının mutlak değerinin orta bölgedeki diğerlerine göre daha
yüksek olduğunu görüyoruz. Grafiğe bakılınca bu mantıklı gözüküyor.
Alternatif İlmik İfadeleri
Bazen sayısal hesaplarda üstte gördüğümüz u+ ifadesinin max(0, x−a) ile formülize
edildiğini görüyoruz. Yani,

y = β0 + β1 x + β2 (x − a)+ + β3 (x − b)+ + ...

yerine

5
y = β0 + β1 x + β2 max(0, x − a) + β3 max(0, x − b) + ...

ki a, b ilmik noktaları. Bu kullanım da aynı sonuç veriyor, düşünürsek max


ifadesi x değeri a değerini geçinceye kadar 0, ondan sonra x − a verecek, bu
da u+ gibi bir kullanım ile aynı.
Mesela

a,b,c,d = (1, -1.4, 2, 2.5)


x = np.linspace(0,5,100)
knots = [2,3,4]
def f(x):
return a + \
b*np.max([0,x-knots[0]]) + \
c*np.max([0,x-knots[1]]) + \
d*np.max([0,x-knots[2]])

y = np.array([f(xx) for xx in x])


plt.plot(x,y,'.')
plt.savefig('compscieng_app20_10.png')

Rasgele bazı ağırlıklarla x = 2, 3, 4 noktalarında aktif olan ilmiklerle üstteki grafiği


çıkarttık. Regresyon bağlamında bir optimizasyon rutinine (illa lineer regresyon
olması gerekmez) veriye bakarak bir hatanın minimize edilmesi üzerinden en
optimal a, b, c, d ağırlıklarını buldurmak ta mümkündür.
Peki max yerine baska bir fonksiyon kullanabilir miydik? max’in sonucta yaptigi
belli bir esik degerinden once 0 sonrasinda baska bir deger vermek degil midir?
Evet. Bu tur bir “karar” fonksiyonu sigmoid ile de elde edilebilir.

alpha = 5.0
def sig(x,a):
return 1/(1+np.exp(-alpha*(x-a)))
x = np.linspace(-5,5,100)

6
y = sig(x,0)
plt.plot(x,y)
plt.savefig('compscieng_app20_11.png')

y = sig(x,3)
plt.plot(x,y)
plt.savefig('compscieng_app20_12.png')

Normal sigmoid üst soldaki, fakat x−a ile onu da istediğimiz noktaya kaydırabiliyoruz.
α parametresi 0’dan 1’e geçişin ne kadar sert olduğunu kontrol ediyor.

rho = 7.0
def sig2(x,a):
return (x-a)*1/(1+np.exp(-rho*(x-a)))

a,b,c,d = (1, -1.4, 2, 2.5)


x = np.linspace(0,5,100)
knots = [2,3,4]
def f(x):
return a + \
b*sig2(x,knots[0]) + \
c*sig2(x,knots[1]) + \
d*sig2(x,knots[2])

y = np.array([f(xx) for xx in x])


plt.plot(x,y)
plt.savefig('compscieng_app20_13.png')

7
Daha yumuşak, pürüzsüz bir fonksiyon elde etmiş olduk. Bu birleşik eğrinin
türevini almak ta daha kolay olacaktır. Gerçi otomatik türev paketleri artık içinde
max bile olan ifadelerin türevini alabiliyor, fakat üsttekinin sembolik türevi rahatça
alınabilir, bu seçeneğin elde olması iyidir.
Küpsel Spline Eğrileri (Cubic Splines)
Baz seçerken elimizde pek çok seçenek var, mesela küpsel spline eğrileri uydur-
mak için

(1, x, x2 , x3 , (x − k1 )3+ , (x − k2 )3+ , (x − k3 )3+ , ..)

gibi bir baz kullanabiliriz, ilmikler k1 , .., kK olarak gider, genel olarak

X
K
f(x) = β0 + β1 x + β2 x2 + β3 x3 + β3+s (x − ks )3+
s=1

formülü verilir. Bu baza kırpılmış güç bazı (truncated power basis) ismi de ver-
iliyor.
Bir örnek üzerinde görelim,

import pandas as pd
dfcube = pd.read_csv('cube.csv')
df2 = dfcube.set_index('x')
df2.y.plot()
plt.savefig('compscieng_app20_09.png')

8
İlmik noktalarını seçelim, 8 ve 13 noktasında olsun,

import pandas as pd
import statsmodels.api as sm

dfcube = pd.read_csv('cube.csv')
dfcube.loc[:,'1'] = 1.
dfcube.loc[:,'x2'] = dfcube.x**2
dfcube.loc[:,'x3'] = dfcube.x**3
k1 = dfcube.x-8; dfcube.loc[k1>0,'k1'] = k1**3
k2 = dfcube.x-13; dfcube.loc[k2>0,'k2'] = k2**3
dfcube = dfcube.fillna(0)
X = dfcube[['1','x','x2','x3','k1','k2']]
y = dfcube.y
f = sm.OLS(y,X).fit()
print f.params

1 1.586781
x 1.747705
x2 -0.381304
x3 0.030443
k1 -0.092883
k2 0.138559
dtype: float64

dfcube['yy'] = f.params[0]*dfcube['1'] + f.params[1]*dfcube.x + \


f.params[2]*dfcube.x2 + f.params[3]*dfcube.x3 + \
f.params[4]*dfcube.k1 + f.params[5]*dfcube.k2
dfcube['y'] = y
df2 = dfcube.set_index('x')
df2[['y','yy']].plot()
plt.hold(True)
plt.axvline(x=8,color='c')
plt.hold(True)
plt.axvline(x=13,color='c')
plt.savefig('compscieng_app20_08.png')

9
Kısıtlanmış Küpsel Spline Eğrileri (Restricted Cubic Splines)
Üstteki metot iyi işliyor, fakat bazen başta ve sondaki parçaların eğri değil tam
düz olması istenebiliyor, yani “eteklerde” düzleştirme amaçlanıyor. Bu özel formülasyon
için bkz. [3, sf. 24]. Bu yaklaşımı baz alan kod [1]’in Python çevrimini altta veriy-
oruz. Metota verilen isim kısıtlanmış küpsel spline eğrileri, ya da doğal spline
eğrileri (natural splines).

import scipy.linalg as lin

def rcs(x,y,knots):
n = len(y)
k = knots
X1 = x
q = len(k)-1
myX=np.zeros((n,len(knots)-2))

for j in range(q-1):
tmp1 = (x-k[j])**3 * (x>k[j])
tmp2 = (x-k[q-1])**3 * (x>k[q-1])*(k[q]-k[j])
XX= tmp1-tmp2/(k[q]-k[q-1])
tmp1 = (x-k[q])**3 * (x>k[q])
tmp2 = (k[q-1]-k[j])
XX = XX+tmp1*tmp2/(k[q]-k[q-1])
myX[:,j]=XX

X = np.hstack( (np.ones((n,1)),np.reshape(X1,(n,1)),myX) )
bhat = np.linalg.lstsq(X,y)[0]
bhatt = np.zeros(len(knots)+1)
bhatt[len(bhat)] = (bhat[2:]*(k[0:-2]-k[-1])).sum()
bhatt[len(bhat)] = bhatt[len(bhat)] / (k[-1]-k[-2])
bhatt = np.hstack([bhatt, 0])
bhatt[-1] = (bhat[2:]*(k[0:-2]-k[-2])).sum()
bhatt[-1] = bhatt[-1] / (k[-2]-k[-1])
bhat = np.hstack((bhat, bhatt[-2:]))
return bhat

def speval(x,coefs,knots):

10
tmp = coefs[0] + coefs[1]*x
for k in range(len(knots)):
tmp = tmp + coefs[k+2]*((x-knots[k])**3)*(x>knots[k])
return tmp

import pandas as pd
x = np.random.randn(300)*np.sqrt(2)
e = np.random.randn(300)*np.sqrt(0.5)
y = np.sin(x)+e
df = pd.DataFrame([x,y]).T
df.columns = ['x','y']
df = df.sort_index(by='x')
print df.head()
knots=np.array([-5.5938, -3.7732, -1.9526, -0.1320, 1.6886, 3.5092, 5.3298]);
bhat = rcs(df.x,df.y,knots)
print bhat
df['spline'] = speval(df.x, bhat, knots)
df2 = df.set_index('x')
df2[['y','spline']].plot()
plt.hold(True)
for k in knots: plt.plot(k,speval(k,bhat,knots),'rd')
plt.savefig('compscieng_app20_01.png')

x y
156 -4.037867 0.786392
214 -3.442141 0.716684
101 -3.331777 0.400504
249 -3.178510 -1.019875
235 -3.131058 0.309575
[ 2.60209869 0.37061018 -0.09614395 0.3059325 -0.30256291 -0.05312331
0.33303297 -0.24924314 0.06210785]

import pandas as pd
dfcube = pd.read_csv('cube.csv')
dfcube = dfcube.sort_index(by='x')
knots=np.array([3,5,8,14,14.5]);
bhat = rcs(dfcube.x,dfcube.y,knots)
print bhat
dfcube['spline'] = speval(dfcube.x, bhat, knots)

11
df2 = dfcube.set_index('x')
df2[['y','spline']].plot()
plt.hold(True)
for k in knots: plt.plot(k,speval(k,bhat,knots),'rd')
plt.savefig('compscieng_app20_03.png')

[ 3.16368016 0.17418578 0.02336622 -0.01432746 -0.05277535 0.42087813


-0.37714154]

Kaynaklar
[1] Bantis, Restricted Cubic Spline, https://uk.mathworks.com/matlabcentral/
fileexchange/41241-restricted-cubic-spline
[2] Ruppert, Semiparametric Regression
[3] Harrell, Regression Modeling Strategies, 2nd Edition
[4] Bayramli, Lineer Cebir, Ders 16
[5] Bayramli, İstatistik, Lineer Regresyon

12
Eğri Uydurma, Aradeğerleme (Interpolation) - 3
Spline Eğrileri
Diyelim ki elimizde 4 xi , yi noktası var, ve bu noktalardan geçen, hepsinden
kesinlikle geçen, yaklaşıksal bir eğri oluşturmak istiyoruz. Spline yöntemi her
iki nokta arasını farklı bir küpsel (üçüncü derece) polinom ile temsil etmektir.
Tekrar dikkat: tüm noktaları temsile edebilecek farklı polinomları toplamıyoruz,
her aralıkta başka bir polinom fonksiyonu parçasını devreye sokuyoruz. Parçalar
niye küpsel olarak seçildi? Çünkü küpsel bir eğri yeterince kavis sağlayabilir ve
aynı zamanda çok fazla inişli çıkışlı, sivri değildir, yeterince pürüzsüz bir eğrinin
ortaya çıkmasını sağlar.

Her i = 0, .., n + 1 için

p(x) = pi (x) = ai + bi (x − xi ) + ci (x − xi )2 + di (x − xi )3 (1)

kullanalım. Noktalar xi olarak gösteriliyor, ve her noktada aktif olan bir pi spline
olacak, o noktadan bir sonrakine kadar eğriyi bu pi tanımlayacak. Noktaların
sayısını n yerine n+1 olarak aldık böylece n eğri parçası ile çalışmamız mümkün
olacak. Her spline bir küpsel polinom ise niye bu küpsel polinomu en basit
şekliyle

p(x) = ai + bi x + ci x2 + di x3

olarak tanımlamadık? Çünkü iki üstteki form ile çalışmak daha rahat. Mesela,
eğer x için xi değrini verirsek, ki bu x1 ya da x2 olabilirdi, o zaman parantez
içinde xi − xi sayesinde tüm terimler sıfır oluyor, geriye sadece ai kalıyor.
Parçaların uçlarının birbirini tutması, ve tüm şeklin sürekli, akışkan bir şekilde
gözükmesi için ise birkaç koşulu bizim tanımlamamız, ve zorlamamız gerekli.
Önce en basit olanı: bir önceki parça ile bir sonraki parça orta nokta üzerinde
aynı değere sahip olmalı. i = 1, .., n + 1 için

pi (xi+1 ) = pi+1 (xi+1 )

Bir diğer basit gereklilik, her xi ’ye tekabül eden spline fonksiyonun elimizdeki yi
değerini vermesi,

1
pi (xi ) = yi

“Tüm noktalardan kesinlikle geçmeli” demiştik. Son parça bir istisna oluşturuyor,
bu son parçanın fonksiyonu hem son noktayı, hem de ondan bir önceki nokta için
kullanılmalı, bir önceden en sona kadar aynı fonksiyon üzerindeyiz.

pn (xn ) = yn+1

Sistemi daha detaylı olarak görmek gerekirse, tüm denklemleri yazalım,

p1 (x) = a1 + b1 (x − x1 ) + c1 (x − x1 )2 + d1 (x − x1 )3

p2 (x) = a2 + b2 (x − x2 ) + c2 (x − x2 )2 + d1 (x − x2 )3

..
.

pn (x) = an + bn (x − xn ) + cn (x − xn )2 + d3 (x − xn )3

Üç noktalı şöyle bir grafik düşünelim,

Üstte bahsettiğimiz gibi, p1 (x1 ) = a1 = y1 olacak, ve tüm indisler için bu geçerli.


Ayrıca x2 noktasında bir önceki parça ve sonraki parça aynı değere sahip olmalı
demiştik, yani mesela p1 ’in sonunda (üstteki ilk parça) x2 noktası vardır, ve aynı
noktada p2 başlayacaktır, o noktada

p1 (x2 ) = a1 + b1 h1 + c1 h21 + d1 h31

ve bu denklem p2 (x2 ) = a2 = y2 ’ye eşit. Bir de, daha önce gördük, a1 = y1 ise, o
zaman

y2 = p1 (x2 ) = y1 + b1 h1 + c1 h21 + d1 h31

haline gelir. Hepsini birarada yazıyoruz (y’yi sağ tarafa aldık)

2
y1 + b1 h1 + c1 h21 + d1 h31 = y2

y2 + b2 h2 + c2 h22 + d2 h32 = y3

..
.

yn + bn hn + cn h2n + dn h3n = yn

ki h1 ≡ x2 − x1 , h2 ≡ x3 − x2 olarak tanımladık, ≡ işareti “tanımlamak (defined


as)” anlamına geliyor, h harfi bir tür kısaltma olarak kullanıldı. Fakat kesintisizlik
için parçaların uçlarının bitişmesi yeterli değil. Mesela alttaki figürün de uçları
birleşiktir,

Demek ki ek bazı şartlar lazım. Bu ek şart “süreklilik” olabilir. Mesela alttaki


örnek sürekli değildir.

Ya da daha iyisi, fonksiyonun her noktada “türevi alınabilir” olma şartı. Mesela
altta koyu yuvarlaklı gösterilen noktada fonksiyonun türevi alınamaz.

3
O zaman şartı koyalım – Fonksiyonun her noktasında, ikinci türev sürekli alınabilmeli.
Bu çok ağır / net bir şart aslında, ve hakikaten çok pürüzsüz (smooth) fonksiy-
onların oluşmasına sebep oluyor. Şimdi bunun ne anlamına biraz daha yakından
bakalım. Biliyoruz ki futbol sahalarının etrafında koşu alanı vardır. Bu alan
şöyledir.

Bu şekil iki ayrı figürün birleşimidir aslında, düz çizgiler ve iki tane yarı çember.
Üstteki düz çizgili kısım sonsuz kere türevi alınabilir bir fonksiyondur. Değil mi?
Düz çizgi sabit bir sayıdır, 1. türev sıfır, ikinci türev yine sıfır, böyle gider. Peki
yarı çember olan kısımlar? Aynı şekilde. Peki her noktada durum böyle midir?
Kritik noktalar ufak yuvarlaklarla gösterilen yerler (altta)

Bu noktalarda kaç kere “sürekli türevler” alınabilir? Cevap, sadece bir kere.
Çünkü iki kere türev alınınca ne olacağına bakalım, düz kısımda ikinci, üçüncü,
vs. türev sıfır. Peki yarı çember? Onun ikinci türevi sıfır olmayan sabit bir sayı. O
zaman fonksiyonun tamamının (düz çizgi ve yarı çemberin beraber) 2. türevini
grafiklesek, şöyle bir şekil ortaya çıkardı,

ve bu grafikte görüyoruz ki bir zıplama var. Bu zıplama yüzünden süreklilik


(2. türevde) bozulmuş oldu. O zaman spline düzgün, pürüzsüz olsun istiyorsak,
her noktada, yani bağlantı noktalarında, sağdaki ve soldaki parçanın birinci ve ik-

4
inci türevinin aynı olması şartını koyabiliriz, o zaman bu noktalarda fonksiyonun
tamamı iki kere sürekli türevi alınabilir hale gelir. Parçaların kendisi üzerinde bu
şartı tanımlamaya gerek yok, çünkü orada polinom kullanacağımızı belirttik za-
ten, polinomlar sonsuz kere sürekli türevi alınabilen objelerdir.
Denklem sistemimize iki tane daha şart gerekiyor. Bu şartlar fonksiyonun ilk
noktada ve son noktada ikinci türevinin sıfır olması şartı olabilir. Her hangi
yöndeki bir çizgi y = ax + b’nin iki kere türevi alınınca sıfır gelir, yani bu şart
fonksiyonumuzun son noktalarda, fonksiyonun “aşağı yukarı aynı yönde” ola-
cak şekilde düz olarak devam etmesi anlamına geliyor. Yaklaşıksal bağlamda
fena bir şart değil.
O zaman ana formüllerimize dönelim, ve mesela p1 (x), p2 (x)’in türevini alalım,

p10 (x) = b1 + 2c1 h1 + 3d1 h21

p20 (x) = b2 + 2c2 h2 + 3d2 h22

..
.

Türevleri eşitleyelim p10 (x2 ) = p20 (x2 ).

p10 (x2 ) = b1 + 2c1 h1 + 3d1 h21

p20 (x2 ) = b2

Üstteki niye sadece b2 oldu? Çünkü xi − xi numarası onun için de geçerli, geriye
sadece b2 kaldı. Hepsi bir arada

b1 + 2c1 h1 + 3d1 h21 = b2 (3)

b2 + 2c2 h2 + 3d2 h22 = b3

..
.

bn−1 + 2cn−1 hn−1 + 3dn−1 h2n−1 = bn

İkinci türevler için benzer bir durum var, bu sefer sol taraftan b’ler yokoluyor,

5
2c1 + 6d1 h1 = 2c2

2c2 + 6d2 h2 = 2c3

..
.

2cn−1 + 6dn−1 hn−1 = 2cn

İlk ve son ikinci türevi sıfıra eşitlemeyi unutmayalım. Son türev

2cn + 6dn hn = 2cn+1 = 0

İlk türev

p100 (x1 ) = c1 + 6d1 (x1 − x1 ) = c1 = 0

6d1 (x1 − x1 )
sıfır olur
Denklem (4)’den başlayan bölümü tekrar düzenlersek,

c2 − c1
d1 = (5)
3h1

c3 − c2
d2 =
3h2

..
.

cn+1 − cn
dn =
3hn

Üstteki denklemleri (2) ve (3)’e geri koyarsak,

c2 + 2c1
b1 + h 1 = s1 (7)
3

c3 + 2c2
b2 + h 1 = s2
3

6
..
.

cn+1 + 2cn
bn + h n = sn
3
y2 −y1 y3 −y2
ki s1 ≡ h1
, s2 ≡ h2
.
(3) ifadesini alıp tekrar düzenlersek,

2c1 h1 + 3d1 h21 = b2 − b1

3d1 h1 için başka bir ifade kullanabiliriz, eğer (5)’i tekrar düzenlersek,

3h1 d1 = c2 − c1

ve iki üstteki formüle koyarsak

2c1 h1 + (c2 − c1 )h1 = b2 − b1

2c1 h1 + c2 h1 − c1 h1 = b2 − b1

c1 h1 + c2 h1 = b2 − b1

(c1 + c2 )h1 = b2 − b1

Bu ifade tüm i noktaları için geçerli, hepsi bir arada

(c1 + c2 )h1 = b2 − b1 (6)

(c2 + c3 )h2 = b3 − b2

..
.

(cn−1 + cn )hn−1 = bn − bn−1

(7)’deki ardı ardına gelen denklemleri birbirinden çıkartıp sonucu 3 ile çarparsak,

7
c1 h1 + 2c2 (h1 + h2 ) + c3 h2 = 3(s2 − s1 )

c2 h2 + 2c3 (h2 + h3 ) + c4 h3 = 3(s3 − s2 )

..
.

cn−1 hn−1 + 2cn (hn−1 + hn ) + cn+1 hn = 3(sn − sn−1 )

Bu formüller birarada düşünülürse, bilinmeyenleri c2 , c3 , .., cn olan normal (ordi-


nary) n−1 tane lineer denklemdirler, ve bir matris çarpımı olarak düşünülebilirler.
c1 h1 matris formunda yok çünkü c1 = 0.

 
2(h1 + h2 ) h2 0 0 ... 0  

 h2 2(h2 + h3 ) h3 0 .. 0  c2


 0 h3 2(h3 + h4 ) h4 .. 0   c3 
 
 0 0 h4 2(h4 + h5 ) ... 0   .. 
  . 
 .. .. .. .. .. .. 
 . . . . . .  cn
0 0 .. 0 hn−1 2(hn−1 + hn )

Bu denklem sağ tarafta suna eşit


 
3(s2 − s1 )

 3(s3 − s2 ) 


 3(s4 − s3 ) 

 .. 
 . 
3(sn − sn−1 )

Bir üçgen köşegen (tridiagonal) matris iki tane ikili köşegen (bidiagonal) matrisin
çarpımına eşittir. LU çarpanlarına ayırma işlemi de, bkz [5], bize bu matrisleri
sağlayacaktır.

Ax = b

şu hale gelir

LUx = b

Şimdi eğer Ux = y kabul edersek, yani yeni bir değişkeni dahil edersek, L’i bul-
duktan sonra

8
Ly = b

kabul edebiliriz, ve bu formülü de y için çözmek çok kolaydır. Sonra çözülen y’yi
alıp geriye sokma (backsubstitution) ile x’i buluruz, yani

Ux = y

denklemini çözeriz.

import scipy.linalg as lin

a = np.array( [[3.,-3.,0,0],
[-3.,8.,-2.,0],
[0,1.,2.,4.],
[0,0,-2.,6.]])

p,l,u = lin.lu(a)

Ly = np.array([[7.,8.,2.,-3.]])

y = lin.solve(l,Ly.T)

x = lin.solve(u,y)
print x

[[ 5.44047619]
[ 3.10714286]
[ 0.26785714]
[-0.41071429]]

Spline yöntemine dönersek, elimizdeki veri ve kod şöyle olsun

import scipy.linalg as lin

xx = np.array([4.,9.,12.,16.,22.])

yy = np.array([157.,41.,145.,92.,7.])

h = np.diff(xx)

dy = np.diff(yy)

s = dy / h

ds = np.diff(s)

s3 = 3 * ds

a = np.array([[ 2*(h[0]+h[1]), h[1], 0],


[ h[1], 2*(h[1]+h[2]), h[2]],
[ 0, h[2], 2*(h[2]+h[3])]])

9
p,l,u = lin.lu(a)

y = lin.solve(l,s3.T)

c = lin.solve(u,y)
print c

[ 13.45756677 -13.90702275 2.64390455]

c’ler bulunduktan sonra h’lerle beraber kullanılarak d’ler bulunur, vs, ve tüm
spline parçalarının katsayıları ortaya çıkartılır.
Kodlar
Bazı kodlar altta bulunabilir. İlk önce SciPy ile B-spline, ilmikleri biz dışarıdan
tanımladık,

from scipy.interpolate import splev, splrep


x = np.linspace(0, 10, 10)
y = np.sin(x)
tck = splrep(x, y, t=[4,8]) # ilmikler t icinde
x2 = np.linspace(0, 10, 200)
y2 = splev(x2, tck)
plt.plot(x, y, 'o', x2, y2)
plt.savefig('compscieng_1_21_05.png')

Alttaki kodlar tüm eğrinin verideki her noktayı ilmik olarak görmesi gerektiğine
göre yazılmıştır, yani her veri noktası aynı zamanda bir ilmiktir.

import numpy as np

def Splines(data):
np1=len(data)
n=np1-1
X,Y = zip(*data)
X = [float(x) for x in X]
Y = [float(y) for y in Y]
a = Y[:]

10
b = [0.0]*(n)
d = [0.0]*(n)
h = [X[i+1]-X[i] for i in xrange(n)]
alpha = [0.0]*n
for i in xrange(1,n):
alpha[i] = 3/h[i]*(a[i+1]-a[i]) - 3/h[i-1]*(a[i]-a[i-1])
c = [0.0]*np1
L = [0.0]*np1
u = [0.0]*np1
z = [0.0]*np1
L[0] = 1.0; u[0] = z[0] = 0.0
for i in xrange(1,n):
L[i] = 2*(X[i+1]-X[i-1]) - h[i-1]*u[i-1]
u[i] = h[i]/L[i]
z[i] = (alpha[i]-h[i-1]*z[i-1])/L[i]
L[n] = 1.0; z[n] = c[n] = 0.0
for j in xrange(n-1, -1, -1):
c[j] = z[j] - u[j]*c[j+1]
b[j] = (a[j+1]-a[j])/h[j] - (h[j]*(c[j+1]+2*c[j]))/3
d[j] = (c[j+1]-c[j])/(3*h[j])
splines = []
for i in xrange(n):
splines.append((a[i],b[i],c[i],d[i],X[i]))
return splines,X[n]

def splinesToPlot(splines,xn,res):
n=len(splines)
perSpline = int(res/n)
if perSpline < 3: perSpline = 3
X=[]
Y=[]
for i in xrange(n-1):
S = splines[i]
x0 = S[4]
x1 = splines[i+1][4]
x = np.linspace(x0,x1,perSpline)
for xi in x:
X.append(xi)
h=(xi-S[4])
Y.append(S[0]+S[1]*h + S[2]*h**2 + S[3]*h**3)
S=splines[n-1]
x=np.linspace(S[4],xn,perSpline)
for xi in x:
X.append(xi)
h=(xi-S[4])
Y.append(S[0]+S[1]*h + S[2]*h**2 + S[3]*h**3)

return X,Y

import Spline
x = lambda n: np.linspace(-1,1,n)
f = lambda x: np.cos(np.sin(np.pi*x))
n = 5
E=200
data = zip(x(n),f(x(n)))

11
splines,xn = Spline.Splines(data)
X,Y = Spline.splinesToPlot(splines,xn,E)
plt.plot(X,Y,'r--')
plt.plot(x(300),f(x(300)),'k')
plt.savefig('compscieng_1_21_04.png')

Bir diğer örnek

import numpy as np
from LUdecomp3 import *

def curvatures(xData,yData):
n = len(xData) - 1
c = np.zeros(n)
d = np.ones(n+1)
e = np.zeros(n)
k = np.zeros(n+1)
c[0:n-1] = xData[0:n-1] - xData[1:n]
d[1:n] = 2.0*(xData[0:n-1] - xData[2:n+1])
e[1:n] = xData[1:n] - xData[2:n+1]
k[1:n] =6.0*(yData[0:n-1] - yData[1:n]) \
/ (xData[0:n-1] - xData[1:n]) \
-6.0*(yData[1:n] - yData[2:n+1]) \
/ (xData[1:n] - xData[2:n+1])
LUdecomp3(c,d,e)
LUsolve3(c,d,e,k)
return k

def evalSpline(xData,yData,k,x):
def findSegment(xData,x):
iLeft = 0
iRight = len(xData)- 1
while 1:
if (iRight-iLeft) <= 1: return iLeft
i =(iLeft + iRight)/2
if x < xData[i]: iRight = i
else: iLeft = i

i = findSegment(xData,x)
h = xData[i] - xData[i+1]

12
y = ((x - xData[i+1])**3/h - (x - xData[i+1])*h)*k[i]/6.0 \
- ((x - xData[i])**3/h - (x - xData[i])*h)*k[i+1]/6.0 \
+ (yData[i]*(x - xData[i+1]) - yData[i+1]*(x - xData[i]))/h
return y

if __name__ == "__main__":

xData = np.array([1,2,3,4,5],float)
yData = np.array([0,1,0,1,0],float)
k = curvatures(xData,yData)
x = 1.5
print("y =",evalSpline(xData,yData,k,x))

import pandas as pd, cubicSpline


df = pd.read_csv('in.csv')
res = cubicSpline.curvatures(np.array(df.x), np.array(df.y))
print res

[ 0. -2.27960615 0.5983445 -2.14369027 -0.5421918 -0.9485407


4.83823742 1.40244849 -0.82589911 -1.3439826 2.52298704 0. ]

Kaynaklar
[1] Vrbik, MATH 2P20 NUMERICAL ANALYSIS I Lecture Notes, http://spartan.
ac.brocku.ca/˜jvrbik/MATH2P20/notes.pdf
[2] Ertel, Advanced Mathematics for Engineers Lecture No. 14, http://www.youtube.
com/watch?v=3rHBCglD1LQ
[3] Ertel, Advanced Mathematics for Engineers Lecture No. 15, http://www.youtube.
com/watch?v=nA0YpqraP9A
[4] Recktenwald, Numerical Methods with MATLAB Implementations and Applica-
tions
[5] Bayramli, Lineer Cebir, Ders 4

13
Karesel Yaklaşıksallama (Quadratic Approximation)
Bir nokta etrafında, herhangi bir boyutta karesel yaklaşıksallama yapmak için bir
karesel baz fonksiyonu kullanabiliriz, mesela iki boyut için

 T
p(x) = x1 x2 x21 x1 x2 x22
 T
bir baz olabilir, ki x = x1 x2 olmak üzere, böylece f(x) = p(x)T a çarpımı ile
bir özgün fonksiyon yaratabiliriz, a = [a0 , a1 , ...] içinde sabitler vardır bu sabitler
fonksiyonu özgün olarak belirleyen değerlerdir. Bir anlamda

f(x) = a0 + a1 x1 + a2 x2 + a3 x1 x2 + a4 x22

çarpımının vektörsel halini görmüş olduk.


Peki eğer a katsayılarını bilmiyorsak, verilen bir deney verisi üzerinden kat-
sayıları nasıl buluruz? Üstteki temeli kullanarak bir veriye en az kareler bağlamında
en iyi uyan karesel denklemi uydurabiliriz, bunun için her veri noktasını baz
fonksiyon üzerinden genişletmemiz gerekir, yani üç boyutlu bir fonksiyondan
alınmış olacak x1 = (x11 , x12 ), x2 = (x21 , x22 ), ..., xn = (xn n
1 , x2 ) ve ona tekabül eden
1 2 n
y , y , ..., y değerleri için
   
(x11 ) (x12 ) (x11 )2 (x11 )(x12 ) (x12 )2 y1
 .. ..  a =  .. 
 . .   . 
n n n 2 n n n 2
(x1 ) (x2 ) (x1 ) (x1 )(x2 ) (x2 ) yn

ortamını yaratmak gerekir. Bu problemi en az kareler stili ile çözebiliriz.


Fakat bizim icin daha faydali olabilecek bilgi, bir karesel fonksiyon üzerinden
ayrıca gradyan ve Hessian bilgisini de alabilmek. Bu bilginin direk alınabileceği
en kolay form

f(x) = xT Ax

formudur. Bu da çok boyutlu karesel fonksiyonları temsil etmenin bir diğer yolu,
ve gradyan ∇f(x) = 2Ax ve Hessian ∇2 f(x) = 2A (A simetrik ise) ile bu form
üzerinden rahatça hesaplanabilir. O zaman istediğimiz öyle bir en az kareler
uygulaması ki, elde edilen katsayıları direk A öğeleri olarak alabilelim, ve bu
A üzerinden ∇f(x) ve ∇2 f(x) hesaplamak kolay olsun.
Üç boyutlu durumda ne olurdu? Üstteki karesel matris formunu şu şekilde açalım,

  
a11 a 12 a13 x1
xT Ax =
 
x1 x2 x3  a21 a22 a23   x2 
a31 a32 a33 x3

1
 T  
x1 a11 + x2 a21 + x3 a31 x1
=  x1 a12 + x2 a22 + x3 a32   x2 
x1 a13 + x2 a23 + x3 a33 x3

= x1 x1 a11 + x1 x2 a21 + x1 x3 a31 +


x1 x2 a12 + x2 x2 a22 + x3 x2 a32 +
x1 x3 a13 + x2 x2 a23 + x3 x3 a33

Buradan görülüyor ki xi , xj indislerinin aij indisi ile direk bağlantısı var. O za-
man bir döngü içinde tüm i, j kombinasyonlarını yanyana koyarak bir vektör
oluşturursak burada elde edilen A matrisi içindeki öğeler beklenen yerlerde ola-
caktır.
Bir pürüz daha kaldı, iki boyutlu ortamı düşünürsek x21 , x22 var ama tek başına x1
yok, ayrıca tek başına bir sabit değer de gerekli, bu lineer denklemlerdeki kesi (in-
tercept) değeri gibi, karesel denklemi olduğu gibi yukarı, aşağı kaydırabilmemizi
sağlayacak. Bunun çözümü basit, üstteki gibi üç boyuttaki denklemde x3 yerine
1 değerini verirsek,

  
a11 a 12 a13 x1
xT Ax =
 
x1 x2 1  a21 a22 a23   x2 
a31 a32 a33 1

Bu bize

= x1 x1 a11 + x1 x2 a21 + x1 a31 +


x1 x2 a12 + x2 x2 a22 + x2 a32 +
x1 a13 + x2 x3 a23 + a33

= a11 x21 + a21 x1 x2 + a31 x1 +


a12 x1 x2 + a22 x22 + a32 x2 +
a13 x1 + a23 x2 x3 + a33

denklemini sağlar, yani iki boyutta tam bize gereken denklem. O zaman en az
kareler için üç boyutta hazırlayacağımız hesap bize iki boyut için gereken sonucu
verir. Tek hatırlamamız gereken gerekli noktalarda bir ’1’ değerini vektöre ekle-
mektir.
Şimdi optimizasyonun klasik problemlerinden Rosenbrock fonksiyonunu görelim.
Bu fonksiyonun belli noktalarından örneklem alacağız, ve bu noktaları kulla-
narak o noktada bir karesel ara değerleme (interpolation) yapacağız.

2
from scipy.interpolate import Rbf
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
import autograd.numpy as anp
import autograd

def random_ball(num_points, dimension, radius=1):


from numpy import random, linalg
random_directions = random.normal(size=(dimension,num_points))
random_directions /= linalg.norm(random_directions, axis=0)
random_radii = random.random(num_points) ** (1/dimension)
return radius * (random_directions * random_radii).T

np.random.seed(0)
N = 20

def rosenbrock(x):
return (1 + x[0])**2 + 100*(x[1] - x[0]**2)**2

def Rosenbrock(x,y):
return (1 + x)**2 + 100*(y - x**2)**2

def get_fvals_in_region(xcurr, f, radius):


b = random_ball(N, 2, radius)
pts = xcurr+b
vals = [f(p) for p in pts]
return xcurr+b, np.array(vals)

x0 = [1.5,0]
xs,vs = get_fvals_in_region(x0, rosenbrock, 0.5)

res = []
for i in range(vs.shape[0]):
res.append((xs[i,0],xs[i,1],vs[i]))
res = np.array(res).reshape(vs.shape[0], 3)

x = np.linspace(-2,2,250)
y = np.linspace(-1,3,250)
X, Y = np.meshgrid(x, y)
Z = Rosenbrock(X, Y)

fig = plt.figure(figsize = (8,4))


ax = fig.gca(projection='3d')
ax.plot3D(res[:,0],res[:,1],res[:,2],'r.')
ax.plot_surface(X,Y,Z,rstride = 5, cstride = 5, cmap = 'jet', alpha = .4, edgecolor =

ax.view_init(21, -133)

plt.savefig('func_70_dfo_01.png')

3
Şimdi üstteki örneklem noktalarını kullanarak ona en yakın karesel fonksiyonu
bulalım,

import itertools
import numpy.linalg as lin

def quad_interpolate(xi, yi):


xi = np.hstack((xi, np.ones((1,len(xi))).T ))
#print (xi)
D = xi.shape[1]
print (D)
X_train = []
for row in xi:
X_train.append([row[i]*row[j] for i,j in itertools.product(range(D),range(D))
X_train = np.array(X_train)
print (X_train.shape)
print (yi.shape)
coef,_,_,_ = lin.lstsq(X_train, yi)
return coef

xi = res[:,[0,1]]
yi = res[:,[2]]
coef = quad_interpolate(xi,yi)

print (coefs)

3
(20, 9)
(20, 1)
[[ 1549.94077306 -331.73935453 -1646.09015508]
[ -331.73935453 108.66378197 273.04187866]
[-1646.09015508 273.04187866 1960.85629284]]

x = np.linspace(-2,2,250)
y = np.linspace(-1,3,250)
X, Y = np.meshgrid(x, y)
Z = Rosenbrock(X, Y)

fig = plt.figure(figsize = (8,4))

4
ax = fig.gca(projection='3d')
ax.plot3D(res[:,0],res[:,1],res[:,2],'r.')
ax.plot_surface(X,Y,Z,rstride = 5, cstride = 5, cmap = 'jet', alpha = .4, edgecolor =

def q_interp(x1,x2):
x = np.array([[x1,x2,1]])
A = coef.reshape(3,3)
res = np.dot(np.dot(x,A),x.T)
return np.float(res)

Zi = np.array([q_interp(xx,yy) for xx,yy in zip(X.flatten(),Y.flatten())])


Zi = Zi.reshape(X.shape)
ax.plot_wireframe(X,Y,Zi)

coefs = coef.reshape(3,3)

g = (2 * np.dot(coefs[:2,:2],np.array(x0).reshape(2,1)))

gnorm = g / np.sum(g)

ax.set_zlim(0,2500)

ax.quiver(x0[0], x0[1], 0, -gnorm[0], -gnorm[1], 0, color='red')

hess = 2*coefs[:2,:2]
print (hess)
newton_dir = -np.dot(lin.inv(hess),g)
print (newton_dir)

d = newton_dir
print (d)

ax.quiver(x0[0], x0[1], 0, d[0], d[1], 0, color='green')

ax.plot3D([x0[0]], [x0[1]], [0.0], 'b.')

ax.view_init(21, -133)

plt.savefig('func_70_dfo_02.png')

[[3099.88154613 -663.47870906]
[-663.47870906 217.32756394]]
[[-1.50000000e+00]
[ 1.77635684e-15]]
[[-1.50000000e+00]
[ 1.77635684e-15]]

5
Görüldüğü gibi en az karelerle hesaplanan A üzerinden Hessian ve Jacobian
hesabı çok kolay oldu. Bu değerlerle o noktada gradyan inişi ve Newton adımı
yönlerini hesapladık.
Fakat dikkat etmek gerekir; her ne kadar yaklaşıklama Hessian ve Jacobian için
gerçeğe yakın değerler hesaplaşa bile, Newton hesabı açısından bu yeterli ol-
mayabilir, onu çizgi arama yöntemi ile birleştirmek gerekir [1].
Kaynaklar
[1] Bayramli, Fonksiyonel Analiz ve Optimizasyon - Newton’un Metodu

6
Özyineli En Az Kareler (Recursive Least Squares)
Ax = b denklem sistemini çözmek için

x = (AT A)−1 AT b

formülü en az kareler çözümü olarak biliniyor, bkz [2]. Bu çözüm iyi işler, fakat
bazı durumlarda negatif bir tarafı var, çözüm toptan (batch) olarak yapılıyor. A
içinde 100 tane satır olabilir, ona göre bir çözüm bulunur, ardından 1 tane ek veri
satırı gelirse olsa 101 tane satır için tüm işlemlerin tekrar baştan yapılması gerekir.
Acaba sadece o yeni verilen satır için önceki x tahminini bir şekilde güncellemek
mümkün mü?
Özyineli en az kareler ile bunu yapabiliriz. Diyelim ki

c1 t + c2 = b

lineer sistemini çözmek istiyoruz, yani bu bir çizgi uydurma (line fitting) ola-
cak, kesi c2 , eğim c1 . Notasyon altta, altsimge k kaç tane veri satırı olduğunu
gösterecek,
   
t1 1 B1
t2 1  B2
 
c1,k
  
Ak xk ≈ bk , Ak =  .. ..  , xk = , bk = 
   
c2,k .. 
 . .   . 
tk 1 Bk

Eğer tek istediğimiz tek boyutlu bir zaman serisi için çizgi uydurma yapmak ise
t1 , .., tk 1 ve k arası tam sayılar olurdu, bu durumda Ak iyice basitleşir. Devam
edelim, eğer (1)’i üstteki format için uyarlarsak,

xk = (ATk Ak )−1 ATk bk

Yani elde k tane veri var, üstteki formülü uyguladık ve bir çözüm bulduk. Şimdi
diyelim ki yeni ölçümler (tk+1 , Bk+1 ) aldık, ve

xk+1 = (ATk+1 Ak+1 )−1 ATk+1 bk+1

hesabını yapmamız lazım. Ek notasyon;

     
Ak tk+1 bk
Ak+1 = , aTk+1 = , bk+1 = , Pk = (ATk Ak )−1
aTk+1 1 Bk+1

Matris tersi Pk ’nin yeni veri noktası gelince nasıl güncellendiğini görelim,

1
   −1
Ak
(ATk+1 Ak+1 )−1
 
Pk+1 = = Ak ak+1
aTk+1

Eşitliğin sağındaki matris çarpımını yaparsak, ve Pk ’yi yerine koyarsak,

= [ATk Ak + ak+1 aTk+1 ]−1 = [Pk + ak+1 aTk+1 ]−1

Üstte yine sağdaki formül (A+BCD)−1 formunda bir ters alma işlemi gibi gözüküyor;
Matris Tersi Yardımcı Teorisi (Matrix Inversion Lemma) diyor ki [1, sf. 469], her-
hangi bir A, B, C, D için,

[A + BCD]−1 = A−1 − A−1 B[C−1 + DA−1 B]−1 DA−1

(2)’deki ifadenin üstteki forma göre paylaştırmasını şöyle yapalım, A = Pk , B =


ak+1 , C = I, D = aTk+1 . Buna göre (2) üstteki açılım üzerinden ve paylaştırılan
sembollere göre şu hale gelir,

Pk+1 = Pk − Pk ak+1 (I + aTk+1 Pk ak+1 )−1 aTk+1 Pk

Parantez içindeki büyük çarpım bir tek sayı olduğu için I değeri 1 yapılabilir,

Pk+1 = Pk − Pk ak+1 (1 + aTk+1 Pk ak+1 )−1 aTk+1 Pk

Bu durumda tersi alınan parantez içindeki tüm ifade de tek sayı demektir, ve bu
tek sayının tersini almak çok basittir (x için 1/x).
Nihai güncelleme formülü için devam edelim; (3) formülüne (4)’teki eşitlikleri
koyalım,

 
  bk
xt+1 = Pk+1 ATk ak+1
Bk+1

= Pk+1 [ATk bk + ak+1 Bk+1 ]

(5) formülünü değiştirerek şu hale getirebiliriz,

(ATk Ak )xk = ATk bk

Bu sonucu iki üstteki formüle sokarsak,

= Pk+1 [ATk Ak xk + ak+1 Bk+1 ]

2
(4)’teki formlar üzerinden

ATk+1 Ak+1 = ATk Ak + ak+1 aTk+1

diyebileceğimizi görmüştük, o zaman

ATk+1 Ak+1 xk = (ATk Ak + ak+1 aTk+1 )xk

Üç üstteki formülde yerine koyalım,

= Pk+1 [(ATk Ak + ak+1 aTk+1 )xk + ak+1 Bk+1 ]

−1
= Pk+1 [Pk+1 xk + ak+1 aTk+1 xk + ak+1 Bk+1 ]

xk+1 = xk + Pk+1 ak+1 aTk+1 xk + Pk+1 ak+1 Bk+1

xk+1 = xk + Pk+1 ak+1 (aTk+1 xk + Bk+1 )

Şimdi Pk+1 ’yi özyineli olarak temsil etmek şunları yapalım. Kk+1 = Pk+1 ak+1
sistemin kazanç matrisi (gain matrix) olsun, ve (6)’daki Pk+1 eşitliği kullanarak
formülü genişletelim,

Kk+1 = Pk+1 ak+1 = [Pk − Pk ak+1 [1 + aTk+1 Pk ak+1 ]−1 aTk+1 Pk ]ak+1

= Pk ak+1 − Pk ak+1 [aTk+1 Pk ak+1 + 1]−1 aTk+1 Pk ak+1

= Pk ak+1 I − [aTk+1 Pk ak+1 + 1]−1 aTk+1 Pk ak+1


 

Eğer bu formülü aynı anda hem (aTk+1 Pk ak+1 ) hem de (aTk+1 Pk ak+1 )−1 ile çarparsak
(hiçbir etkisi olmayan bir işlem, birbirini iptal ediyor çünkü) bazı temizleme işlemlerini
yapmak mümkün olur,

= Pk ak+1 (aTk+1 Pk ak+1 + 1) − aTk+1 Pk ak+1 (aTk+1 Pk ak+1 + 1)−1


 

Büyük parantez içinde sadece +1 sağ kalır, geri kalanlar iptal olur,

Kk+1 = Pk ak+1 (aTk+1 Pk ak+1 + 1)−1

3
Bu formülü (7) içine geri Kk+1 olarak koyarsak,

xk+1 = xk + Kk+1 (aTk+1 xk + Bk+1 )

Aynı şekilde (6) içine koyarsak,

Pk+1 = Pk − Pk ak+1 (1 + aTk+1 Pk ak+1 )−1 aTk+1 Pk


| {z }
Kk+1

Pk+1 = Pk − Kk+1 aTk+1 Pk

Böylece Kk+1 , Pk+1 , xk+1 özyineli güncelleme formüllerini elde etmiş oluyoruz.
Kodlar
Güncelleme kodları alttadır,

import numpy as np

def rlse_online(aT_k1,b_k1,x,P):
K = np.dot(P,aT_k1.T)/(np.dot(np.dot(aT_k1,P),aT_k1.T)+1)
x = x +K*(b_k1-np.dot(aT_k1,x))
P = P-np.dot(K,np.dot(aT_k1,P))
return x,K,P

Örnek olarak alttaki veriyi kullanalım.

import numpy.linalg as lin


b = np.array([[3.0,4.0,6.0,3.0,8.0,7.0,5.0]]).T
A= np.ones((len(b),2)); A[:,1] = range(len(b))

Özyineli olarak problemi çözelim; her veri noktasını teker teker güncelleme ruti-
nine geçelim.

import rls
n = 2
P = np.eye(n,n)*100.
x = np.zeros((n,1))
for k in range(len(b)):
x,K,P = rls.rlse_online(np.array([[k,1]]),b[k,:],x,P)
print x

[[ 0.5037057 ]
[ 3.62655923]]

Üstteki sonuç bulundu. Şimdi aynı verileri en az kareler ile toptan şekilde çözelim,

4
import statsmodels.api as sm

y = b; x = A
f = sm.OLS(y,x).fit()
print f.params

[ 3.64285714 0.5 ]

Önce Toptan, Sonra Özyineli


Eğer verinin bir kısmı için toptan başlayıp sonra özyineli gitmek istersek ne ya-
parız? O zaman elde bir (ATk Ak )−1 , yani Pk olurdu, toptan şekilde hesaplanmış
olacaktı, ve bu değerin sonraki hali için güncelleme formülünü biliyoruz, böyle
devam ederdik. Tabii bu durumda (ATk Ak )−1 ’yi toptan hızlı hesaplamak için
bir teknikten bahsetmek lazım, en az kareler rutinleri genelde bu değeri geri
döndürmezler, Lineer Cebir Ders 16’dan hatırlarsak bu hesabı direk yapmak oldukça
pahalı, o yüzden QR bazlı bir yaklaşım lazım (aynen x’in kendisinin QR bazlı
hesaplandığı gibi). Her Ak matrisinin bir Ak = QR açılımı olacağından hareketle,

ATk Ak = (QR)T QR = RT QT QR = RT R

O zaman

(ATk Ak )−1 = (RT R)−1 = R−1 R−T

Şimdi verinin en son satırı hariç ilk kısmı üzerinde bu değeri hesaplayalım,

A_k = A[:-1,:]
b_k = b[:-1,:]
print A.shape, A_k.shape
q,r = lin.qr(A_k)
Pk_r = np.dot(lin.inv(r), lin.inv(r.T))
print Pk_r
Pk = lin.inv(np.dot(A_k.T,A_k))
print Pk

(7, 2) (6, 2)
[[ 0.52380952 -0.14285714]
[-0.14285714 0.05714286]]
[[ 0.52380952 -0.14285714]
[-0.14285714 0.05714286]]

Direk usül ve QR bazlı ters işleminin aynı sonuçlara erişildiğini görüyoruz. Top-
tan xk

x_batch = np.dot(np.dot(lin.inv(r), q.T), b_k)


print x_batch.T[0]

[ 3.0952381 0.82857143]

Şimdi yeni veri noktası ile güncelleyelim,

5
A_new = A[-1,:]
b_new = b[-1,:]
x_new,K_new,P_new = rls.rlse_online(A_new,b_new,x_batch.T[0],Pk_r)
print x_new

[ 3.64285714 0.5 ]

Aynı sonuca eriştik.


Kaynaklar
[1] Yang, Applied Numerical Methods using Matlab
[2] Bayramli, Lineer Cebir, Ders 16

6
Logaritmayı Taylor Serisi İle Hesaplamak
Taylor açılımı tekniğini ilk gördüğümüzde öğrenci genelde kendine şu soruyu so-
rar: ”İyi ama, bu ne işe yarar?” Taylor serilerini ilginç kılan özellik, bir formülü bir
başkasına dönüştürmemizi sağlamaları, ve, genelde sonsuz olmayan bir formülü,
sonsuza kadar devam eden terimlerin toplamı olan başka bir formül ile değiştirmemizi
sağlamalarıdır.
Sonsuza kadar devam eden terimler toplamı, karışık bir durumdur. Teklikten,
çokluğa niye gidilmektedir? Bu sonsuz terimler dizisi ne işe yaramaktadır? Öğrenciye
göre, düzenden, düzensizliğe gidilmiştir. Niçin? Bu tür sorular, Taylor seri-
lerinin tanıştırıldığı her derste cevaplanmalıdır. Bu yazıda, Taylor serisinin ne
işe yaradığını, hangi problemler için kullanıldığını, ve ait olduğu matematiksel
dünyanın hangisi olduğunu göreceğiz.
Yaklaşıklamak (Approximation)
Yaklaşıklamak, bir değeri, fonksiyonu, matematiksel bir kavramın yerine ona
yakın, aşağı yukarı eşit olan başka bir değeri/fonksiyonu/kavramı koymak de-
mektir. Gündelik hayatta bazı sayıları sürekli başkaları ile yaklaşıklamaya uğraşmaktayız.
Mesela bir alan, uzunluk, hacim, vs. gibi şeyler ölçerken, mecburen yaklaşıksal
kavramlar ile yüzyüze gelmekteyiz. Normalde gündelik hayatımızda sadece
tamsayılar ve tamsayıların bölümü olarak gösterilebilecek rasyonel sayılar kul-
lanırız, fakat matematikte rasyonel sayıların yanında, irrasyonel sayılar da mev-
cuttur. Ölçümlerimiz sırasında irrasyonel sayılar ortaya çıkmasalar da, teorik
argümanlarımız ve işlemlerimiz çoğunlukla bizi o yöne doğru itiverir. Yarıçapı
1/2 olan bir çemberin uzunluğu pi denilen ’irrasyonel’ sayıdır, ya da iki kenarı
eşit, bir birim uzunluğunda olan dik üçgenin hipotenüsü 2’nin kareköküdür,
bu sayı da irrasyonel bir sayıdır. ”İrrasyonel” kelimesinin İngilizce’de ’deli’,
’üşütük’, veya ’mantıksız’ olarak karşılık bulması da ilginçtir. İrrasyonel sayılar
virgülden sonra bile sonsuza kadar devam etmektedirler [3].
Bu sebeple, irrasyonel sayılar ile işlem yaparken, onları ’rasyonel’ bir sayı ile
yaklaşıklamak gerekir. Bunu yapmak için çoğu zaman virgülden sonra belli bir
basamak sonrasını atarız [3].
Başka bir alanı ele alalım: Doğa bilimleri sürekli fonksiyonlar ile bir yaklaşıklama
eylemi içindedirler. Doğanın ölçümsel gizemleri matematikte bir fonksiyon olarak
gösterilir, ve bu fonksiyonlar hiçbir zaman kesinkes, tıpatıp her seviyede ve her
molekülü anlatan betimler değildir. Elde olan, yaklaşıksal olarak ve şartlara göre
kesinlik derecesi bazen çok, bazen daha fazla olan bir ibaredir [3].
Bâzen de, doğal şartlara hiç alâkası olmayan ”pür matematiksel” bir fonksiy-
onu başka bir fonksiyon ile değiştirmeye mecbur kalabiliriz. Bunu da, genelde
başlangıç fonksiyonunu hesaplayabilmek için yaparız [3].
Şimdi yaklaşıklamak istediğimiz log() fonksiyonuna gelelim.
Log Nedir?

1
Log(x) fonksiyonu en basit şekilde f(t) = 1/t fonksiyonunun, 1 değeri ile x
değeri arasında kalan alanıdır [4]. Yani, bu fonksiyonunun entegralinin 1 ile x
değeri arasındaki değeridir (entegralin alan hesapladığını lise matematiğinden
biliyoruz).

Zx
1 d(ln x) 1
ln x = , =
1 t dx x

Sembolik olarak logaritma fonksiyonu, çarpma işlemlerini toplamaya çevirmemizi


sağladığı için matematiksel olarak çok yararlı bir araçtır. Zaten, keşfedilme se-
bebi de budur. Bu yaygın kullanım, uygulamalar için logaritmanın bir aşamada
hesaplanmasını gerektirmektedir. Fakat, görüldüğü gibi 1/t fonksiyonu entegral
işleminden sonra güzel bir matematiksel fonksiyona dönüşmediği için, yaklaşıksal
yöntemlere gereksinim duymaktayız. Taylor açılımı işte burada imdadımıza yetişmektedir.
Örnek olarak, log(20) işleminin sonucunu Taylor serisinin yardımı ile hesaplay-
acağız. Niye Taylor açılımı? Çünkü log fonksiyonunun her dereceden türevi
mevcut, Taylor açılımı için de bu türevler lazım.
Log’un Açılımı
Log fonksiyonunu nasıl açarken, amatör bir başlangıç şöyle olabilirdi. Dikkat
edelim, şu anda sadece sembolik olarak işlem yapıyoruz.

f(x) = log(x)

1 00 −1
f 0 (x) = , f (x) = 2 , f 000 (x) = ..
x x

f 00 (a)
f(x) ≈ f(a) + f 0 (a)(x − a) + (x − a)2 + ...
2!

2
−1
1 2
f(x) ≈ log(a) + (x − a) + a (x − a)2
a 2!
Bu pek derli toplu bir açılım olarak gözükmüyor. a = 0 seçersek,

−1
1 2
f(x) ≈ log(a) + (x − a) + a (x − a)2 + ..
a 2!

−1
1 2
f(x) ≈ log(0) + x + 0 (x)2 + ..
a 2!
çıkar. log(0) tanımsızdır. Yani bu açılım işimize yaramayacak. Daha temiz bir
açılım için matematikçiler şu yöntemi bulmuştur.
log(x) yerine, log(1 + x) kullanalım.

f(x) = log(1 + x)

1 −1 2 000
f 0 (x) = , f 00 (x) = , f (x) = ...
1+x 1+x

f 000 (a)
f(x) ≈ f(a) + f 0 (a)(x − a) + (x − a)2 + ...
2!
a = 0 alırsak

−1
1 (1+a)2
f(x) ≈ log(1 + a) + (x − a) + (x − a)2
1+a 2!

−1
1 2
f(x) ≈ log(1) + (x) + 1 (x)2
1 2!

−1
1 2
f(x) ≈ 0 + (x) 1 (x)2
1 2!

x2 x3
f(x) ≈ x − + ...
2! 3!
Bu çok daha temiz oldu. Dikkat ederseniz, entegrali düzgün olmayan log()
fonksiyonunun Taylor açımı ne kadar temiz oldu. Bu fonksiyonu bilgisayar ile
hesaplamak çok basittir. Artık log(20)’yi hesaplamaya hazırız.

x2 x3
f(x) ≈ x − + ...
2! 3!

3
202 203
log(20) ≈ 20 − + ...
2! 3!

Ama dikkat! Açılan fonksiyonunu hesaplarken x’e verdiğimiz değerin a nok-


tasına yakın olması önemlidir.
Çok uzak noktalar (yukarıdaki log(20)’nin açılımının olduğu gibi) elimizdeki yeni
seriyi uzaklastiran (diverging) bir seri haline getirebilir. Bunun tersi olan yakınlasan
(converging) seriler, elinizdeki terim sayısını biz arttırdıkça, sabit bir sayıya doğru
yönelen serilere denir. Bizim amacımız hesap yapmak olduğuna göre, bir so-
mut sayıya doğru yönelen bir seriyi tabii ki tercih ederiz. Bu sebeple elimizdeki
serinin, istediğimiz x değeri için yakinlasan bir seri mi, yoksa uzaklasan bir seri
mi olduğunu çok iyi bilmek zorundayız.
log(1 + x)’in Taylor açılımı sadece −1
Burada, log aritmetiği yardımımıza erişiyor. Log işlemlerinde, bölmenin çıkarmaya,
çarpmanın toplamaya dönüştüğünü hatırlayalım. Yâni Log(x*y) = log(x) + log(y),
ve log(x/y) = log(x) - log(y) olur.
O zaman, log(20)’yi 1’den küçük sayılar kullanacak şekilde yeniden yazalım:

1
2 1 1
log(20) = log( 1
) = log( ) − log( )
40
2 40

x2 x3
log(1 + x) ≈ x − +
2! 3!
1
Not: (1 + x)’in 2
vermesi için x’in − 21 olması gerekir.

2 3
1 1 −1 −1
log( ) ≈ − − 2 + 2 − ...
2 2 2! 3!

Aynı şekilde 1/40 için durum aynıdır.

2 3
1 39 − 39 − 39
log( ) ≈ − − 40 − 40 + ...
40 40 2! 3!

Bu kadar! Sağ tarafta gözüken serilerin hesabını, bir Python programı ile yaptık.

def taylor_ile_log(bolum, bolen, taylor_ile_acilim_buyuklugu):


sum = 0
for i in range(1,taylor_ile_acilim_buyuklugu):
sum += np.power(-1, i+1) * (np.power(bolum/bolen, i) / i)

return sum

print taylor_ile_log(-39.0, 40.0, 160)

4
-3.68527101165

LISP

;;
;; Not: (/ 1 2) yazilirsa, Common Lisp 0 cevabi veriyor.
;; Bunun sebebi, 1 2 deyince, parametrelerin integer
;; (tamsayi) olarak anlasilmasiymis, parametreler tamsayi
;; olunca, sonucta tamsayi olarak donuyor. O yuzden kesirli
;; cevaplar almak icin, (/ 1.0 2.0) demek lazim.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun power (Base Exponent)


"Reproduced EXPT in case where Exponent is non-negative integer"
(cond
((= Exponent 0) 1)
((evenp Exponent)(Power (* Base Base) (/ Exponent 2)))
(t (* Base (Power Base (- Exponent 1))))) )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun basit-taylor-ile-log-of-1-bolu-2 ()
(+
(* +1 ;;; taylor serisinin birinci terimi
(/
(power (/ -1.0 2.0)
1)
1)
)
(* -1 ;;; taylor serisinin ikinci terimi
(/
(power (/ -1.0 2.0)
2)
2)
)
(* +1 ;;; taylor serisinin ucuncu terimi
(/
(power (/ -1.0 2.0)
3)
3)
)
;
; vs...vs..
;
)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun taylor-ile-log-hesapla (bolum bolen taylor-acilim-buyuklugu)
(let ((sum 0)(i 1))
(loop for i from 1 to taylor-acilim-buyuklugu do
(setq sum (+ sum (* (power -1 (+ i 1))
(/
(power (/ bolum bolen)

5
i)
i)
)))
)
sum)
)

(print "------------- 1/2 (yani log( 1 + (-1/2)) Hesabi -----")


(print "Basit kod")
(print (basit-taylor-ile-log-of-1-bolu-2))
(print "Daha cok taylor terimi kullanan kod")
(print (taylor-ile-log-hesapla -1.0 2.0 100))
(print "Bilgisayarin kendi log()'undan gelen sonuc")
(print (log (/ 1.0 2.0)))

(print "------------- 1/40 (yani log( 1 + (-39/40)) ------- ")


(print "160 taylor terimi")
(print (taylor-ile-log-hesapla -39.0 40.0 160))
(print "180 taylor terimi")
(print (taylor-ile-log-hesapla -39.0 40.0 180))
(print "200 taylor terimi")
(print (taylor-ile-log-hesapla -39.0 40.0 200))
(print "220 taylor terimi")
(print (taylor-ile-log-hesapla -39.0 40.0 220))
(print "240 taylor terimi")
(print (taylor-ile-log-hesapla -39.0 40.0 240))
(print "260 taylor terimi")
(print (taylor-ile-log-hesapla -39.0 40.0 260))
(print "Bilgisayarin kendi algoritmasina gore log(1/40)")
(print (log (/ 1.0 40.0)))
(print "--------------- Sonuc --------------------- ")

(print "log(1/2) - log(1/40)")


(print (- (taylor-ile-log-hesapla -1.0 2.0 100)
(taylor-ile-log-hesapla -39.0 40.0 200)))

(print "Bilgisayarin mevcut algoritmasinin verdigi ")


(print (log 20))

Kaynaklar
[3] Thomas, Thomas’ Calculus

6
Kesit Seviyeleri (Level Sets) ile İmaj Gruplamak
Bir dijital resimdeki bir kümeyi, grubu ortaya çıkartmak (segmentation) için bir
teknik daha, kesit seviyeleri kullanmak. Grup bulmak derken resimdeki diğerlerinden
daha ayrı duran, bizim çıplak gözle gördüğümüz bir grubu diğerlerinden ayırıp
etrafındaki sınırlar çizmek, ve bunları otomatik olarak yazılımın yapmasını sağlamak.
Kesit seviyeleri tekniği her ne kadar dışarıdan bir eğriyi belli bir enerji fonksiy-
onunu minimize ederek kümenin etrafında “sarmalayan” yılan (snake) tekniğine
benzese de, aslında daha derin ve kuvvetli özellikleri olan bir yaklaşımdır. Yılan
tekniğinde eldeki bir eğriyi bizzat değiştirerek grup etrafını sarmalasına uğraşıyoruz.
Kesit seviyeleri ile grubu tanımlayan manipüle ettiğimiz sınıların kendisi değil
bir yansımadan dolaylı elde edilen ama kendisi daha yüksek boyutta olan başka
bir fonksiyon.
Alttaki görüntüler daha iyi açıklayabilir,

İmajın düzlemde olduğunu düşünürsek o görülen kırmızı çizgiler kesit seviyesi


(φ = 0 için). İmaj düzlemi, ve kesit seviyesi iki boyutlu, manipüle edilen ise
üç boyutlu bir φ fonksiyonu, ve gruplamayı yapan bu fonksiyonun sıfır kesit
seviyesindeki kontur çizgileridir, yani φ(x, y, t) = 0 ne ise gruplama, küme (seg-
ment) odur.
Altta, değişen φ’nin imaj düzlemindeki değişen kesit seviyesini görebiliyoruz.

1
Peki φ fonksiyonunu imaj üzerindeki yakın duran pikselleri göz önüne alarak
(ki kesit seviyesi onların etrafını sarsın) nasıl değiştireceğiz? İşte kesit seviyeleri
matematiği burada devreye giriyor.
Ana yüzey fonksiyonu φ(x, y), ya da vektörel olarak φ(~x), daha basit φ(x) diye-
lim, bu yüzeyi t ile parametrize edersek kesit seviyesini

φ(x(t), t) = 0

ile tanımlarız. Üstteki eşitliği t için elde edilen x için t anındaki yüzeyin fonksiy-
onu olarak düşünebiliriz. Şimdi sıfır seviyesindeki kontur eğrisinin değişimini
takip etmek istediğimiz için [5], üstteki eşitliğin t’ye göre değişiminin açılımını
görmek istiyoruz. Hatırlarsak pozisyonun türevi hızdır, ve eğer hızı bilirsek
yüzeyin hareketini modelleyebiliriz.

∂φ(x(t), t)
=0
∂t
Zincirleme Kuralını uygulayınca

∂φ ∂x(t) ∂φ
+ =0
∂x(t) ∂t ∂t

Tanım itibariyle ∂φ/∂x(t) kısmi türev yüzeyimizin gradyanı, bunu temel çok
boyutlu Calculus’tan biliyoruz. Diğer notasyonu da biraz kısaltınca

∇φxt + φt = 0

Üstte eğrinin hareketinin φ’ye normal / dik olduğunu söylemiş olduk, eğer yönü
∇φ
birim vektör olarak göstermek gerekirse, ||∇φ|| . Şimdi hızın kendisi lazım, düzlemdeki
yere bağlı olarak değişebilecek bir F kuvveti ile yönü çarparak yönsel hızı elde
∇φ
edebiliriz, xt = F ||∇φ|| . Yerine koyarsak,

2
∇φ
∇φF + φt = 0
||∇φ||

||∇φ||2
F + φt = 0
||∇φ||

F||∇φ|| + φt = 0

Biraz daha organize edince kesit seviyeleri denklemini elde ediyoruz.

φt = −F||∇φ||

Bu bize yüzeyin değişim hızı φt ’yi veriyor.


Hesaplama
φ’nin başlangıç değerlerini biliyorsak ve değişim hız formülünü baz alarak hareket
denklemini çözebiliriz / zamanda ileri doğru taşıyabiliriz. Yani bulmak istediğimiz
herhangi bir t anındaki φ. Hesabı yapmanın en basit yolu Sonlu Farklar (Finite
Differences) yöntemi ile. Temel Calculus’tan hatırlarsak,

f(x + ∆x) − f(x)


f 0 (x) =
∆x

Bunu φ için uygularsak,

∂φ(x(t), t) φ(x(t), t + ∆t) − φ(x(t), t)


=
∂t ∆t

∆tφt = φ(x(t), t + ∆t) − φ(x(t), t)

φ(x(t), t + ∆t) = φ(x(t), t) + ∆tφt

Şimdi φt için daha önce bulduğumuz formülü koyarsak,

φ(x(t), t + ∆t) = φ(x(t), t) − ∆tF||∇φ||

Böylece değişim fonksiyonunu elde etmiş olduk. Yapay Öğrenim konusunu bilen-
lere üstteki formül tanıdık gelebilir, φ üzerinde t bazlı olarak gradyan inişi (gra-
dient descent) yapmış oluyoruz bir bakıma.

φ 0 = φ + ∆tF||∇φ||

3
Not: Üstte +∆tF var fakat türetimden −∆tF gelmesi gerekiyor. Bu nasıl oldu?
Eğer ilerideki kodda işareti değiştirsek eksinin işlemeyeceğini görürdük, artı ol-
ması gerekiyor. Bu gradyan tanımıyla alakalı, fakat istenen işarete erişmek için
sonlu farklar başlangıcında ufak bir değişiklik yeterli olurdu.
Şimdi F konusuna gelelim; bu F’nin seçilmesi kesit seviyesi yöntemimize direk
etki edecektir. Sonuç olarak eğriyi belli bir yönde, ve hızda ittiren “kuvvet”
budur. F resmin her noktasında tanımlı bir nevi hız, kuvvet alanı (velocity field)
olarak görülebilir, her noktada bize φ’nin hareketinin yönünü ve büyüklüğünü
verir.
O zaman düşünürsek, imajda gruplama yapmak istiyoruz, ve alttaki gibi bir
resim var diyelim,

F’nin ortadaki objenin sınırlarına kadar yüksek olmasını ama sınırlarda çok az
hatta sıfır olmasını isteyebiliriz, değil mi? Bu dolaylı olarak obje tanımlamayı
gerçekleştirecektir, çünkü φ yüzeyi objeye gelinceye kadar hızla ilerleyecek, ardından
obje çevresine geldiği noktalarda yavaşlayacaktır, ve yan etki olarak kesit seviyesi
nesneyi sarmalamış olur, ve bu noktada gruplamayı bitmiş kabul edebiliriz.
F’yi o zaman direk imajın kendisinden hesaplayalım, ve onu bir nevi kenar algılayıcı
(edge detector) olarak görelim. Eh en basit kenar bulucu gradyan olduğuna göre
imajın gradyanını almak yeterli olacaktır. I imajı için g gradyanı [6],

1
g(I) =
1 + ||∇I||2

Hepsini bir araya koyunca alttaki kod yazılabilir,

from skimage import color, io


import scipy.ndimage

def grad(x):
return np.array(np.gradient(x))

def norm(x, axis=0):


return np.sqrt(np.sum(np.square(x), axis=axis))

def stopping_fun(x):
return 1. / (1. + norm(grad(x))**2)

4
def default_phi(x):
# phi yuzeyini imaj disindaki 5 piksel genisligindeki bantta 1
# bant icinde ise -1 olarak tanimliyoruz
phi = np.ones(x.shape[:2])
phi[5:-5, 5:-5] = -1.
return phi

img = io.imread('twoObj.bmp')
img = color.rgb2gray(img) # grilestir
img = img - np.mean(img) # ortalamayi cikart
# puruzsuzlestirme uygula yanyana pikseller daha benzer olsun
img_smooth = scipy.ndimage.filters.gaussian_filter(img, sigma=2)

F = stopping_fun(img_smooth)

dt = 1.
n_iter = 100
phi = default_phi(img)
for i in range(n_iter):
dphi = grad(phi)
dphi_norm = norm(dphi)
dphi_t = F * dphi_norm
phi = phi + dt * dphi_t
if i%10==0:
plt.imshow(img,cmap = 'gray')
plt.contour(phi, levels=[0],colors=['red'])
plt.savefig('img2/out-%03d.png' % i)
plt.close()

İşlemden seçilmiş üç kare alttadır,

Kesit seviyeleri tekniğinin faydalarını görmek zor değil; üç boyutlu fonksiyonu
daha esnek yönlerde değiştirebileceğimiz için onu düzlemdeki yansımaları bir-
birinden kopuk duran (ama alakalı) obje gruplarını bile bulup çıkartabilir.

5
Eski Yazı
Kesit Seviyeleri, Kenar Bazlı İmaj Gruplamak
Bir dijital imajı renklere, objelere göre belli parçalara bölmek (segmentation) için,
matematiksel bir formül kullanmak iyi çözümlerden biridir. Bunu yapmanın bazı
yolları var. Basitleştirerek bir örnek verelim: diyelim ki gruplama için elimizdeki
formül bir yuvarlak formülü x2 + y2 − c = 0, ki√ c bir sabit. Bu formülü x ve y
kordinatları üzerinde bastığımız zaman radius’u c olan bir çember elde ederiz.
Gruplama için bu çemberi büyütüp küçültebildiğimizi farzedelim, çember imaj
üzerindeki istediğimiz bölüme en iyi uyduğu anda gruplamayı başarılı olarak
kabul ediyoruz.
Fakat problem şurada: eğer imajda birden fazla grup var ise, o zaman birden fa-
zla çember gerekecektir, bu sefer algoritmik olarak üstteki formülü ikinci, üçüncü
kere yaratmamız, ve o formüllerin o gruplara uyumunu ayrı ayrı takip etmemiz
gerekirdi. Ya da diyelim ki özyineli (iterative) bir uydurma işlemi takip ediyoruz,
bu işlem sırasında belki iki çemberin birleşmesi gerekse, o zaman iki formülü
silip, yerine yenisini oluşturmakla uğraşmak gerekli olacaktı. Bunlar hem matem-
atiksel, hem kodlama açısından külfet oluşturacaktır.
Kesit Seviyeleri kavramını kullanarak bu işi daha basitleştirebiliriz. Diyelim ki
bölme görevini yapan φ adli fonksiyonumuzu 2 boyutlu olmak yerine 3 boyutlu
eksende tanımladık, ve, 2 boyutta bölme yapma görevini onun bir kesitine verdik.
Kesit derken, alttaki üç boyutlu fonksiyonu yatay olarak bir noktadan “kestiğimizi”
farz ediyoruz, ve o kesit üzerinde düşen φ değerlerine bakıyoruz.
Bakıç açışımızı, tanımlamamızı değiştirerek, bazı avantajlar elde etmeyi umuy-
oruz aslında. Altta iki tane φ fonksiyonu ve onların altında kesitlerini görebiliriz.
Kesit Seviyeleri tekniğini kullanarak elde ettiğimiz avantaj nedir? Artık sadece
tek bir φ fonksiyonu kullanarak 2 boyutlu imajımız üzerinde birbirinden ayrı
gruplamalar yaratabiliyoruz. Bu gruplar birbiri ile birleşebilir, ayrılabilir, bu
artık bizi ilgilendirmiyor. Biz sadece 3. boyuttaki φ fonksiyonunu değiştirmekle
uğraşacağız, imaj üzerindeki gruplamalar ise o fonksiyonun 2. boyuta yansıması
(projection) üzerinden kendiliğinden gerçekleşecekler.
Matematiksel olarak φ fonksiyonunu nasıl temsil ederiz? φ fonksiyonu x, y,
boyutlarını alıp bize bir üçüncü z boyutu döndürmeli, ayrıca bu fonksiyonu imajı
parçalarına ayırma işlemini gerçekleştirmek için kademeli olarak değiştirmeyi
planladığımıza göre, o zaman bir t değişkeni de gerekiyor. Yani φ(x, y, t) fonksiy-
onu. Gruplama için kullanılacak kesiti ise sıfır kesiti olarak alalım, yani φ(x, y, t) =
0. Doğal olarak

d
(φ(x, y, t) = 0) = 0
dt

Şimdi x, ve y değişkenlerinin zaman göre değişimini formüle bir şekilde dahil


etmek lazım. Bunun için sıfır kesit seviyesi üzerinde bir parçacık hayal edilir, ve

6
bu parçacığın gittiği yol x(t), ve y(t) olarak tanımlanır. O zaman

d
(φ(x(t), y(t), t)) = 0
dt

Tam diferansiyel formülünden hareketle:

∂φ ∂φ ∂φ
d(φ(x(t), y(t), t) = dx + dy + dt = 0
∂x ∂y ∂t

d(φ(x(t), y(t), t)) ∂φ dx ∂φ dy ∂φ


= + + =0
dt ∂x dt ∂y dt ∂t

∂φ dx ∂φ dy
= + + φt = 0 (1)
∂x dt ∂y dt

Temsilen daha kısa bir işaret kullanmak gerekirse, 5 ile φ’nin gradyanını (gra-
dient) alarak, elde edilecek vektörün nokta çarpımını kullanabiliriz. O zaman
formül (1) daha kısa olarak:

~ =0
φt + 5φ · V

olarak temsil edilebilir, ki


 
∂φ ∂φ
5φ = ,
∂x ∂y
 
~ = dx dy
V ,
dt dt

İki vektörün nokta çarpımı bilindiği gibi sırayla her iki vektörün sırasıyla uyan
elemanlarının birbirleri ile çarpılması ve o çarpımların toplanmasıdır.
~ vektörü neyi temsil eder? Formüle göre bu vektör φ’nin üzerindeki değişimi
V
etkiliyor, ve bu değişimler t’nin değişimine göre tanımlandığına göre bu değerler
“hız” olarak tanımlanabilir. İmaj bağlamında düşünürsek mesela φ renklerin
aynı olduğu yerlerde yüksek hızda, renklerin değiştiği yerler düşük hızda değişebilir
~ ile gösterebiliriz.
şeklinde bir kurgu yapılabilir, işte bu bölgelerde değişiminin hızını V
~ yerine kesit seviyelerine dik olan (normal) vektörler ile çalışmak isteseydik,
V
~ dik ve teğet bileşenlerine ayırarak tekrar temsil edebilirdik: V
V’yi ~ = VN N
~ + VT ~T .
Bu formülde ~T teğet, N
~ dik vektörler, VN ve VT skalar. Yerine koyalım:

~ + VT ~T ) = 0
φt + 5φ · (VN N

7
~ = 5φ
φ’ye göre dik vektörün diğer bir formülü N |5φ|
olduğuna göre


φt + (5φ · VN + 5φ · VT ~T ) = 0
| 5 φ|

Devam edelim: 5φ yüzeye dik olduğuna göre, bu dik vektörün teğet olan ~T ile
noktasal çarpımı sıfır değerini verecektir, o çarpım formülden atılabilir. Kalanlar:


φt + (5φ · VN )=0
| 5 φ|

Daha da kısaltabiliriz: 5φ · 5φ = | 5 φ|2 olduğunu biliyoruz, gradyanın ken-


disi ile noktasal çarpımı, o gradyan vektörünün uzunluğunun karesidir. Daha
genel olarak, bir vektörün uzunluğu, o vektörün kendisi ile noktasal çarpımının
kareköküdür. O zaman en son formülde bu çarpımı gerçekleştirip, uzunluk olarak
yazalım:

| 5 φ|2
φt + VN =0
| 5 φ|

φt + VN | 5 φ| = 0

Şimdi bu formül hakkında biraz anlayış geliştirelim. Eğer elimizdeki bir φ seviye
kesitinin şeklen olduğu gibi kalmasını ama sadece küçülmesini isteseydik, φ’nin
normalinin tersi yönünde bir büyüme tanımlamamız gerekirdi. Normal vektör
dışa doğru işaret ettiğine göre üstteki formülde mesela VN = −1 tanımlayabilirdik.
O zaman

φt + | 5 φ| = 0

φt = −| 5 φ|

Hesapsal olarak bunu nasıl gerçekleştiririz? 80 x 80 boyutunda bir matris içinde


φ fonksiyonu ayrıksal olarak tutalım. Yani 80 tane x, 80 tane ayrı y değeri var, her
x ve y değerlerin kombinasyonlarına tekabül eden φ değerleri bu matris içinde.
Gradyanın ne olduğunu hatırlayalım. Gradyan
 
∂φ ∂φ
5φ = ,
∂x ∂y

olarak tanımlıdır, ve her (xi , yi ) noktasındaki φ(xi , yi ) değerine göre değişik bir
vektör sonucunu getirecektir. Bilgisayar dünyasında parçalı türevler hesapsal
“farklılıklara” dönüşürler, phi matrisindeki farklılıkları Python ile

8
gradPhiY, gradPhiX = np.gradient(phi)

olarak hesaplayabiliriz. Üstte elimize geçen gradyan dizinlerindeki değerler ile


| 5 φ| büyüklüğünü hesaplayabiliriz, ve bu sonucu φ üzerindeki değişim oranı
φt olarak kabul ederiz. O zaman φt ile zaman t değimi dt çarptığımız zaman ele
geçecek olan φ’nin değişimidir. Döngünün her basamağında eski phi değerlerine
bu farkları eklediğimiz zaman φ fonksiyonu istediğimiz gibi evrilecektir.
Alttaki kodda bizim başlangıç φ’miz kenarlardan w uzaklığında içi boş bir kutu
olacak.
İmaj Gruplamak
İmajı bölümlere ayırmak için (segmentation) birkaç faktörün bileşimi kullanılıyor.
Köşeleri kullanan aktif kontur (edge based active contour) yönteminde ortalama
eğim ve imajın piksel değerlerinin farklılıkları (image gradient) aynı anda kul-
lanılır. Yani kesit seviyesini ilerletirken hızı hem eğime oranlıyoruz, hem de imaj
piksel renk değerleri arasındaki farka ters oranda hızlandırıyor, ya da yavaşlatıyoruz.
Böylece kesit seviyemiz renk farklılığı çok olmayan yani büyük bir ihtimalle tek
bir objeye ait bir bölgede hızla ilerliyor, büyük renk farkının olduğu büyük bir
ihtimalle bir kenar noktasına gelince ise yavaşlıyor. O sırada kesit seviyesinin
geri kalan tarafları tabii ki başka hızlarda hareket ediyor olabilirler, zaten işin püf
noktası burada, sonunda resim bölgelere ayrılmış oluyor.
Bitirirken önemli gözlemi vurgulayalım. Problemi matematiksel olarak temsil
ederken, hedefe doğru türetirken sürekli (continous) alemde, sürekli, kesintisiz
fonksiyonlarla iş yapıyoruz. Hesaplama anı gelince sürekli fonksiyonları ayrıksal
(discrete) hale çeviriyoruz, işte uygulamalı matematiğin hesapsal kısmı burada
devreye giriyor. Fakat diferansiyel denklemler, fonksiyonlar, türevler gibi sürekli
matematiğin kavramları çok önemli, bunlar olmasa problemi soyut bir şekilde
temsil edemez, ve basitleştiremezdik. Temel matematiğin kavramlarını kullanırken
yüzyılların matematiksel bilgisi devreye girebiliyor, matematiğin en yoğun şekilde
kullanıldığı fizikten bol bol teknik alınabilir. Yani söylemek istediğimiz problemi
çözmek için hemen kodlamaya başlamıyoruz, düşünsel eylemin önemli bir kısmı
matematiksel formüllerle (belki kalem kağıtla) yapılıyor.

import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as signal
import scipy.ndimage as image
import time

def gauss_kern():
""" Returns a normalized 2D gauss kernel array for convolutions """
h1 = 8
h2 = 8
x, y = np.mgrid[0:h2, 0:h1]
x = x-h2/2
y = y-h1/2
sigma = 10.0

9
g = np.exp( -( x**2 + y**2 ) / (2*sigma**2) );
return g / g.sum()

Img = plt.imread("twoObj.bmp")
Img = Img[::-1]
g = gauss_kern()
Img_smooth = signal.convolve(Img,g,mode='same')
Iy,Ix=np.gradient(Img_smooth)
absGradI=np.sqrt(Ix**2+Iy**2);
rows, cols = Img.shape

# initial function phi - level set is a square 4 pixels


# away from borders on each side, in 3D it looks like an empty
# box
c0=4
w=4
nrow, ncol=Img.shape
phi=c0*np.ones((nrow,ncol))
phi[w+1:-w-1, w+1:-w-1]=-c0

# edge-stopping function
g = 1 / (1+absGradI**2)

# gradient of edge-stopping function


gy,gx = np.gradient(g)

# gradient descent step size


dt=1

# number of iterations after which we reinitialize the surface


num_reinit=10

phiOld=np.zeros((rows,cols))

# number of iterations after which we reinitialize the surface


iter=0

while iter<150:
# gradient of phi
gradPhiY, gradPhiX = np.gradient(phi)
# magnitude of gradient of phi
absGradPhi=np.sqrt(gradPhiX**2+gradPhiY**2)
# normalized gradient of phi - eliminating singularities
normGradPhiX=gradPhiX/(absGradPhi+(absGradPhi==0))
normGradPhiY=gradPhiY/(absGradPhi+(absGradPhi==0))

divYnormGradPhiX, divXnormGradPhiX=np.gradient(normGradPhiX)
divYnormGradPhiY, divXnormGradPhiY=np.gradient(normGradPhiY)

# curvature is the divergence of normalized gradient of phi


K = divXnormGradPhiX + divYnormGradPhiY
tmp1 = g * K * absGradPhi
tmp2 = g * absGradPhi
tmp3 = gx * gradPhiX + gy*gradPhiY
dPhiBydT =tmp1 + tmp2 + tmp3

10
phiOld=phi
# level set evolution equation
phi = phi + ( dt * dPhiBydT )
iter=iter+1
if np.mod(iter,20)==0:
f=plt.figure()
plt.imshow(Img, cmap='gray')
CS = plt.contour(phi,0, colors='r')
plt.savefig('/tmp/level_2_%03d.png' % iter)

Ortalama Eğim (Mean Curvature) Kullanmak


Eğer imaj içindeki değer farklılıklarını hız için kullanmak yerine yerine sıfır ke-
sit seviyesinin herhangi bir noktada ne kadar “eğri” olduğuna göre ilerlemesini
işletseydik ne olurdu? Diyelim ki çok eğri bölgelerde çok hızlı, az eğik (düz,
düze yakın) bölgelerde ilerleme az hız istiyoruz. O zaman hangi şekille başlarsa
başlasındalar φ kesiti sonuçta bir çember şekline doğru evrilecektir. Ortalama
eğim (mean curvatüre) hesabı için şu denklem kullanılır:
 

κ = −div
| 5 φ|

Bu formul nereden geliyor?


Eğim (Curvature)
Kesit seviyeleri tekniğinde bir eğri normal formda değil, dolaylı (implicit) bir
fonksiyon ile F(x, y) = 0 olarak gösterilir. Bu fonksiyonun tam diferansiyelini
alırsak,

dF = Fx dx + Fy dy = 0

dy = −Fx /Fy dx

dy df
y0 = = −Fx /Fy = f 0 (x) =
dx dx

11
Burada bir faraziye daha var, o da aslında ilk verilen formülde olmasa bile y =
f(x) olarak kabul etmemiz, yani F(x, y) nasıl bir formül olursa olsun, y’nin x’leri
içerecek şekilde tekrar düzenlenebileceğini farz etmemiz, böylece F(x, f(x)) ola-
bileceğini söylemiş oluyoruz [4].
Şimdi y 0 ifadesinin türevini bir daha alalım. Yukarıdaki y 0 formülünde en sağ
taraf bir bölme işlemi içerdiği için burada Calculus’un Bölümler Kuralını (Quo-
tient Rule) uygulamamız lazım (detaylar için Bölüm Kuralı yazısına bakınız). Bu
kural şöyle gösterilir:

vdu udv
 
d u −
= dx 2 dx
dx v v

Bölümler Kuralı için u ve v tanımları nedir?

u = −Fx (x, f(x))

v = Fy (x, f(x))

O zaman

du dFx
v = Fy
dx dx

dv dFy
u = −Fx
dx dx

Bunlardan mesela dFx /dx üzerinde Zincirleme Kanunu (Chain Rule) uygulamak
lazım (bu kural tam integral kuralının bir sonucu).

dFx (x, f(x)) ∂Fx ∂Fx df


= (x, f(x)) +
dx ∂x ∂y dx

= Fxx (x, f(x)) + Fxy (x, f(x))f 0 (x)

dFy (x, f(x))


= Fxy (x, f(x)) + Fyy (x, f(x))f 0 (x)
dx

Zincirleme Kanunu niye üstteki şekilde açıldı? Tam Diferansiyeli bir daha hatırlayalım:

∂f ∂f
df = dx + dy
∂x ∂y

12
df ∂f dx ∂f dy
= +
dx ∂x dx ∂y dx

df ∂f ∂f dy
= +
dx ∂x ∂y dx

O zaman formüller (1) (2) (3) ve (4) bir araya konulursa,

Fy Fxx − Fy Fxy FFyx − Fx Fxy + Fx Fyy FFyx


00
y =−
F2y

F2x Fyy
Fy Fxx − Fxy Fx − Fx Fxy + Fy
y 00 = −
F2y

Üstteki bölümün hem bölen, hem bölünen terimlerini Fy ile çarparsak, ve sadeleştirirsek

F2y Fxx − 2Fxy Fx Fy + F2x Fyy


y 00 = −
F3y

Şimdi surada [2] türetimi gösterilen eğim formülüne bakalım. Not: Eğer

x 0 y 00 − y 0 x 00
κ=  3/2
02
x +y 02

formülünün alttaki formüle nasıl dönüştüğü tam anlaşılır değilse, hatırlayalım


ki, y = f(x), ve x 0 = 1, ve x 00 = 0.
Bu formülün Courant [1] sf. 231’de benzer bir formunu görüyoruz (Bu arada o
karmaşık formül yerine yaklaşıksal olarak hesaplama sırasında sadece f 00 kullan-
mak ta mümkün [3, giriş bölümü])

f 00
κ=
(1 + f 02 )3/2

Bu formüldeki f 00 yani y 00 için üstte bulduğumuz sonucu, f 0 yani y 0 için bu yazının


başındaki formülü koyarsak,

F2y Fxx − 2Fxy Fx Fy + F2x Fyy



F3y
κ=
(1 + f 02 )3/2

Bölen kısmı nedir?

13
  2 3/2
02 3/2 −Fx
(1 + f ) = 1+
Fy

3/2
F2x

= 1+ 2
Fy

3/2
F2y + F2x

=
F2y

= (F2y + F2x )3/2 (F−2


y )
3/2

= (F2y + F2x )3/2 F−6/2


y

= (F2y + F2x )3/2 F−3


y

Yerine koyarsak,

F2y Fxx − 2Fxy Fx Fy + F2x Fyy



F3y
κ=
(F2y + F2x )3/2 F−3
y

3
F−3
y ve Fy birbirlerini iptal ederler ve sonuç:

F2y Fxx − 2Fxy Fx Fy + F2x Fyy


κ=
(F2y + F2x )3/2

Üstteki ünlü eğim formülüdür.


Bu eğim formülünün diğer bir şekli şöyledir (F yerine φ kullanırsak)


κ=5·
| 5 φ|

Bunun okunuş şekli “birim normal gradyanın uzaklaşım ölçüsü (divergence of


the unit normal gradient)” şeklindedir. Acaba bu formül, (5). formül ile uyumlu
mu?

∇φ
κ=∇·
|∇φ|

14
(φx , φy )
=∇· q
φ2x + φ2y

   
φx  + ∂y q φy
= ∂x q 
2 2
φx + φy 2 2
φx + φy

φxx φx (φx φxx + φy φxy ) φyy φy (φx φxy + φy φyy )


=q − 2 2 3/2
+q −
φ2x + φ2y (φx + φy ) φ2x + φ2y (φ2x + φ2y )3/2

φxx (φ2x + φ2y ) − φx (φx φxx + φy φxy ) + φyy (φ2x + φ2y ) − φy (φx φxy + φy φyy )
=
(φ2x + φ2y )3/2

φxx φ2y − 2φx φy φxy + φyy φ2x


=
(φ2x + φ2y )3/2

Bu formül bizim (5). formül ile tıpatıp aynı.


Üstteki işlemlerde uzaklaşım ölçüsü (divergence) operatörü ∇· ile gradyan op-
eratörü ∇ arasındaki farkı belirtelim: ∇· operatörü F(x, y) üzerinde kısmi türevlerin
toplamını verir, yani bir skalar tek sayı döndürür. Gradyan ise her bir elemanı bir
kısmi türeve tekabül eden bir vektör geri getirir.
Python Numpy kodlaması bağlamında, daha önce Kesit Seviyeleri yazısında ayrıksal
olarak bir phi değişkeni içindeki bir fonksiyon üzerinde eğimselliği şöyle hesaplamıştık:

1 gradPhiY, gradPhiX = np.gradient(phi)


2 absGradPhi=np.sqrt(gradPhiX**2+gradPhiY**2)
3
4 normGradPhiX=gradPhiX/(absGradPhi+(absGradPhi==0))
5 normGradPhiY=gradPhiY/(absGradPhi+(absGradPhi==0))
6
7 divYnormGradPhiX, divXnormGradPhiX=np.gradient(normGradPhiX)
8 divYnormGradPhiY, divXnormGradPhiY=np.gradient(normGradPhiY)
9
10 K = divXnormGradPhiX + divYnormGradPhiY

∇φ
Bu satırların ∇ · |∇φ| ifadesiyle birebir uyum gösterdiğini herhalde görebiliyoruz.
∇φ
Satır 1, ∇φ ifadesidir. Satırlar 4-5 |∇φ| işlemini gerçekleştiriyor, gradyanı onun
uzunluğuna (magnitude) bölerek onu birim vektörü haline getiriyor. Satırlar 7-10
tekrar sonucun gradyanını bir daha alıyor, ama bu sefer hesapsal kısmi türevleri
birbiriyle topluyor, böylece uzaklaşım ölçüsü (divergence) hesaplanmış oluyor.
Tüm bu işlemlerin sonucu eğimsellik κ oluyor.

15
Dikkat edilirse Python kodundaki K yani κ, N x N boyutlu bir matristir, bu
mantıklı çünkü κ hesabı için kullandığımız Fx , Fy gibi türevler aslında Fx (x, y),
Fy (x, y) formüllerine sahipler, yani her x, y kombinasyonu için farklı bir sonuç
döndürebilirler. Bu sebeple K yani κ φ fonksiyonunun her x, y noktası için tanımlıdır.
Bazen literatürde ∇· yerine div(..) kullanıldığını görebilirsiniz, bu operatörlerin
ikisi de aynıdır.
Kodu görelim,

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

def plot_phi(phi):
fig = plt.figure()
ax = Axes3D(fig)
x = []
y = []
for (i,j),val in np.ndenumerate(phi):
x.append(i)
y.append(j)
ax.plot(xs=x, ys=y, zs=phi.flatten(),
zdir='z', label='ys=0, zdir=z')

f, ax = plt.subplots()

# initial function phi - level set is a square 4 pixels


# away from borders on each side, in 3D it looks like an empty
# box
c0=2; w=2
nrow, ncol= (30,30)
phi=c0*np.ones((nrow,ncol))
phi[w+1:-w-1, w+1:-w-1]=-c0

dt=1.

phiOld=np.zeros((nrow,ncol))

iter=0

while iter < 50:


# gradient of phi
gradPhiY, gradPhiX = np.gradient(phi)
# magnitude of gradient of phi
absGradPhi=np.sqrt(gradPhiX**2+gradPhiY**2)

# normalized gradient of phi - eliminating singularities


normGradPhiX=gradPhiX/(absGradPhi+(absGradPhi==0))
normGradPhiY=gradPhiY/(absGradPhi+(absGradPhi==0))

divYnormGradPhiX, divXnormGradPhiX=np.gradient(normGradPhiX)
divYnormGradPhiY, divXnormGradPhiY=np.gradient(normGradPhiY)

16
# curvature is the divergence of normalized gradient of phi
K = divXnormGradPhiX + divYnormGradPhiY
dPhiBydT = K * absGradPhi # makes everything circle

# level set evolution equation


phi = phi + ( dt * dPhiBydT )
if iter % 10 == 0:
CS = plt.contour(phi,0,colors='r')
plt.hold(False)
plt.savefig('img1/level_1_'+ str(iter) + '.png')
#plot_phi(phi)
plt.savefig('img1/phi_1_'+ str(iter) + '.png')
iter += 1

Kaynaklar
[1] Courant, Introduction to Calculus and Analysis Volume 2, sf. 223-232
[2] Wolfram Mathworld, Curvature, http://mathworld.wolfram.com/Curvature.
html
[3] Strang, Computational Science and Engineering,
[4] Bayramlı, Diferansiyel Denklemler, Türevler
[5] Kristiadi, Level Set Method Part I: Introduction, https://agustinus.kristia.
de/techblog/2016/11/05/levelset-method/
[6] Kristiadi, Level Set Method Part II: Image Segmentation, https://agustinus.
kristia.de/techblog/2016/11/20/levelset-segmentation/
[7] Lombaert, Level set method: Explanation, https://profs.etsmtl.ca/hlombaert/
levelset/

17
Radyo Dalgaları

import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as signal
dir = "/home/burak/Documents/Dropbox/Public/data"
extract_data = np.fromfile(dir + "/fm1.dat",dtype="uint8")
interleavedData = extract_data[0::2] + 1j*extract_data[1::2]

plt.title("SpectoGram of 'signal' loaded from file")


plt.xlabel("Time")
plt.ylabel("Frequency")
plt.specgram(interleavedData, NFFT =1024, Fs=1140000)
plt.savefig('compscieng_app60wave_07.png')

plt.title("PSD of interleaved Data")


plt.psd(interleavedData, NFFT=1024, Fs=1140000)
plt.savefig('compscieng_app60wave_08.png')

1
calculate_range = max(interleavedData) - min(interleavedData);
data = (interleavedData - min(interleavedData))/ calculate_range
x1 = (data*2) - 1
plt.title("SpectoGram of signal post normalization")
plt.xlabel("Time")
plt.ylabel("Frequency")
plt.specgram(x1, NFFT =1024, Fs=1140000)
plt.savefig('compscieng_app60wave_09.png')

plt.title("PSD of normalized signal")


plt.psd(x1, NFFT=1024, Fs=1140000)
plt.savefig('compscieng_app60wave_10.png')

2
Fs = 1140000
fc = np.exp(-1.0j*2.0*np.pi* 250000/Fs*np.arange(len(x1)))
x2 = x1*fc
f_bw=200000
Fs=1140000
n_taps=64
lpf= signal.remez(n_taps, [0, f_bw, f_bw +(Fs/2-f_bw)/4,Fs/2], [1,0], Hz=Fs)
plt.xscale('log')
plt.title('Filter Frequency Response')
plt.xlabel('Frequency')
plt.ylabel('Amplitude')
plt.margins(0,1)
plt.grid(which='both',axis='both')
plt.plot(w, 20*np.log10(abs(h)))
plt.savefig('compscieng_app60wave_11.png')

w,h = signal.freqz(lpf)
x3 = signal.lfilter(lpf, 1.0, x2)
plt.psd(x2, NFFT=1024, Fs=1140000, color="blue") # original
plt.psd(x3, NFFT=1024, Fs=1140000, color="green") # filtered
plt.title("PSD of output signal from LPF Vs Original Signal")
plt.savefig('compscieng_app60wave_12.png')

3
dec_rate = int(Fs/f_bw)
x4 = signal.decimate(x3, dec_rate)
Fs_x4 = Fs/dec_rate
plt.psd(x4, NFFT=1024, Fs=Fs_x4, color="blue")
plt.title("PSD of deimated signal")
plt.savefig('compscieng_app60wave_13.png')

y = x4[1:] * np.conj(x4[:-1])
x5 = np.angle(y)
plt.psd(x5, NFFT=1024, Fs=Fs_x4, color="blue")
plt.title("PSD of Post Frequency Discrimination")
plt.savefig('compscieng_app60wave_14.png')

4
d = Fs_x4 * 75e-6 # Calculate the # of samples to hit the -3dB point
r = np.exp(-1/d) # Calculate the decay between each sample
b = [1-r] # Create the filter coefficients
a = [1,-r]
x6 = signal.lfilter(b,a,x5)
plt.psd(x6, NFFT=1024, Fs=Fs_x4, color="blue")
plt.title("PSD of signal Post DeEmphasis")
plt.savefig('compscieng_app60wave_15.png')

d = Fs_x4 * 75e-6 # Calculate the # of samples to hit the -3dB point


r = np.exp(-1/d) # Calculate the decay between each sample
b = [1-r] # Create the filter coefficients
a = [1,-r]
dec_rate = int(Fs/f_bw)
x7=signal.decimate(x6,dec_rate)
x7*= 10000 / np.max(np.abs(x7)) # scale so it's audible
x7.astype("int16").tofile("radio.raw")
aplay radio.raw -r 100000.0 -f S16_LE -t raw -c 1

aplay radio.raw -r 45600 -f S16_LE -t raw -c 1

Kaynaklar

5
[1] The Basic Facts About Radio Signals, https://www.windows2universe.org/
spaceweather/wave_modulation.html
[2] https://drive.google.com/uc?export=view&id=1oevS3Dxy-ksVEQrulxI57R-
mHcwFI-Tk
[3] https://drive.google.com/uc?export=view&id=1B65C4v4m8TUx4R_
_CQ58Jzyw7fnWYDDK
[4] Scher, How to capture raw IQ data from a RTL-SDR dongle and FM demodulate with
MATLAB,http://www.aaronscher.com/wireless_com_SDR/RTL_SDR_AM_
spectrum_demod.html
[5] EE123: Digital Signal Processing, http://inst.eecs.berkeley.edu/˜ee123/
sp14/
[6] Fund, Capture and decode FM radio, https://witestlab.poly.edu/blog/
capture-and-decode-fm-radio/
[7] Fund, Lab 1: Working with IQ data in Python, http://witestlab.poly.
edu/˜ffund/el9043/labs/lab1.html
[9] Swiston, pyFmRadio - A Stereo FM Receiver For Your PC, http://davidswiston.
blogspot.de/2014/10/pyfmradio-stereo-fm-receiver-for-your-pc.
html

6
Simulasyon
Önce basit bir simülasyon kodlayalım. Bazı toplar var, onları başta bir kuvve-
tle rasgele yönlere iteceğiz ve ne yapacaklarına bakacağız. Fiziksel parametreler
şöyle, yerçekimi sabiti g = 0.8 (dünyadan daha az), topların birbirine ya da du-
vara çarpması sonucu hiç enerji kaybı olmuyor.
Bu tür bir sistemin konumu, o anki hali her parçacık için bazı değişkenlerin takip
edilmesiyle olacak, bu değişkenler pozisyon, hız, kuvvet. Kütle her parçacık için
aynı olacak.
Parçacık hareketi o parçacık üzerinde uygulanan kuvvet ile belirlenir, Newton
denklemi mā = f̄, ki ivme ve kuvvet çok boyutlu dikkat edelim, o sebeple vektör
notasyonu olarak üstte çizgi kullandık. Peki ivmeden, hiza ve yer değişikliğine
nasıl gideriz? Newton formülünü bir ODE olarak tekrar düzenlersek onu ileri
doğru entegre edebiliriz. Yer x̄, hız v̄ olmak üzere [5,6] ve her i parçacığı için,

v̄˙ i = f̄i /mi

x̄˙ i = v̄i

Bu tür bir sistemi entegre etmek için Euler’in metotu kullanılabilir [5, sf 5], her n
anında bir sonraki n + 1 değeri için

x̄n+1 = x̄n + hv̄n

v̄n+1 = v̄n + hān

ki h ufak zaman aralığı olarak alınır, bir diğer isim ∆t olabilir, alttaki kodda dt . O
zaman her zaman diliminde her parçacığa etki eden kuvvetler toplanır, bir nihai
kuvvet vektörü elde edilir. Ardından üstteki formüllerle sistem her parçacık için
entegre edilir ve bir sonraki sistem durumu elde edilir.
Bu ilk sistemde bazı basitleştirmeler var; kuvvet uygulanma ve onun hıza dönüşmesine
her koşulda bakmıyoruz, duvarlar ve parçacıklar arası etkileri direk hız üzerinde
uyguluyoruz. Topların birbirine çarpma sonucu hız vektörlerinin hesabı [4]’te.
Kodlama notu, çarpışma hesabı için her parçacığın diğer parçacığa yakınlık kon-
trolü pahalı olursa, daha fazla parçacık için mesela, bunun için böleç tekniği kul-
lanılabilir [3].
Genel grafik yöntemi şurada [1] işlendi.

# convert -scale 30% /tmp/sim/*.png /tmp/balls6.gif


from random import random
from collections import defaultdict

1
import numpy as np, datetime
import sys, numpy.linalg as lin
from mayavi import mlab

G = np.array([0.0, 0.0, -0.8])

m = 0.1
B = 8 # top

EPS = 0.1
BOUND_DAMPING = -0.6

class Simulation:
def __init__(self):
self.r = 0.2
self.rvec = np.ones(B) * self.r
self.dt = 0.1
self.balls = []
self.cor = 0.5
self.mmax = 2.0-self.r
self.mmin = 0.0+self.r

def init(self):
for b in range(B):
v = np.array([0.0, 0.0, 0.0])
p = np.array([np.random.rand(), np.random.rand(), np.random.rand()])
f = 5*np.array([np.random.rand(), np.random.rand(), np.random.rand()])
self.balls.append({'x':p, 'f':f, 'v': v, 'i': b})

def computeForces(self, i):


if (i==0):
for j,b in enumerate(self.balls):
b['f'] = b['f'] + (G * m)
else:
for b in self.balls:
b['f'] = G * m

def integrate(self):

for j,p in enumerate(self.balls):


p['v'] += self.dt*(p['f']/m)
p['x'] += self.dt*p['v']

if p['x'][0]-EPS < 0:
p['v'][0] *= BOUND_DAMPING
p['x'][0] = 0
if p['x'][0]+EPS > 2.0:
p['v'][0] *= BOUND_DAMPING
p['x'][0] = 2.0-EPS

if p['x'][1]-EPS < 0:
p['v'][1] *= BOUND_DAMPING
p['x'][1] = 0
if p['x'][1]+EPS > 2.0:

2
p['v'][1] *= BOUND_DAMPING
p['x'][1] = 2.0-EPS

if p['x'][2]-EPS < 0:
p['v'][2] *= BOUND_DAMPING
p['x'][2] = 0
if p['x'][2]+EPS > 2.0:
p['v'][2] *= BOUND_DAMPING
p['x'][2] = 2.0-EPS

vDone = {}
for j,b in enumerate(self.balls):
for other in self.balls:
if (other['i'] != b['i'] and b['i'] not in vDone and other['i'] not in
dist = lin.norm(other['x']-b['x'])
if (dist < (2*self.r)):
#print ('collision')
vrel = b['v']-other['v']
n = (other['x']-b['x']) / dist
vnorm = np.dot(vrel,n)*n
#print (vnorm)
b['v'] = b['v'] - vnorm
other['v'] = other['v'] + vnorm
vDone[b['i']] = 1
vDone[other['i']] = 1

def update(self,i):
self.computeForces(i)
self.integrate()

def display(self, i):


mlab.options.offscreen = True
ball_vect = [[b['x'][0],b['x'][1],b['x'][2]] for b in self.balls]
ball_vect = np.array(ball_vect)

fig = mlab.figure(figure=None, fgcolor=(0., 0., 0.), bgcolor=(1, 1, 1), engine


color=(0.2, 0.4, 0.5)
mlab.points3d(ball_vect[:,0], ball_vect[:,1], ball_vect[:,2], self.rvec, color
mlab.points3d(0, 0, 0, 0.1, color=(1,0,0), scale_factor=1.0)

BS = 2.0
mlab.plot3d([0.0,0.0],[0.0, 0.0],[0.0, BS], color=(0,0,0), tube_radius=None, f
mlab.plot3d([0.0,BS],[0.0, 0.0],[0.0, 0.0], color=(1,0,0), tube_radius=None, f
mlab.plot3d([0.0,0.0],[0.0, BS],[0.0, 0.0], color=(0,1,0), tube_radius=None, f
mlab.plot3d([0.0,0.0],[0.0, BS],[BS, BS], color=(0,0,0), tube_radius=None, fig
mlab.plot3d([0.0,BS],[0.0,0.0],[BS,BS], color=(0,0,0), tube_radius=None, figur
mlab.plot3d([BS,BS],[0.0,BS],[BS,BS], color=(0,0,0), tube_radius=None, figure=
mlab.plot3d([BS,0],[BS,BS],[BS,BS], color=(0,0,0), tube_radius=None, figure=fi
mlab.plot3d([0,0],[BS,BS],[BS,0], color=(0,0,0), tube_radius=None, figure=fig)
mlab.plot3d([BS,BS],[0.0,0.0],[0.0,BS], color=(0,0,0), tube_radius=None, figur
mlab.plot3d([BS,BS],[0.0,BS],[0.0,0.0], color=(0,0,0), tube_radius=None, figur
mlab.plot3d([BS,0.0],[BS,BS],[0.0,0.0], color=(0,0,0), tube_radius=None, figur

3
mlab.plot3d([BS,BS],[BS,BS],[0.0,BS], color=(0,0,0), tube_radius=None, figure=

mlab.view(azimuth=50, elevation=80, focalpoint=[1, 1, 1], distance=8.0, figure

mlab.savefig(filename='/tmp/sim/out-%02d.png' % i)
#exit()

if __name__ == '__main__':
s = Simulation()
s.init()
for i in range(40):
s.update(i)
s.display(i)
#exit()

Tüm resimleri birleştirirsek,

! convert -scale 30% /tmp/glutout-*.png /tmp/balls1.gif

Sonuç [2]’de görülebilir.


Kaynaklar
[1] Bayramlı, OpenGL, PyOpenGL, https://burakbayramli.github.io/dersblog/
sk/2020/08/pyopengl.html
[2] Bayramlı, Simulasyon 1 Animasyon, https://github.com/burakbayramli/
classnotes/blob/master/phy/phy_007_sim/balls1.gif?raw=true
[3] Bayramlı, Bilgisayar Bilim, Geometrik Anahtarlama (Spatial Hashing) ve Izgara
(Grid) ile En Yakın Noktaları Bulmak
[4] Bayramlı, Fizik, Temel Fizik 2, Dönüşler, Basınç, Çarpışma
[5] Müller, Fluid Simulation SIGGRAPH 2007 Course Notes,
[6] Visual Interactive Simulation (Spring 15), https://www8.cs.umu.se/kurser/
5DV058/VT15/

4
Katı-Gövde Simülasyonu
Dönüş Animasyonu
Bir örnek gövde üzerinde simülasyon yapmaya uğraşalım. Elimizde bir simit, ya
da geometride torus denen bir şekil var. Bu dosya STL denen bir format içinde,
detaylar için [1]. Kuvvet uygulama sonrası lineer ve açısal momentum içeren
simülasyon için pek çok değişkeni diferansiyel tanımları üzerinden entegre et-
memiz gerekiyor, daha basit bir örnek ile, özellikle sabit bir açışal hız üzerinden
salt döndürme ile başlamak uygun olabilir. [4]’te tarif edilen döndürme matrisi
türevini hatırlarsak,

dR
= ω̃ · R
dt

Döndürmeyi bir ω etrafında düşünüyorduk, ω’nin büyüklüğü açısal dönme hızına


tekabül ediyordu, ve ω̃ eksi-bakışımlı matris idi.

Tüm bunları entegre edici odeint çağrısının kabul edeceği bir formda nasıl kul-
lanırız? Bu çağrı düzleştirilmiş bir liste içinde diferansiyel sonuçların, ve ana
değişkenlerin olmasını bekliyor. O zaman R’yi kolon bazlı olmak üzere düzleştiririz,
ve gerektiği o listeden matris formuna geçeriz, vs.

from scipy.integrate import odeint


from stl import mesh

def skew(a):
return np.array([[0,-a[2],a[1]],[a[2],0,-a[0]],[-a[1],a[0],0]])

your_mesh = mesh.Mesh.from_file('torus.stl')
prop = your_mesh.get_mass_properties()
R0 = np.eye(3,3)
omega = np.array([1.0,1.0,1.0])
#omega = np.array([0.0,1.0,0.0])
skew_omega = skew(omega)

def dRdt(u,t):

1
R1x,R1y,R1z,R2x,R2y,R2z,R3x,R3y,R3z = u
R = np.array([R1x,R1y,R1z,R2x,R2y,R2z,R3x,R3y,R3z])
R = R.reshape((3,3)).T
res = np.dot(skew_omega, R)
return list(res.T.flatten())

LIM = 5
STEPS = 20
t=np.linspace(0.0, 3.0, STEPS)
R0 = np.eye(3,3)
u0 = R0.flatten()
u1=odeint(dRdt,list(u0),t)

Üstte görülen mesela R1x R matrisinin 1’inci kolonunun x değişkeni anlamında.


Simülasyonda simit şeklinin baktığı yön R içinde, ve grafik amaçlı olarak her
seferinde simit şeklini sıfırdan yükleyip son R’ye ilerletiyoruz, ve her adımda bu
grafiği basıyoruz. Simülasyonu hesapladık, tüm sonuç u1 içinde, görüntüden
bazı seçilmiş kareler altta görülebilir,

import matplotlib.pyplot as plt


from mpl_toolkits import mplot3d

def plot_vector(fig, orig, v, color='blue'):


ax = fig.gca(projection='3d')
orig = np.array(orig); v=np.array(v)
ax.quiver(orig[0], orig[1], orig[2], v[0], v[1], v[2],color=color)
ax = fig.gca(projection='3d')
return fig

for i in range(STEPS):
fig = plt.figure()
axes = mplot3d.Axes3D(fig)
your_mesh = mesh.Mesh.from_file('torus.stl')
R = u1[i].reshape((3,3)).T
your_mesh.rotate_using_matrix(R)
scale = your_mesh.points.flatten()
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors,alpha=0.3))
plot_vector(fig, [0,0,0], omega, color='red')
axes.auto_scale_xyz(scale, scale, scale)
axes.set_xlim(-LIM,LIM);axes.set_ylim(-LIM,LIM);axes.set_zlim(-LIM,LIM)
axes.view_init(azim=20,elev=0)
plt.savefig('/tmp/rotate_%02d.png' % i)

2
! convert -delay 20 -loop 0 /tmp/rotate*.png /tmp/rotate1.gif

Animasyon sonucu [4]’te.


Torus şekli hakkında bazı istatistikler alttadır.

from stl import mesh

3
your_mesh = mesh.Mesh.from_file('torus.stl')

prop = your_mesh.get_mass_properties()
print ('hacim',np.round(prop[0],3))
print ('yercekim merkezi (COG)',np.round(prop[1],3))
print ('COG noktasinda atalet matrisi')
print (np.round(prop[2],3))

hacim 4.918
yercekim merkezi (COG) [-0. 0. -0.]
COG noktasinda atalet matrisi
[[ 3.223 -0. 0. ]
[-0. 3.223 0. ]
[ 0. 0. 5.832]]

COG sıfır noktasında olması, ayrıca atalet matrisinin köşegen olması mantıklı
çünkü simit şekli simetrik.
İttirme Animasyonu
Bu animasyon için katı gövdeye bir noktada bir kuvvet uyguluyacağız. O nok-
tayı seçmek için STL formatında olan üçgenlerden birini kullanabiliriz, çünkü
bu üçgenlerin gövdenin yüzeyinde bir yerlerde olduğunu biliyoruz, Torus STL
şekli bu üçgenlerin herbirine dik olan normal vektörü STL formatında zaten,
o üçgenlerden birinin normal vektörünü ters çevirirsek, o noktaya o yönde bir
kuvvet uyguladığımızı hayal edebililriz, ve simülasyonun geri kalanını bu nok-
tadan devam ettiririz.

import matplotlib.pyplot as plt


from mpl_toolkits import mplot3d

fig = plt.figure()
axes = mplot3d.Axes3D(fig)

SCALE = 4
LIM = 5

scale = your_mesh.points.flatten()
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors,alpha=0.3))
axes.auto_scale_xyz(scale, scale, scale)

def plot_vector(fig, orig, v, color='blue'):


ax = fig.gca(projection='3d')
orig = np.array(orig); v=np.array(v)
ax.quiver(orig[0], orig[1], orig[2], v[0], v[1], v[2],color=color)
ax = fig.gca(projection='3d')
return fig

axes.set_xlim(-LIM,LIM);axes.set_ylim(-LIM,LIM);axes.set_zlim(-LIM,LIM)

tidx = 2000
o = np.mean(your_mesh.vectors[tidx],axis=0)
axes.plot (o[0],o[1],o[2],'gd')
n = your_mesh.get_unit_normals()[tidx]

4
plot_vector(fig, o, n*SCALE)
plot_vector(fig, o, -n*SCALE, color='red')
axes.view_init(azim=84,elev=28)

plt.savefig('phy_005_basics_04_05.png')

Kuvveti kırmızı vektörle gösterilen yönde uygulayabiliriz.


Şimdi “sıfırıncı anda” yani ilk başlangıçta uygulanan kuvvetleri, lineer, açısal,
hesaplamak lazım. Noktayı üstte seçtik, sonu o noktada başlangıcı nesne ağırlık
merkezinde olan bir vektör ile kuvvet vektörü arasında çapraz çarpım yapıyoruz,
bu bize torku veriyor.

Benzer şekilde sonu nesne merkezinde başı o noktada olan bir vektör daha var,
lineer kuvvet bu doğrultuda uygulanacak, o vektör üzerine iki üstte görülen
kırmızı vektörü yansıtıyoruz, bu da lineer kuvvet oluyor. Bir üstteki resim üzerinde
gösterirsek,

5
Daha önce söylediğimiz gibi her iki kuvvet de ilk anda lineer ve açısal momen-
tumu ekileyen faktörler, sonraki adımlarda etkileri yok.
Ayrıca entegrasyon için kendi pişirdiğimiz kodları kullanacağız, odeint işleri
zorlaştırabilir çünkü zamana bağlı bazı farklı kodlamalar var, ayrıca I−1 her adımda
sürekli değişiyor, yani bir konum güncellemesi var, bu tür kodlamalar kapalı bir
kutu isteyen odeint ile daha zor olabilir. Bunlar problem değil, [5]’te paket kul-
lanmadan hesaplanan bir kodlama şeklini görmüştük.

import numpy as np
from stl import mesh
import numpy.linalg as lin

your_mesh = mesh.Mesh.from_file('torus.stl')
prop = your_mesh.get_mass_properties()
cog = np.round(prop[1],3) # baslangic aninda obje COG
Ibody = np.round(prop[2],3)
Ibodyinv = lin.inv(Ibody)
dt = 0.1
x = np.zeros((1,3))
R = np.eye(3,3)
L = np.zeros((1,3))
v = np.zeros((1,3))
F = np.zeros((3,1))
M = 1
P = M* v

def skew(a):
return np.array([[0,-a[2],a[1]],[a[2],0,-a[0]],[-a[1],a[0],0]])

tidx = 2000
apply_at = np.mean(your_mesh.vectors[tidx],axis=0) - cog
f_at = -1 * 5 * your_mesh.get_unit_normals()[tidx]
tau0 = np.cross(apply_at, f_at).reshape(1,3) * 10.0
flindir = cog-apply_at
flin0 = np.dot(f_at,flindir)*(flindir/np.abs(lin.norm(flindir)))

res = []
for i in range(30):

6
xold,Rold,Pold,Lold = x.copy(),R.copy(),P.copy(),L.copy()

Iinv = np.dot(np.dot(Rold, Ibodyinv), Rold.T)


omega = np.dot(Iinv, Lold.T).T
omega = omega.reshape(3)
skew_omega = skew(omega)
R = Rold + np.dot(skew_omega, Rold) * dt

v = Pold / M
x = x + v*dt
P = Pold
if i==0: # baslangic ani
L = Lold + tau0*dt
P = Pold + (flin0*dt)
else:
L = Lold # sonraki adimlarda degisim yok
P = Pold # momentum ayni kaliyor
res.append([x,R,P,L])

Hesaplar yapıldı, şimdi grafikleme,

import matplotlib.pyplot as plt


from mpl_toolkits import mplot3d

LIM = 5
SCALE = 4

def plot_vector(fig, orig, v, color='blue'):


ax = fig.gca(projection='3d')
orig = np.array(orig); v=np.array(v)
ax.quiver(orig[0], orig[1], orig[2], v[0], v[1], v[2],color=color)
ax = fig.gca(projection='3d')
return fig

for i, [x,R,P,L] in enumerate(res):


fig = plt.figure()
axes = mplot3d.Axes3D(fig)
your_mesh = mesh.Mesh.from_file('torus.stl')
# t-0 aninda uygulanan kuvvet yonunu goster
o = np.mean(your_mesh.vectors[tidx],axis=0)
n = your_mesh.get_unit_normals()[tidx]
plot_vector(fig, o, -n*SCALE, color='red')

your_mesh.rotate_using_matrix(R)
your_mesh.translate(x.reshape(3))
scale = your_mesh.points.flatten()
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors,alpha=0.3))
axes.auto_scale_xyz(scale, scale, scale)
axes.set_xlim(-LIM,LIM);axes.set_ylim(-LIM,LIM);axes.set_zlim(-LIM,LIM)

az = 80-(i*2) # kamera dondurmek icin


axes.view_init(azim=az,elev=28)
plt.savefig('/tmp/rotate_%02d.png' % i)
plt.close('all')

7
! convert -delay 20 -loop 0 /tmp/rotate*.png /tmp/rotate2.gif

Animasyon sonucu [6]’da görülebilir. Hareket mantıklı gözüküyor, unutmayalım


grafikleme açısından kolay olduğu için öyle çizildi fakat aslında hesaplara göre
vektörün ucu kuvvet uygulanan noktada, ve uygulanan kuvvet sonrası şekil dönmeye
başlayarak ve yukarı doğru uçarak devam ediyor (kuvvet alttan yukarı doğru).
Simülasyon ortamı boşluk ortamı, uzay gibi yerçekimsiz bir yer, tek kuvvet ilk
başta şekle uygulanan kuvvet, ardından momentum muhafazası ile hareket de-
vam ediyor.
Kaynaklar
[1] Bayramlı, 3D Baskıya Hazır CAD Tasarımlarına Erişmek, Numpy-STL, https://
burakbayramli.github.io/dersblog/sk/2020/08/numpy-stl.html
[2] Witkin, Physically Based Modeling
[3] Bayramlı, Animasyon 1, https://drive.google.com/uc?export=view&
id=17qlJvaucB6_l0eLUfcevu84qNXQocGHO
[4] Bayramlı, Fizik, Temel Fizik 4, Katı Gövde

8
[5] Bayramlı, Fizik, Simulasyon
[6] Bayramlı, Animasyon 2, https://drive.google.com/uc?export=view&
id=1ZvONRASb4By5zKnuDs6unAVwj0PA8_HK

9
Temel Fizik 5 - Katı-Gövde Simülasyonu
Bir örnek gövde üzerinde simülasyon yapmaya uğraşalım. Elimizde bir simit, ya
da geometride torus denen bir şekil var. Bu dosya STL denen bir format içinde,
detaylar için [1]. Torus STL şekli içiçe geçmiş üçgenler ile tanımlı, bu üçgenlerin
herbirine dik olan normal vektörü biliyoruz. O üçgenlerden birinin orta nok-
tasından çıkan vektörlerden birini ters çevirirsek, o noktaya o yönde bir kuvvet
uyguladığımızı hayal edelim, ve simülasyonun geri kalanını bu noktadan devam
ettirelim.

import matplotlib.pyplot as plt


from mpl_toolkits import mplot3d
import pandas as pd, numpy as np
from stl import mesh

your_mesh = mesh.Mesh.from_file('torus.stl')

prop = your_mesh.get_mass_properties()
print ('\nhacim',prop[0])
print ('\nyercekim merkezi (COG)',prop[1])
print ('\nCOG noktasinda atalet matrisi')
print (prop[2])

fig = plt.figure()
axes = mplot3d.Axes3D(fig)

scale = your_mesh.points.flatten()
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors,alpha=0.3))
axes.auto_scale_xyz(scale, scale, scale)

def plot_vector(fig, orig, v, color='blue'):


ax = fig.gca(projection='3d')
orig = np.array(orig); v=np.array(v)
ax.quiver(orig[0], orig[1], orig[2], v[0], v[1], v[2],color=color)
ax = fig.gca(projection='3d')
return fig

LIM = 5
axes.set_xlim(-LIM,LIM);axes.set_ylim(-LIM,LIM);axes.set_zlim(-LIM,LIM)

SCALE = 4
tidx = 2000
o = np.mean(your_mesh.vectors[tidx],axis=0)
axes.plot (o[0],o[1],o[2],'gd')
n = your_mesh.get_unit_normals()[tidx]
plot_vector(fig, o, n*SCALE)
plot_vector(fig, o, -n*SCALE, color='red')
axes.view_init(azim=84,elev=28)

plt.savefig('phy_005_basics_04_05.png')

hacim 4.917547323463467

1
yercekim merkezi (COG) [-1.57676116e-12 3.04791724e-11 -6.76980205e-11]

COG noktasinda atalet matrisi


[[ 3.22258484e+00 -5.48156069e-10 2.81815519e-10]
[-5.48156069e-10 3.22258489e+00 2.90733626e-09]
[ 2.81815519e-10 2.90733626e-09 5.83209197e+00]]

[devam edecek]
Kaynaklar
[1] Bayramli, 3D Baskıya Hazır CAD Tasarımlarına Erişmek, Numpy-STL, https://
burakbayramli.github.io/dersblog/sk/2020/08/numpy-stl.html
[2] Witkin, Physically Based Modeling

2
Pürüzleştirilmiş Parcaçık Hidrodinamiği (Smoothed Particle Hydrodynamics -
SPH-)
SPH sıvıların dinamik hareketini görmemizi sağlayan bir simulasyon tekniğidir.
Lagrangian bakış açısını temel alır, yani Euler aksine, bir sıvı paketini takip edip
nereye gittiğine, hangi değişimlere uğradığına bakarız.
Önce akış dinamiğini formüllerini görelim,
Sıvının akışını simüle etmek pek çok alanda faydalı olabilecek bir tekniktir. Sıvıların
kendisine ek olarak gazları yoğunluğu daha az olan sıvı olarak görebiliriz, hatta
katı maddeler de akışkanlığı çok az sıvı gibi düşünülebilirse, böylece aerodi-
namikten başlayıp, gemi tasarlamaya, oradan oyunlarda duman simülasyonuna
kadar giden geniş yelpazede teknikler kullanım bulabilir.
SPH tekniği bu sıvı simülasyon yöntemlerinden birisidir. Navier-Stokes den-
klemleri bir sıvının akışını tanımlar, bu denklem simülasyon ortamında yaklaşık
olarak çözülmelidir [13], bunu yapmanın iki yolu vardır. Önceki anlatımdan
hareketle herhalde cevabı tahmin edebiliriz, birisi Lagrange usulü diğeri Euler
usulü. SPH yöntemi Lagrange yaklaşımını takip eder, yani bir sıvı paketini alıp
onun zaman ve uzayda gidişini izler. Tek bir yere mıhlanmış olmamanın (Euler
usulü) pek çok avantajları var, mesela oyun grafiklerini çizerken daha geniş bir
alanda iş yapabilmek mümkün, farklı maddeler arasındaki iletişim daha rahat
halledilebiliyor, vs.
Formülasyon için temel fizikle başlayalım. Simüle ettiğimiz bir sıvı paketidir
demiştik, bu paketin ivmesini takip edelim mesela, bunun önemli olacagini tah-
min edebiliriz, oradan kuvvet, enerji bağlantıları var, F = ma formülünden hareke-
tle, ve materyel türev ile

Dū
m = Ftoplam
Dt
diyebiliriz. Daha önce materyel türevi yoğunluk üzerinde uygulamıştık, pek çok
farklı ölçüt üzerinde materyel türev kullanılabilir demiştik, ayrıca hız ū materyel
türev içinde kullanılmakta, ama hızın kendisine de gayet rahat bir şekilde materyel
türev uygulanabilir.
Üstteki eşitliğin sağ tarafını detaylandırabiliriz, düşünelim, hangi kuvvetler bir
sıvı akışı sırasında sıvı paketi / parçacık üzerinde etki ediyor? Bunlar sırasıyla
basınç, ağdalık, ve yerçekim olurdu herhalde, bal gibi ağdalı bir sıvıda parçalar
birbirlerine yapışkandır, şu için daha az, bu bir kuvvettir. Yerçekimi bir kuvvet-
tir doğal olarak. Basınç ta öyle, biraz derine dalan herkes etrafındaki suyun
basıncını bir kuvvet olarak hisseder. O zaman,

Dū
m = Fbasınç + Fağdalık + Fyerçekim
Dt

diyebiliriz. Kuvvetlerden en basiti yerçekimi, Fyerçekim = mḡ. İvme ḡ bir vektör

1
olarak gösterildi, bu ḡ = (0, 0, 9.8) olurdu, sadece z ekseni üzerinde etki eden bir
ivmelenme yani.
Diğer kuvvet basınç. Yüksek basınç bölgeleri alçak basınç bölgelerinde doğru bir
kuvvet uygular. Basıncın tüm sıvı için p(x̄) değişkeninde olduğunu düşünelim,
peki basınç dengesizliğini matematiksel olarak göstermenin en basit yolu nedir?
Basıncın negatif gradyanını almak, −∇p olur mu acaba? Evet. Temel Calcu-
lus’tan hatırlarsak gradyan en dik iniş yönünü gösterir, o zaman gradyanın negat-
ifi yüksek basınç bölgesinden dışarı, alçak basınç bölgesine doğru gösterecektir.
Tabii ki bu etkiyi üzerinde olduğumuz sıvı paketinin hacmi üzerinden entegre et-
memiz gerekir, ama basit bir yaklaşıklama olarak onu direk hacim V ile çarpabiliriz.
Tümü Fbasınç = −V∇p.
Üçüncü kuvvet ağdalık. Ağdalı bir sıvı deforme edilmeye karşı direnir. Bu
kuvveti kabaca “her parçacığı yanındaki diğer parçacıkların ortalama hızında
hareket etmesini zorlayan kuvvet” olarak görebiliriz, bir diğer deyişle birbirine
yakın olan parçacıkların arasındaki hız farklarını minimize etmeye uğraşan kuvvet.
Şimdi, mesela görüntü işleme literatürünü düşünürsek, o alanda çalışanlar bir
ölçünün etrafındaki ortalamadan ne kadar saptığını hesaplamak için bir diferan-
siyel operatör kullanır, bu operatör Laplasyan ∇ · ∇. Bu operatör, aynı şekilde
hacim üzerinden entegre edilince bize ağdalık kuvvetini verebilir, burada bir
ek her sıvının farklı ağdalığını formüle dahil edebilmek için bir de bir dinamik
ağdalık sabiti (dynamic viscosity coefficient) µ ile herşeyi çarpmak gerektiği, o
zaman Fağdalık = Vµ∇ · ∇ū formülünü elde ediyoruz.
Hepsini bir araya koyunca,

Dū
m = mḡ − V∇p + Vµ∇ · ∇ū
Dt

Bu denklemi hacim ve kütle limite giderken düşüneceğiz, ama bu haliyle formül


problem çıkartabilir, o zaman her şeyi V ile bölersek ve sonra limiti düşünürsek
daha iyi olur, m/V’yi sıvı yoğunluğu ρ olarak tanımlayalım,

Dū
ρ = ρḡ − ∇p + µ∇ · ∇ū
Dt

Bu denklem bazıları için tanıdık gelebilir.. Navier-Stokes denklemine benzemiyor


mu? Navier-Stokes ünlü denklemi,

∂ū 1
+ ū + ∇p = ḡ + ν∇ · ∇ū
∂t ρ

∇ · ū = 0

olarak gösterilir.

2
Neyse bizim türetişle devam edersek, her şeyi yoğunluk ρ ile bölelim,

Dū 1 µ
+ ∇p = ḡ + ∇ · ∇ū
Dt ρ ρ

Basitleştirme amacıyla kinematik ağdalık ν = µ/ρ tanımlayalım, o zaman

Dū 1
+ ∇p = ḡ + ν∇ · ∇ū
Dt ρ

Sıkıştırılamazlığın (incompressibility) ∇ · ū = 0 olduğunu daha önce [5]’deki (2)


formülünde görmüştük.
Devam edelim,

Dū
ρ = Ftoplam
Dt

denklemini gördük. Bu Newton’un F = ma formülasyonun bir karşılığı. Bu


denklemde basınç, ağdalık gibi kuvvetler için terimler vardı. Toplam kuvvetleri
açarsak,

Ftoplam = Fbasınç + Fağdalık + Fyerçekim

Daha detaylı hali,

Dū
ρ = −∇p + µ∇ · ∇ū + ρḡ
Dt

Simulasyon için bize ivme gerekli. Kütle ve kuvvetten ivme, oradan sayısal en-
tegrasyon ile yer değişimi elde edilebilir, katı-gövde simulasyonunu kodlarken
[6]’da bu anlatılmıştı. O zaman eldeki i’inci parçacık için toplam kuvvet Fi hesaplarsak

dui Fi
ai = =
dt ρi

ile ivmeyi buluruz, ve oradan devam ederiz.


Şimdi bize gereken ∇p(ri ) ve ∇2 u(ri ) hesaplarını yaklaşık yapabilmemizi sağlayacak
bir metot kullanmak. SPH tekniği bunu sağlıyor.
Bir fonksiyon A aradeğerleme (interpolation) / yaklaşıklama üzerinden temsil
edilebilir [1],
Z
AI (r) = A(r 0 )W(r − r 0 , h) dr 0

3
Belirtilmediği yerlerde r = r̄, u = ū kabul edilebilir, bunlar vektör, dr 0 diferan-
siyel hacim öğesi. AI aradeğerlenmiş fonksiyon, A yaklaşık göstermeye uğraştığımız
fonksiyon. A simulasyon ortamında hesaplanan herhangi bir ölçüt olabilir, mesela
herhangi bir r = (x, y, z) noktasındaki basınç, sıcaklık, yoğunluk, vs.
W ağırlık fonksiyonudur, ya da çekirdek (kernel) fonksiyonu, sahip olması gereken
bir şart,
Z
W(r − r 0 , h) dr 0 = 1

ve

lim W(r, h) = δ(r)


h→0

[4, sf. 11]. [4]’te bu tekniğin Dirac fonksiyonu ile bağlantıları anlatıldı. Eğer W =
δ dersek, yani çekirdek için Dirac fonksiyonu kullanırsak, orijinal fonksiyonun
kendisini elde ederiz.
SPH’in temel fikri entegral aradeğerlemeden geliyor, hatta ona bir tür Çekirdek
Yoğunluk Kestirme (Kernel Density Estimation) yöntemi de denebilir. Sıvıyı ayrıksal
parçalara bölüyoruz, ve takip edilen ölçüt ne ise çekirdek fonksiyonu üzerinden
bu ölçüt pürüzsüzleştiriliyor / etrafa yayılıyor / yumuşatılıyor. Yani çekirdek
yarıçapı içindeki diğer parçacıklar o an üzerinde olduğumuz parçacığın neyini
ölçüyorsak onu etkiliyor, mesela yakındaki parçacıkların basıncı ya da yoğunluğu
bizim basıncı, yoğunluğu etkiliyor. Kabaca düşünülünce aslında bu bakış açısının
sıvıların tabiatına son derece uygun olduğu anlaşılacaktır.
Ortalamanın alınma şekli RBF tekniği [11] ile ya da olasılıktaki beklenti hesabına
benziyor, RBF ile üzerinde olduğumuz veriyi etraftaki verilere Gaussian uydu-
rarak temsil etmeye uğraşırız, SPH ile üzerinde olduğumüz parçacık ölçümünü
etraftaki ölçütlerin (çoğunlukla Gaussian-ımsı) bir çekirdek üzerinden ortalamasıyla
temsil ederiz. Ortalama bir entegraldir, Olasılık Teorisi’nde R∞ beklentinin alınması
gibi, x değerlerinin f(x) üzerinden ağırlıklı ortalaması infty xf(x) dx.
Yaklaşıklamayı sıvıya uygulamak için onu kütle öğelerine bölmemiz gerekli, i’inci
öğe mi kütlesine, ρi yoğunluğuna, ve ri pozisyonuna sahip olacak. A ölçütü /
hesabının i parçacığındaki değeri Ai ile gösterilsin. Her parçacık için,
Z
A(r) = A(r 0 )W(r − r 0 , h) dr 0

Yaklaşıklık için AI (r) da diyebilirdik, ya da ≈ kullanabilirdik. Şimdi,

Z
A(r 0 )
= W(r − r 0 , h)ρ(r 0 ) dr 0
ρ(r 0 )

4
ρ(r 0 )’i hem bölen hem bölünene eklediğimiz için hiçbir değişim yaratmamış olduk,
ama böylece ρ(r 0 ) dr 0 ifadesi elde ettik ki ona parçacık kütlesi diyebiliriz. Böylece
parçacıkların kütleleri üzerinden bir toplam alabiliriz,

X Ab
As (r) = mb W(r − rb , h)
b
ρb

Formülde kütle kullanımı daha faydalı çünkü kütle simülasyona başlamadan


önce bilinir, hatta çoğu parçacık için birbirinin aynısıdır.
Üstteki toplamın teoride tüm parçacıklar üzerinden alındığı gösterildi, fakat pratikte
r’ye yakın olan diğer parçacıklar üzerinden alınır, çoğunlukla çekirdek 2h gibi bir
uzaklıkta zaten hızla sıfıra düştüğü için, ayrıca performans açısından, çok uzak-
taki parçacıkları göz önüne almaya gerek yoktur.
Bu formül bana herhangi bir r noktasında hesaplayabileceğim bir A kestirme
hesabı (estimation) vermiş oldu. Parcaçık bazlı simulasyon yaptığımız için her i
parçacığı çevresindeki j parçacıkları üzerinden bu kestirme hesabı yapabileceğiz.
Bazı hesaplar formülün basit yan ürünü, mesela yoğunluk

X ρj X
ρi = ρ(ri ) = mj W(ri − rj , h) = mj W(ri − rj , h)
j
ρj j

Yani etraftaki parçacıkların kütlesi üzerinden alınan bir ağırlıklı ortalama bana
parçacığın yoğunluğunu veriyor.
Aradeğerlemenin bize sağladığı güzel bir özellik onun üzerinden mesela kolayca
gradyan alabilmem. Diyelim ki A ölçümü basınç, yani p. O zaman (1)’de görülen
−∇p formülünü üstteki entegral üzerinden açabilmem gerekir (p ölçümünün ya
da hesabının nereden geldiği ileride anlatılacak). r’de olan her i parçacığı için
p(ri ) diyelim,

X mj p j
p(ri ) = W(ri − rj , h)
j
ρj

Bu denklemin gradyanını alabiliriz şimdi,

X mj p j
∇p(ri ) = ∇W(ri − rj , h)
ρj

Gradyan direk W üzerinde uygulanmış oldu. Burada modellemeyi yapan kişi


tabii ki W’yi “gradyanı rahat alınan” fonksiyonlar arasından da seçecektir, böylece
işi daha kolaylaşacaktır.
O zaman üstteki sonuç ile −∇p yazarsak,

5
X mj p j
Fbasınç
i =− ∇W(ri − rj , h)
j
ρj

elde ederiz.
Yanlız burada bir problem var, j bölgesindeki basıncı kullanarak o fark üzerinden
i üzerindeki kuvveti hesapladık, fakat basınç farkı dolayısıyla i’nin j üzerinde
uyguladığı kuvvet aynı olmayabilir. Yani kuvvet simetrik olmaz, fakat fizik ka-
nunlarına göre etki-tepki aynı olmalıdır. Simulasyon amacıyla çoğunlukla yapılan
dışarıdan müdahele ile kuvveti simetrik hale getirmektir, mesela bir yöntem basit
aritmetik ortalama almak,

X pi + pj
Fbasınç
i = −∇p(ri ) = − mj ∇W(ri − rj , h)
j
2ρj

Ağdalık kuvvetine gelelim. İlk başta (1) bazlı olarak bu formül

ağdalık
X uj 2
Fi =µ mj ∇ W(ri − rj , h)
j
ρj

olarak yazılabilirdi. Fakat simetriklik problemi burada da var, bu problem de


hıza olan bağlantıyı izafi hıza çevirerek çözülebilir, çünkü fiziksel olarak düşünülürse
esas önemli olan mutlak hızlar değil iki parçacığın hızlarının farkı, ya da bir
parçacığın diğerine baktığında gördüğü hız (ki bu izafi demek) o zaman

ağdalık
X uj − ui 2
Fi =µ mj ∇ W(ri − rj , h)
j
ρj

daha uygun olur.


Çekirdek Fonksiyon Seçimi
SPH’in stabilitesi, doğruluğu ve hesap hızı pürüzleştirme çekirdeğinin doğru
seçilmiş olmasına bağlı [2]. Çekirdek fonksiyonlarını hangisinin, hangi durum-
larda iyi olacağı aktif bir araştırma alanıdır. Yaygın kullanılan bir çekirdek poly6
ismiyle bilinen 6. derece polinom çekirdeği. Bu fonksiyon,


315 (h2 − ||r||2 )3 0 6 ||r|| 6 h
Wpoly6 (r, h) =
64πh9 0 ||r|| > h

Gradyanı,

945
∇W(r, h) = − r(h2 − ||r||2 )2
32πh9
Laplasyanı ise,

6
945
∇2 W(r, h) = − (h2 − ||r||2 )(3h2 − 7||r||2 )
32πh9

Tek boyutta ve h = 1 üzerinden her üç fonksiyonu grafikleyebiliriz,

r = np.linspace(-1,1,100)
h = 1
import pandas as pd
df = pd.DataFrame(r)
df.columns = ['r']
df['W'] = (315./(64*np.pi*h**9)) * (h**2 - np.abs(r)**2)**3
df = df.set_index('r')
df.plot()
plt.savefig('compscieng_app40sph_01.png')

df = pd.DataFrame(r)
df.columns = ['r']
df['W'] = (315./(64*np.pi*h**9)) * (h**2 - np.abs(r)**2)**3
df['Gradyan W'] = -945./(32*np.pi*h**9) * r * (h**2 - np.abs(r)**2)**2
df = df.set_index('r')
df.plot()
plt.savefig('compscieng_app40sph_02.png')

7
df = pd.DataFrame(r)
df.columns = ['r']
df['W'] = (315./(64*np.pi*h**9)) * (h**2 - np.abs(r)**2)**3
df['Gradyan W'] = -945./(32*np.pi*h**9) * r * (h**2 - np.abs(r)**2)**2
df['Laplasyan W'] = -945./(32*np.pi*h**9) * \
(h**2-np.abs(r)**2) * \
(3*h**2 - 7**np.abs(r)**2)
df = df.set_index('r')
df.plot()
plt.savefig('compscieng_app40sph_03.png')

Basınç
Basınç kuvveti eğer basınç biliniyorsa hesaplanabilir, basıncın kendisini hesapla-
mak için İdeal Gaz Kanunu gerekli [9], bu kanun

pV = nRT

ki V = 1/ρ, yani birim kütleye düşen hacim, n mol üzerinden kaç tane gaz
parçacığı olduğu, R evrensel gaz sabiti, T ise sıcaklık. SPH için sıvıda eşsıcaklık
(isothermal), ve parçacıkların sayısı simulasyon sırasında değişmez kabul edilir,
o zaman üstteki formülün sağ tarafında bir gaz sertlik (stiffness) sabiti k kul-
lanılabilir [4, sf. 18],

pV = k

1
p =k
ρ

p = kρ

Sayısal kodlamalarda stabilite amaçlı olarak ayrıca bir de ρ0 kullanılır, ki her


basınç hesabı için yoğunluğun bu baz ρ0 ile olan farkı bazlı alınır, nihai formül,

8
p = k(ρ − ρ0 )

Simülasyon kodu alttadır. Simüle edilen bir blok sıvıyı havada asılı bir durum-
dan bırakmak. Ne olacak? Yerçekim etkisiyle tabii ki sıvı parçacıkları düşmeye
başlayacaklar, ama normal sadece elastik çarpışma içeren simülasyondan farklı
olarak şimdi sıvı parçacıkları arasında ağdalık var, yani birbirlerine yakın dur-
maya meyilliler. Ayrıca basınç var, tüm bunların etkisini simüle eden program
acaba sıvısal bir davranış gösterecek mi? Simülasyon animasyon / video olarak
[10]’da bulunabilir.

from random import random


from collections import defaultdict
import numpy as np, datetime
import sys, numpy.linalg as lin
from mayavi import mlab
import itertools

m = 0.1
R = 0.1
EPS = 0.1
BOUND_DAMPING = -0.6
mmin,mmax=0.0,2.0
BN = int(np.abs(mmax-mmin) / R) + 1
bins = np.linspace(mmin, mmax, BN)
G = np.array([0.0, 0.0, -9.8*2])

REST_DENS = 10.0
GAS_CONST = 0.5
MASS = 100.0
VISC = 20.0
DT = 0.1
H = 0.1 # kernel radius
PI = 3.14159
HSQ = H*H # radiusˆ2 for optimization
POLY6 = 315.0/(65.0*PI*np.power(H, 9.));
SPIKY_GRAD = -45.0/(PI*np.power(H, 6.));
VISC_LAP = 45.0/(PI*np.power(H, 6.));
EPS = 0.05
BOUND_DAMPING = -0.5

idx27 = list(itertools.product( [-1,0,1], repeat=3 ))

class Simulation:
def __init__(self):
self.r = R
self.balls = []

def init(self):
i = 0
for xs in np.linspace(0, 0.4, 10):
for ys in np.linspace(0, 0.4, 10):
for zs in np.linspace(0, 0.4, 10):

9
v = np.array([0.0, 0.0, 0.0])
f = np.array([0,0,0])
x = np.array([xs, ys, zs])
xi = np.digitize(xs, bins)
yi = np.digitize(ys, bins)
zi = np.digitize(zs, bins)
d = {'x': x, 'f':f, 'v': v, 'i': i, 'rho': 0.0, 'p': 0.0, 'grid':
self.balls.append(d)
i += 1
self.rvec = np.ones(i) * self.r

def get_neighbors(self, ball):


neighbors = {}
cx,cy,cz = ball['grid']
for (xa,ya,za) in idx27:
nx,ny,nz = cx+xa,cy+ya,cz+za
if (nx,ny,nz) in self.grid_hash:
tn = self.grid_hash[(nx,ny,nz)]
for n in tn: neighbors[ n['i'] ] = n
return neighbors

def hash_balls(self):
self.grid_hash = defaultdict(list)
for i,b in enumerate(self.balls):
xi = np.digitize(b['x'][0], bins)
yi = np.digitize(b['x'][1], bins)
zi = np.digitize(b['x'][2], bins)
b['grid'] = (xi,yi,zi)
self.grid_hash[(xi,yi,zi)].append(b)

def computeDensityPressure(self):
for i,pi in enumerate(self.balls):
pi['rho'] = 0.0
otherList = self.get_neighbors(pi)
for (k,pj) in otherList.items():
r2 = lin.norm(pj['x']-pi['x'])**2
if r2 < HSQ:
pi['rho'] += MASS*POLY6*np.power(HSQ-r2, 3.0)
pi['p'] = GAS_CONST*(pi['rho'] - REST_DENS)

def computeForces(self):
for i,pi in enumerate(self.balls):
fpress = np.array([0.0, 0.0, 0.0])
fvisc = np.array([0.0, 0.0, 0.0])
otherList = self.get_neighbors(pi)
for k,pj in otherList.items():
if pj['i'] == pi['i']: continue
rij = pi['x']-pj['x']
r = lin.norm(rij)
if r < H:
if np.sum(rij)>0.0: rij = rij / r
tmp1 = -rij*MASS*(pi['p'] + pj['p']) / (2.0 * pj['rho'])
tmp2 = SPIKY_GRAD*np.power(H-r,2.0)
fpress += (tmp1 * tmp2)

10
tmp1 = VISC*MASS*(pj['v'] - pi['v'])
tmp2 = pj['rho'] * VISC_LAP*(H-r)
fvisc += (tmp1 / tmp2)
fgrav = G * pi['rho']
pi['f'] = fpress + fvisc + fgrav

def integrate(self):
for j,p in enumerate(self.balls):
if p['rho'] > 0.0:
p['v'] += DT*p['f']/p['rho']
p['x'] += DT*p['v']

if p['x'][0]-EPS < 0.0:


p['v'][0] *= BOUND_DAMPING
p['x'][0] = 0.0
if p['x'][0]+EPS > 2.0:
p['v'][0] *= BOUND_DAMPING
p['x'][0] = 2.0-EPS

if p['x'][1]-EPS < 0.0:


p['v'][1] *= BOUND_DAMPING
p['x'][1] = 0.0
if p['x'][1]+EPS > 2.0:
p['v'][1] *= BOUND_DAMPING
p['x'][1] = 2.0-EPS

if p['x'][2]-EPS < 0.0:


p['v'][2] *= BOUND_DAMPING
p['x'][2] = 0.0
if p['x'][2]+EPS > 2.0:
p['v'][2] *= BOUND_DAMPING
p['x'][2] = 2.0-EPS

self.hash_balls()

def update(self):
self.hash_balls()
self.computeDensityPressure()
self.computeForces()
self.integrate()

def display(self, i):


mlab.options.offscreen = True
ball_vect = [[b['x'][0],b['x'][1],b['x'][2]] for b in self.balls]
ball_vect = np.array(ball_vect)

fig = mlab.figure(figure=None, fgcolor=(0., 0., 0.), bgcolor=(1, 1, 1), engine


color=(0.2, 0.4, 0.5)
mlab.points3d(ball_vect[:,0], ball_vect[:,1], ball_vect[:,2], self.rvec, color
mlab.points3d(0, 0, 0, 0.1, color=(1,0,0), scale_factor=1.0)

BS = 2.0
mlab.plot3d([0.0,0.0],[0.0, 0.0],[0.0, BS], color=(0,0,0), tube_radius=None, f

11
mlab.plot3d([0.0,BS],[0.0, 0.0],[0.0, 0.0], color=(1,0,0), tube_radius=None, f
mlab.plot3d([0.0,0.0],[0.0, BS],[0.0, 0.0], color=(0,1,0), tube_radius=None, f
mlab.plot3d([0.0,0.0],[0.0, BS],[BS, BS], color=(0,0,0), tube_radius=None, fig
mlab.plot3d([0.0,BS],[0.0,0.0],[BS,BS], color=(0,0,0), tube_radius=None, figur
mlab.plot3d([BS,BS],[0.0,BS],[BS,BS], color=(0,0,0), tube_radius=None, figure=
mlab.plot3d([BS,0],[BS,BS],[BS,BS], color=(0,0,0), tube_radius=None, figure=fi
mlab.plot3d([0,0],[BS,BS],[BS,0], color=(0,0,0), tube_radius=None, figure=fig)
mlab.plot3d([BS,BS],[0.0,0.0],[0.0,BS], color=(0,0,0), tube_radius=None, figur
mlab.plot3d([BS,BS],[0.0,BS],[0.0,0.0], color=(0,0,0), tube_radius=None, figur
mlab.plot3d([BS,0.0],[BS,BS],[0.0,0.0], color=(0,0,0), tube_radius=None, figur
mlab.plot3d([BS,BS],[BS,BS],[0.0,BS], color=(0,0,0), tube_radius=None, figure=

mlab.view(azimuth=50, elevation=80, focalpoint=[1, 1, 1], distance=8.0, figure

mlab.savefig(filename='/tmp/sim/out-%02d.png' % i)

if __name__ == '__main__':
s = Simulation()
s.init()
for i in range(20):
print (i)
s.update()
s.display(i)
#exit()

12
Komşuları bulmak için [12]’deki ızgara bazlı yöntem kullanıldı. Bu yöntem, bi-
raz ek yapılarak mükkemmel sonuç verebilir, ve bu önemli çünkü SPH’in doğru
çalışabilmesi için tüm komşuların bulunabilmesi gerekir.
Kaynaklar
[1] Monaghan, Smoothed particle hydrodynamics, 2005
[2] Schuermann, Particle-Based Fluid Simulation with SPH, https://lucasschuermann.
com/writing/particle-based-fluid-simulation
[3] Bayramlı, Hesapsal Bilim, Ders 4
[4] Kelager, Lagrangian Fluid Dynamics Using Smoothed Particle Hydrodynamics
[5] Bayramlı, Fizik, Muhafaza Kanunları
[6] Bayramlı, Fizik, Simulasyon
[7] Monaghan, Introduction to SPH Part I, https://www.youtu.be/tAXHCAEgSuE
[8] Müller, Particle-Based Fluid Simulation for Interactive Applications
[9] Bayramlı, Fizik, Temel Fizik 3, Basınç, Çarpışma
[10] Bayramlı, Simulasyon Animasyonu, https://github.com/burakbayramli/
classnotes/blob/master/compscieng/compscieng_app40sph/balls4.
gif?raw=true
[11] Bayramlı, Istatistik, Dairesel Baz Fonksiyonları (Radial Basis Functions -RBF-)
[12] Bayramlı, Bilgisayar Bilim, Geometrik Anahtarlama (Spatial Hashing) ve Izgara
(Grid) ile En Yakın Noktaları Bulmak
[13] Schuermann, Particle-Based Fluid Simulation with SPH, https://lucasschuermann.
com/writing/particle-based-fluid-simulation

13
Sonlu Öğeler Metotu (Finite Elements Method -FEM-) - 1

1
Sonlu Öğeler Metotu (Finite Elements Method -FEM-) - 2

1
Sonlu Öğeler Metotu (Finite Elements Method -FEM-) - Mittal
Fonksiyonların İç Çarpımı (Inner Product)
Vektörlerden bildiğimiz çoğu tekniği fonksiyonlara uygulamak mümkündür [3].
Elimizde f(x), g(x), ... reel değerli, α 6 x 6 β aralığında tanımlı fonksiyonları
olduğunu düşünelim, bu fonksiyonlar bir reel vektör uzayı oluştururlar. Şimdi
(f, g) iç çarpımını düşünelim, ki bu çarpım tanımı


(f, g) = f(x)g(x) dx
α

olsun. Üstteki bizim tanımımız tabii, başkaları ekler yapabilirler, mesela bazıları
iç çarpıma bir ağırlıklama fonksiyonu w ekliyorlar, yani üstteki entegralde f, g ve
w çarpılıyor. Bizim dersimizin amaçları için biz gördüğümüz tanımla yetineceğiz.
Üstteki entegral lineer. Simetrik olduğu bariz. Ayrıca kesin artı (positive definite)
özelliği de var.
Eldeki iç çarpım tanımıyla artık “bir fonksiyonun uzunluğu” bile hesaplanabiliyor,
aynen vektörlerin uzunluğunun hesaplanabildiği gibi.

Zβ Zβ
s s
||f|| = (f, f) =
p
f(x)f(x) dx = [f(x)]2 dx
α α

Bu sayede birim fonksiyonlar bile yaratabilirim, mesela f(x)’i uzunluğu ||f(x)|| ile
bölersem onu normalize etmiş olurum, yani uzunluğu bire inmiş olur, g, h, vs ile
bunu aynı şekilde gerçekleştirebilirim.
Tamlık (Completeness)
Bir α 6 x 6 β aralığında tanımlı fonksiyonlar kümesi S olsun. Ayrıca y0 , y1 , ..
aynı S kümesinde tanımlı birimdik (orthonormal) fonksiyonlar olsun (yani her
yi fonksiyonun birbiri ile iç çarpımı sıfır sonucu verecek). Bu birimdik fonksiy-
onlar kümesine tam denir eğer herhangi bir f ∈ S’i o baz fonksiyonların lineer
kombinasyonu olarak yaklaşık şekilde temsil edebiliyorsam. Yaklaşıklık dere-
cesi benim tanımladığım  > 0 ile ölçülecektir, ve kaç tane fonksiyonu kombine
ettiğim de yine benim tarafımdan tanımlı olacaktır. Yaklaşıklık

||f − (k0 y0 + k1 y1 + k2 y2 + ... + km ym )|| < 

ile ölçülebilir.
Not: Birimdiklik tamlık için şart değil, fakat birimdiklik bazı rahat işlemler yapa-
bilmemizi sağlar, o bakımdan tercih edilir.
Örnek

1
−π 6 x 6 π arasında tanımlı bir f(x) olsun. O zaman Fourier fonksiyonları 1,
sin x, cos x, sin 2x, cos 2x, ... bir tam küme oluştururlar. Çünkü −π 6 x 6 π
arasında bana verilen herhangi bir fonksiyonu Fourier fonksiyonlarının bir kom-
binasyonu olarak temsil edebilirim, ya da doğru terminoloji kullanmak gerekirse,
onu bir “Fourier Serisi” olarak temsil edebilirim. Görülen o her birimdik fonksiy-
onu a0 , b0 , a1 , b1 , .. sabitleriyle çarpıp toplarım ve yaklaşık temsili yaparım, tabii
katsayıların ne olduğunu bulmam gerekir, doğru olanlarını bulunca f’yi iyi tem-
sil etmiş olurum. Seriyi uzattıkça, daha fazla Fourier terimi ekledikçe, f’ye daha
da yaklaşırım, benden beklenen  yakınlığını böylece elde edebilirim. Mesela
kabaca bir yaklaşıklık için 4-5 tane terim, çok iyi olması için yüzlerce.
Örnek
Herhangi bir kupsel polinomu temsil etmek bağlamında 1, x, x2 , x3 bir tam küme
oluşturur. Fakat bu küme yegane küme mi? Hayır. Mesela 5, 3 + x, 9 + 2x + 6x2 ,
5x + 20x2 kümesi de tamdır.
Tam küme öğelerinin bir özelliğine dikkat çekmek gerekir, onların birini diğerlerinin
lineer kombinasyonu olarak temsil etmek mümkün değildir. Mesela x3 ’u 1, x,
x2 ’yi lineer olarak birleştirerek erisemem.
Örnek
Bu örnekte tam olmayan bir kümeye bakalım. Mesela küpsel polinomları temsil
etmek için 1, x, x3 tam değildir, çünkü x2 eksik. Mesela üstteki 9+2x+6x2 fonksiy-
onu.. onu eldeki bu baz ile temsil edemem çünkü x2 bazı yok. Evet x3 var ama
oradan “aşağı inerek” karesel temsil yapmak mümkün değil, en azından ben-
den istenen  yakınlığında, ve lineer kombinasyonlar kullanarak bunu yapmak
mümkün değil.
Teori
y0 , y1 , y2 , .. fonksiyonları S kümesi için, α 6 x 6 β aralığında tanımlı, tam, ve
birimdik (bu sefer şart) bir küme olsun. O zaman f ∈ S bir sürekli fonksiyon ise
ve her ym ’e dikgen ise bu demektir ki f muhakkak sıfırdır.
Mesela iki boyutta basit bir örnek üzerinde görelim; iki birimdik baz var, x ve y
üzerinde kalın çizgi ile gösterdiğim, i, j diyelim, şimdi bir A vektörü düşünelim,
bu vektör çizildiği haliyle tabii, birimdik i, j kombinasyonu ile temsil edilebilir.
Fakat şimdi düşünelim, eğer A hem i’ye hem j’ye dikgen olsaydı, yani öyle bir
vektör olsaydı ki ne x ne y üzerinde hiçbir yansıması olmasaydı, bu A sıfırdan
başka bir şey olamazdı, değil mi? Üstteki teorinin söylediği bundan ibaret.

2
Ağırlıklı Artıklar Metotu (Weighted Residual Method -WRM-)
Önceki derste iyi koşullu bir sistemi elde etmeyi gördük, bu kötü koşullu (ill
conditioned) olmanın tersi tabii. Bu derste WRM’yi kurmayı göreceğiz [1], ki
bu metot aslında kapsayıcı bir tarif, altında farklı hesap yöntemleri de olabiliyor,
WRM’nin kendisi hata kontrolünü nasıl yapacağımızı tarif ediyor.
Basit bir problemle başlayalım. Laplace formülü mesela, iki boyutu baz alalım,
ama birazdan göreceğimiz fikirler 1D ya da 3D için de geçerli. Problem bölgesi
(domain) Ω olsun onun sınırları Γ ,

İlgilendiğimiz alan (field) T (x, y), bu reel değerli bir fonksiyon, ve kurduğumuz
sistem için bu fonksiyonun şu şartlara tabi olmasını istiyoruz,

∇2 T = 0 Ω üzerinde

Γ için T = T0

Bu tür problemlere Drichlet problemleri deniyor.


Üstteki şartları yerine getiren bir T (x, y) çözümü bulmak istiyoruz. O zaman ilk
akla gelen nedir? Diferansiyel denklemi alıyorum ve Ω içindeki tüm noktalar için
çözmeye uğraşıyorum. Fakat bu kolay değil. Ayrıca Ω’daki eşitlik Γ sınırında
geçerli değil, ikinci şart sebebiyle. Bu arada matematiksel olarak çözüm nedir?
Ω’daki sonsuz tane nokta için geçerli olan şeydir. Buna kesin çözüm (exact solu-
tion) deniyor.

3
Fakat bu çözümü bulmak mümkün değilse, ya da yaklaşık bir çözüm de yeterli
oluyorsa o zaman yaklaşık yöntemler kullanabilirim.. ∇2 T = 0 eşitliği Ω’daki her
nokta için, her Γ sınır şartında değil belli seçilmiş noktalarda olsun diyebilirim.
Ama “belli noktalarda” deyince de iş bitmiyor, o seçilmiş noktalarda kesin çözüm
mü yapsam, yoksa o noktalarda da yaklaşık çözüm yapsam? Ya da tüm nok-
talarda yaklaşık çözüm üzerinden bir hata hesaplayıp, tüm seçilmiş noktalarla
hesaplanan ortalama bir hatanın sıfır olması için mi uğraşsam?
Şöyle bir yöntem deneyelim; elimizde / verili belli bir baz fonksiyon “sınıfı” ol-
sun, bu fonksiyonlar Fourier bazı sin, cos olabilir, ya da Chebisev polinomları
olabilir. Bu “test”, baz fonksiyonları Ti (x, y) içinde, i = 1, 2, ..., N, ve nihai T ’yi

X
N
T = T0 + ci Ti (x, y)
i=1

ile hesaplayayım, ci ’ler başta bilmediğim katsayı değerleri olsun. Bilinen / ver-
ili test fonksiyonları üzerinden doğru ci ’leri bulursam bu beni gerçek fonksiyon
T ’ye yaklaştırır. Üstteki toplamda T0 terimi özellikle o şekilde formüle dahil
edildi, Ti toplamının sınırda sıfır olmasını ayarlayabilirsem, T = T0 şartını otomatik
olarak tatmin etmiş olurum.
N sayısına dikkat, gerçek fonksiyonu aşağı yukarı temsil etmek istesem N’yi az
tutardım, birkaç tane temel fonksiyon birleşimi.. Ama N’i arttırarak, hatta son-
suza yaklaştığımızda gerçek fonksiyona tıpatıp eşit olacağımızı bekleyebilirdik,
o zaman N sayısı bir anlamda yaklaşıklamanın kalitesini kontrol edecektir. N
arttıkça hata azalır, yaklaşıklama gerçeğe yaklaşır. Bir ödünleşim (trade-off) du-
rumu var muhakkak, çok büyük N hesaplaması zor olan bir sistem ortaya çıkartabilir,
vs.
Bu bizi hata tanımına getiriyor. Onu gerçek ve yaklaşık değerler arasındaki fark,
“artık” (residual) üzerinden tanımlayacağız, artık R,

R(ci , x, y) = ∇2 T

Bu kadar basit. Niye artığı direk ∇2 T ’e eşitlemek yeterli? Çünkü ana formüle
bakarsak ∇2 T ideal durumda sıfır olmalı değil mi? Ama yaklaşıklama mükemmel
olmadığı için sıfırdan farklı (fakat umuyoruz ki ona yakın) değerler döndürecektir,
o zaman bu değeri alıp direk hata / artık değeri olarak kullanabiliriz. O zaman

X
N
R(ci , x, y) = T0 + ci Ti (x, y)
i=1

diyelim. Üstteki denklem bana her veri noktası, belli bir x, y için olan hatayı verir.
Sınır koşulunu denklem doğal olarak karşıladığı için orada zaten hata yok. Yani

4
tanım itibariyle sınırda hata sıfır, ve sınırlar içinde muhtemel olarak sıfır olmayan
bir değerde.
Şimdi ci ’lerin bulunmasına gelelim, yaklaşık temsil onlar üzerinden mümkün
olacak. N tane ci bilinmiyor o zaman bir şekilde N tane denklem üretmem lazım,
ki onları çözerek bilinmeyenleri elde edeyim. WRM burada devreye giriyor.
Ağırlıklı artıklar dedik, ağırlıklardan da (dikkat ci katsayılarından, ve test fonksiy-
onlarından farklı bu) da N tane var, N tane fonksiyon. Onları j ile indisleyebiliriz,
wj , j = 1, ..., N. Artıkları şöyle ağırlıklıyoruz,
Z
wj R dΩ

Biraz önce söylediğimiz artığın sıfır olma hedefini biraz genişletip ağırlıklanmış
artığın sıfır olması haline getiriyoruz. O zaman N tane denklemi şöyle üretiriz,

Z "
X
N
#
j = 1, w1 (x, y) ∇2 T0 + ci ∇2 Ti (x, y) dΩ
Ω i=1

Z "
X
N
#
j = 2, w2 (x, y) ∇2 T0 + ci ∇2 Ti (x, y) dΩ
Ω i=1

..
.

Z "
X
N
#
j = N, wN (x, y) ∇2 T0 + ci ∇2 Ti (x, y) dΩ
Ω i=1

Böylece N tane bilinmeyen için N tane formül elde ettim, ve bu şekilde çözümü
yapabilirim.
wj ’ler ne yapıyor? Başta hataların ortalamasından bahsetmiştik hatırlarsak, her
wj bir nevi ortalamadır, ama her j için farklı bir ortalama şekli seçebiliriz, mesela
alttaki resimde

5
karalanmış kısma daha fazla ağırlık ver diyebiliriz, vs. Genel anlamda hatırlarsak
üç sayı A,B,C ortalaması demek aslında her sayının 1/3 “ağırlığı” ile çarpılıp,
toplanması ve sonucun 3’e bölünmesi demektir. Bu ağırlıkları değiştirebiliriz, o
zaman farklı bir ortalama elde ederiz, mesela 1/2, 1/4, 1/4 kullansam A’ya daha
fazla ağırlık vermiş olurdum.
Bu açıdan bakınca üstte üretilen her denklem belli bir artık formülünün farklı
şekillerde ağırlıklanması sonucu elde edilen denklemlerdir.
Galerkin Metotu
Bu metot FEM’in temelini oluşturur [2], 1915, 1913’te Galerkin, Bubnov tarafından
ayrı ayrı keşfedilmiştir. Galerkin metotunun özü şu basit önermeden ibaret, daha
önce gördüğümüz ağırlıklı artıklar metotunda Galerkin metotu der ki wj = Tj ,
yani ağırlık fonksiyonu test fonksiyonu ile aynı olsun. Ayrica hatirlarsak Tj ’lerin
bir tam kume olusturmasi gerekiyor, o zaman wj ’lerin de tam kume olusturmasi
gerekiyor. Bu durumda agirlikli artiklar metotu bizi su noktaya getirir,

(wj , R) = 0

Yani R her wj ’e dikgen, bu daha önceki dikgenlik teorisini hatırlatmalı bize, eğer
R her birimdik baz fonksiyonuna dik ise, kendisi sıfırdan başka bir şey olamaz.
Bu çok kuvvetli bir sonuç. R hatasının tam kümedeki her fonksiyon ile iç çarpımının
sıfır olma şartına bakıyoruz.. bu tür bir ilişkinin bize ileride faydalı olacağını
görmek zor değil, dikgenlikten direk R’nin sıfır olmasına atlayabilmiş oluyoruz,
bunu lineer cebirsel işlemlerimizde kullanabiliriz.
Kaynaklar
[1] Mittal, FEM for Fluid Dynamics, Lecture 07 Part A, Method of Weighted Residu-
als, IIT Kanpur, https://www.youtube.com/channel/UCWheqBdP45xBVp_
Eqi1eltQ/videos
[2] Mittal, FEM for Fluid Dynamics, Lecture 07 Part B, IIT Kanpur, https://www.
youtube.com/channel/UCWheqBdP45xBVp_Eqi1eltQ/videos
[3] Mittal, FEM for Fluid Dynamics, Lecture 05 Part C, Inner Product for functions,Orthogonality,Comple

6
IIT Kanpur, https://www.youtube.com/channel/UCWheqBdP45xBVp_Eqi1eltQ/
videos

7
Hesapsal Sıvı Dinamiğine (Computational Fluid Dynamics -CFD-) Giriş
Tek Boyutlu Lineer Taşınım Akımı (Convection)
Tek boyutlu lineer taşınım akımı, ya da tek boyutlu lineer yatay iletim (advec-
tion), CFD hakkında bir şeyler öğrenmek için güzel fırsatlar içeriyor. Bu ufak
denklemin bize ne kadar çok şey öğreteceğini görmek bizi şaşırtabilir. Denklem,

∂u ∂u
+c =0
∂t ∂x

Dikkat bu bir dalga denklemi olarak bilinir, fakat esas dalga denkleminin kısmi
türevsel formu ikinci kısmi türevi içeriyor, bkz [2]. Üstteki denklem verili başlangıç
şartlarına göre bir basit dalganın şekil değiştirmeden c hızında yayılmasını tem-
sil eder. Başlangıç şartlarını u(x, 0) = u0 (x) olarak gösterirsek, denklemin kesin
analitik çözümü u(x, y) = u0 (x − ct).
Üstteki formülü süreklilik denkleminin [3] bir formu olarak ta görebiliriz [4, sf.
557]. Süreklilik denklemi

∂ρ
+ ∇ · (ρū) = 0
∂t

idi, bu formülü tek boyutta düşünürsek ve sabit hız ū = c alırsak (2)’ye ulaşırız.
Denklemi hem zaman, hem uzay bağlamında ayrıksallaştıracağız. Türev tanımından
(ve limit ifadesini çıkartınca),

∂u u(x + ∆x) − u(x)



∂x ∆x

olduğunu biliyoruz. Şimdi zamanda İleri Farklılık (Forward Difference), uzayda


Geriye Farklılık (Backward Difference) kullanalım.. Ve eğer x eksenini N parçaya
ayırırsak ve bu parçaları i = 0, .., N ile indekslersek, ve en ufak zaman adımını da
∆t ile gösterip o adımı n ile indislersek,

un+1 − un un − un
i i
+c i i−1
=0
∆t ∆x

ki n ve n + 1 ardı ardına olan iki zaman adımı, i − 1 ve i ise ayrıksallaştırılmış iki


x yeri oluyor. Eğer başlangıç koşulları verilmiş ise o zaman bu ayrıksal sistemde
tek bilinmeyen un+1i ’dir. Denklemi tekrar düzenlersek bilinmeyen için yeni bir
formül elde edebiliriz,

∆t n
un+1 = un
i −c (u − un
i−1 )
i
∆x i

1
Yeri temsil eden x eksenini eşit aralıklı parçalara böleceğiz, bir tek boyutlu ızgara
yaratacağız, genişlik 2 birim olacak, nx değişkeni kaç tane ızgara noktası olduğunu
tanımlayacak, dx iki nokta arasındaki uzaklık.

import time, sys


nx = 41
dx = 2 / (nx-1)
nt = 25
dt = .025
c = 1

Başlangıç şartlarını tanımlamak lazım, başlangıç hızı u0 aralık 0.5 6 x 6 1 içinde


u = 2, diğer her yerde u = 1.

u = np.ones(nx)
u[int(.5 / dx):int(1 / dx + 1)] = 2
print(u)

[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 1. 1. 1.
1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

plt.plot(np.linspace(0, 2, nx), u);


plt.savefig('compscieng_app45cfd1_01.png')

Üstteki bir fonksiyon türü aslında, ona görüntüsü sebebiyle “şapka fonksiyonu”
ismi de veriliyor.
Şimdi taşınım akımı denkleminin ayrıksal kodlamasına gelelim, burada sonlu
farklılık (finite difference) yaklaşımı kullanıyoruz, u vektörü içindeki her öge için
(1) formülünü işleteceğiz.

un = np.ones(nx)
for n in range(nt):
un = u.copy()
for i in range(1, nx):
u[i] = un[i] - c * dt / dx * (un[i] - un[i-1])

2
Üstteki işlemle zamanı ileri sardık ve fonksiyon belli bir noktaya geldi. Nereye
geldi?

plt.plot(np.linspace(0, 2, nx), u);


plt.savefig('compscieng_app45cfd1_02.png')

Evet, başlangıç fonksiyonu hakikaten sağa doğru taşındı. Fakat artık fonksiyon
bir şapka değil. Ne oldu? Sonuç yaklaşık temsilin kalitesiyle alakalı, dx ve dt
küçültüldükçe kalite artacaktır, ve şapkaya daha çok benzeyen sonuçlar görülecektir.
Gayrı Lineer Taşınım Akımı (Nonlinear Convection)
Şimdi biraz önceki teknikleri kullanarak gayrı lineer taşınım akımı kodlayacağız,
tek boyutta denklem,

∂u ∂u
+u =0
∂t ∂c
Dikkat edersek önceki denklemdeki c ile çarpım yerine şimdi u ile çarpım var,
bu sebeple formülün ikinci terimi gayrı lineer hale geldi. Eğer ayrıksallaştırma
işlemini tekrar uygularsak, alttaki sonuca erişiriz,

∆t n
un+1
i = un n
i − ui (ui − un
i−1 )
∆x

nx = 41
dx = 2 / (nx - 1)
nt = 20
dt = .025
u = np.ones(nx)
u[int(.5 / dx) : int(1 / dx + 1)] = 2
un = np.ones(nx)

un = np.ones(nx)
for n in range(nt):

3
un = u.copy()
for i in range(1, nx):
u[i] = un[i] - un[i] * dt / dx * (un[i] - un[i-1])

plt.plot(np.linspace(0, 2, nx), u);


plt.savefig('compscieng_app45cfd1_03.png')

Yakınsama (Convergence)
Lineer taşınım hesabında ortaya çıkan tepe şeklinin ızgara çözünülürlüğü ile
alakalı olduğunu söylemiştik. Bunu birkaç farklı çözünürlük ile deneyerek görelim.
İlk gördüğümüz sonuç nx=41 kullandı. Arttıralım,

def linearconv(nx):
dx = 2 / (nx - 1)
nt = 20
dt = .025
c = 1

u = np.ones(nx)
u[int(.5/dx):int(1 / dx + 1)] = 2

un = np.ones(nx)

for n in range(nt):
un = u.copy()
for i in range(1, nx):
u[i] = un[i] - c * dt / dx * (un[i] - un[i-1])

plt.plot(np.linspace(0, 2, nx), u);

linearconv(61)
plt.savefig('compscieng_app45cfd1_04.png')

4
linearconv(71)
plt.savefig('compscieng_app45cfd1_05.png')

Gittikçe daha fazla şapka fonsiyonuna benzer sonuçlar alıyoruz. Şimdi dikkat,
bir kez daha arttıralım,

linearconv(85)
plt.savefig('compscieng_app45cfd1_06.png')

5
Bu sonuç şapka fonksiyonuna benzemiyor. Ne oldu?
Hesaplananları düşünürsek, yer ekseni üzerinde dalganın hareketini hesaplıyoruz,
fakat her adımda ∆t = 0.025 farzederk bu hesapları yapıyoruz. Üstteki yanlış
sonuçta ∆t zaman aralığında öyle bir adım attık ki bu adım dx’in büyüklüğünden
daha fazla. Bu durum ilk denemelerde ortaya çıkmadı çünkü dx yeterince büyük
tutulmuştu. Fakat onu küçültükçe bir noktada hesap patladı.
Stabilite için ∆t adımını ∆x ile ilişkilendirecek bir formül faydalıdır, böyle bir
formül var,

u∆t
σ= 6 σmax
∆x
u dalganın hızı, σ degiskeni Courant sayısı, ve σmax stabiliteyi sağlayacak üst
limit. Çoğunlukla σmax = 1 seçilir. Bu ilişkinin türetilmesini [7]’de bulabiliriz.
Diffusion (Yayınım) Denklemi
Tek boyuttaki yayınım denklemi,

∂u ∂2 u
=ν 2
∂t ∂x
Dikkat edersek bu denklemde bir ikinci kısmı türev var. Denklemin o kısmını
Merkezi Farklar yaklaşımı ile ayrıksal hale getireceğiz, bu yaklaşım İleri Farklar
ve Geriye Farklar yaklaşımlarının birleştirilmesi ile elde edilir.
Önce Taylor serilerini hatırlarsak, genel tanım

h2 00
f(x + h) = f(x) + hf 0 (x) + f (x) + ...
2
Biz ui+1 ve ui−1 açılımını Taylor serisi ile yapmak istiyoruz, daha önce belirttiğimiz
gibi bir önceki ve sonraki x değerleri ∆x uzaklığında, yani bir önceki

6
h2 00
u(x − ∆x) = u(x) − ∆xf 0 (x) + u (x) + ...
2

İşaretin eksi olmasına dikkat, ve sonraki

h2 00
u(x + ∆x) = u(x) + ∆xf 0 (x) + u (x) + ...
2

Şimdi indisleriyle u için ve [1]’deki formuyla yazalım,

∆x2 ∂2 u ∆x3 ∂3 u

∂u
ui+1 = ui + ∆x + 2
+ 3
+ O(∆x4 )
∂x i 2 ∂x i 3! ∂x i

∆x2 ∂2 u ∆x3 ∂3 u

∂u
ui−1 = ui − ∆x + − + O(∆x4 )
∂x i 2 ∂x2 i 3! ∂x3 i

Bir üstteki denklemin ilk hali ui = ui−1 ... ile ama ufak bir yer değişimi ile görülen
biçim elde edilmiş.
Son iki formülü toplarsak bazı terimlerin ters işaretli olması sebebiyle iptal olacağını
görebiriliz. Ayrıca yaklaşık temsil açısından O(∆x4 ) ve daha üstü kuvvetleri yok
sayarsak,

∂2 u

ui+1 + ui−1 = 2ui + ∆x2 2 + O(∆x4 )
∂x i

∂2 u

∂x2
için çözersek ve tekrar düzenlersek,
i

∂2 u ui+1 − 2ui + ui−1


2
= 2
+ O(∆x2 )
∂x ∆x

O(∆x2 ) ifadesi O(∆x4 ) terimi ∆x2 ile bölününce ortaya çıktı.


Artık 1D yayınım formülünün nihai ayrıksal halini yazabiliriz,

un+1 − un un − 2un n
i + ui−1
i i
= ν i+1
∆t ∆x2

Daha önce olduğu gibi başlangıç koşuları tanımlı ise tek bilinmeyen un+1
i , bu
bilinmeyen eşitliğin solunda kalacak şekilde tekrar düzenlersek,

ν∆t n
un+1 = un
i + (u − 2un n
i + ui−1 )
i
∆x2 i+1

7
Üstteki denklem bize çözümü adım adım ilerletmemizi sağlayacak. Ama bir
başlangıç koşuluna ihtiyacımız var, daha önceki favorimize dönebiliriz, şapka
fonksiyonu. t = 2’de u = 0, 0.5 6 x 6 1 aralığında ise u = 1.

nx = 41
dx = 2 / (nx - 1)
nt = 20
nu = 0.3
sigma = .2
dt = sigma * dx**2 / nu

u = np.ones(nx)
u[int(.5 / dx):int(1 / dx + 1)] = 2

un = np.ones(nx)

for n in range(nt):
un = u.copy()
for i in range(1, nx - 1):
u[i] = un[i] + nu * dt / dx**2 * (un[i+1] - 2 * un[i] + un[i-1])

plt.plot(np.linspace(0, 2, nx), u);


plt.savefig('compscieng_app45cfd2_01.png')

2D Taşınım (2D Convection)


2 boyuta geçme zamanı geldi. 2D lineer taşınım akımını (convection) temsil eden
parçalı kısmi diferansiyel denklem,

∂u ∂u ∂u
+c +c =0
∂t ∂x ∂y

Bu 1D lineer taşınım akımı ile neredeyse aynı formda, sadece şimdi tek yersel
boyut yerine iki tane boyutumuz var, x ve y.
Ayrıksal hale getirmek için aynı yaklaşımı kullanacağız, zaman adımlarını ileri

8
farklar, konumsal değişkenleri ise geriye farklar yöntemi ile ayrıksal yapacağız.
1D durumda i altsimgesini konumda olan hareketlilik için kullanmıştık, un n
i −ui−1
mesela. Şimdi, 2D durumda, ikinci bir altsimge j ekliyoruz, y boyutunu böylece
indislemiş olacağız.
Tüm bunları kullanarak ayrıksal forma erişmek zor değil,

un+1 n
i,j − ui,j un n
i,j − ui−1,j un n
i,j − ui,j−1
+c +c =0
∆t ∆x ∆y

Daha önce olduğu gibi tek bilinmeyene göre tekrar düzenleyelim,

∆t n ∆t n
un+1 = un
i,j − c (ui,j − un
i−1,j ) − c (u − un
i,j−1 )
i,j
∆x ∆y i,j

Denklemi alttaki başlangıç şartlarına göre çözeceğiz,



2 0.5 6 x, y 6 1 için
u(x, y) =
1 diğer her yerde

Sınır şartları

x = 0, 2
u = 1 değeri için
y = 0, 2

from mpl_toolkits.mplot3d import Axes3D


from matplotlib import cm
nx = 81
ny = 81
nt = 100
c = 1
dx = 2 / (nx - 1)
dy = 2 / (ny - 1)
sigma = .2
dt = sigma * dx

x = np.linspace(0, 2, nx)
y = np.linspace(0, 2, ny)

u = np.ones((ny, nx)) ##create a 1xn vector of 1's


un = np.ones((ny, nx)) ##

u[int(.5 / dy):int(1 / dy + 1),int(.5 / dx):int(1 / dx + 1)] = 2

fig = plt.figure(figsize=(11, 7), dpi=100)


ax = fig.gca(projection='3d')
X, Y = np.meshgrid(x, y)
surf = ax.plot_surface(X, Y, u[:], cmap=cm.viridis)
plt.savefig('compscieng_app45cfd3_01.png')

9
İki boyutta zamanı ileri saralım şimdi. Tüm i ve j’leri işleyebilmek için bir içiçe
geçmiş döngü gerekiyor bize. Python dilinde for kullanmak çok optimal değildir,
ama alttaki kod neler olduğunu gösterebilmek için yardımcı olacaktır.

u = np.ones((ny, nx))
u[int(.5 / dy):int(1 / dy + 1), int(.5 / dx):int(1 / dx + 1)] = 2

for n in range(nt + 1):


un = u.copy()
row, col = u.shape
for j in range(1, row):
for i in range(1, col):
tmp1 = (c * dt / dx * (un[j, i] - un[j, i - 1]))
tmp2 = (c * dt / dy * (un[j, i] - un[j - 1, i]))
u[j, i] = (un[j, i] - tmp1 - tmp2)
u[0, :] = 1
u[-1, :] = 1
u[:, 0] = 1
u[:, -1] = 1

fig = plt.figure(figsize=(11, 7), dpi=100)


ax = fig.gca(projection='3d')
surf2 = ax.plot_surface(X, Y, u[:], cmap=cm.viridis)
plt.savefig('compscieng_app45cfd3_02.png')

Burgers’in Denklemi

10
Bu denklem tek boyutta şuna benziyor

∂u ∂u ∂2 u
+u =ν 2
∂t ∂x ∂x

Görüldüğü gibi bu formül gayrı lineer taşınım akımı (convection) ile yayınım
(diffusion) formüllerinin birleşimi. O zaman denklemi önce gördüğümüz teknikler
ile ayrıksal hale getirebiliriz.

un+1
i − un
i
n n
n ui − ui−1 un n n
i+1 − 2ui + ui−1
+ ui =ν
∆t ∆x ∆x2

Daha önce olduğu gibi başlangıç koşulumuz var, ona göre denklemi tekrar düzenliyoruz,

∆t n ∆t n
un+1
i = un n
i − ui (ui − un
i−1 ) + ν 2
(ui+1 − 2un n
i + ui−1 )
∆x ∆x

Bu örnekte farklı bir başlangıç şartı kullanacağız.

2ν ∂φ
u=− +4
φ ∂x

−x2 −(x − 2π)2


   
φ = exp + exp
4ν 4ν

Bu başlangıç şartlarına göre Burgers denkleminin analitik çözümü biliniyor,

2ν ∂φ
u=− +4
φ ∂x

−(x − 4t)2 −(x − 4t − 2π)2


   
φ = exp + exp
4ν(t + 1) 4ν(t + 1)

Sınır şartı

u(0) = u(2π)

Fakat başlangıç şartını belli ızgara noktalarında işletebilmek istiyoruz, fakat üstteki
formülde çetrefil bir form var, birşeylerin türevi vs var. Ne yapacağız? Paket
sympy kullanılabilir.

import sympy
from sympy.utilities.lambdify import lambdify
from sympy import init_printing
init_printing(use_latex=True)

11
x, nu, t = sympy.symbols('x nu t')
phi = (sympy.exp(-(x - 4 * t)**2 / (4 * nu * (t + 1))) +
sympy.exp(-(x - 4 * t - 2 * sympy.pi)**2 / (4 * nu * (t + 1))))
phiprime = phi.diff(x)

u = -2 * nu * (phiprime / phi) + 4
ufunc = lambdify((t, x, nu), u)
print(ufunc(1, 4, 3))

3.49170664206445

nx = 101
nt = 100
dx = 2 * np.pi / (nx - 1)
nu = .07
dt = dx * nu

x = np.linspace(0, 2 * np.pi, nx)


un = np.empty(nx)
t = 0

u = np.asarray([ufunc(t, x0, nu) for x0 in x])

plt.figure(figsize=(11, 7), dpi=100)


plt.plot(x, u, marker='o', lw=2)
plt.xlim([0, 2 * np.pi])
plt.ylim([0, 10]);
plt.savefig('compscieng_app45cfd2_02.png')

for n in range(nt):
un = u.copy()
for i in range(1, nx-1):
u[i] = un[i] - un[i] * dt / dx *(un[i] - un[i-1]) + nu * dt / dx**2 *\
(un[i+1] - 2 * un[i] + un[i-1])
u[0] = un[0] - un[0] * dt / dx * (un[0] - un[-2]) + nu * dt / dx**2 *\
(un[1] - 2 * un[0] + un[-2])
u[-1] = u[0]

u_analytical = np.asarray([ufunc(nt * dt, xi, nu) for xi in x])

12
plt.figure(figsize=(11, 7), dpi=100)
plt.plot(x,u, marker='o', lw=2, label='Hesapsal')
plt.plot(x, u_analytical, label='Analitik')
plt.xlim([0, 2 * np.pi])
plt.ylim([0, 10])
plt.legend();
plt.savefig('compscieng_app45cfd2_03.png')

Alternatif Anlatim [4, sf. 559]


Tek boyutta Burgers’in denklemi,

∂u ∂u
+ u =0
∂t ∂x
olarak ta gösterilebilir. Denklemin muhafazakar formu (ayrıksallaştırmada işi
kolaylaştırıyor),

∂u ∂(u2 /2)
+ =0
∂t ∂x
u2 nereden geldi? u2 üzerinde ∂/∂x türevi uygulanınca Zincirleme Kanunu ile
2u · ∂u/∂x elde ederdik, o zaman bu formülü 2 ile bölerek iki üstteki forma erise-
biliriz.
Bu denklem taşınım formülünün bir şekli bir anlamda, eğer dalga hızı c = u
dersek. Dikkat edersek bu durumda dalga hızı dalga boyuna (amplitude) oranlı
hale geliyor, yani dalganın üst tarafında hız daha artacak. Denkleme eklenen bir
gayri lineerlik ilginç davranışlara yol açıyor. Taşınım formülünde dalganın her
kısmı aynı hızda hareket eder, “taşınır”, ve bu sebeple dalga şeklinde bir değişim
olmaz. Ama dalganın üst kısmı alt kısmına göre daha hızlı hareket ederse şekil
değişimi olur, dalganın üstü daha ileri gider, şok dalgası (shock wave) denen
durumu ortaya çıkartır.
Kaynaklar
[1] Barba, 12 steps to Navier–Stokes, Ders 1, https://nbviewer.jupyter.org/
github/barbagroup/CFDPython/tree/master/lessons/

13
[2] Bayramlı, Fizik, Isı ve Dalga Denklemlerini Türetmek
[3] Bayramlı, Fizik, Akış Dinamiği
[4] Landau, Computational Physics
[5] Mittleman, Applied Electromagnetics ENGN1560 Brown Lecture
[6] Logan, Applied Mathematics, Third Edition
[7] Bayramlı, Hesapsal Bilim, Dalga Denklemi

14
Sonlu Hacim (Finite Volume) Yöntemi - 1
Üç boyutlu kütle muhafazası üzerinden süreklilik formül [2]’de işlendi. Şimdi tek
boyutlu ortamda muhafaza kanunlarını işleyeceğiz, gaz dinamiği, genel aerodi-
namik konularında bu yaklaşım faydalı olacak. Sayısal çözmeye çalışılacak prob-
lemler, ki sonlu hacim (finite volume -FV-) yöntemi burada lazım, muhafaza ka-
nunları içeren hiperbolik sistemleridir (hyperbolic systems of conservation laws).
Bu tür sistemler zamana bağlı çoğunlukla gayrı lineer kısmi türevsel denklem-
lerdir (nonlinear PDE), ve aslında basit yapıları vardır. Tek yersel boyutta şuna
benzerler [3, sf. 1],

∂ ∂
u(x, t) + f(u(x, t)) = 0 (1)
∂t ∂x

Daha önce [1]’de Burgers’in denklemini görmüştük, bir PDE,

ut + uux = 0 (2a)

Bu denklem (1) ışığında düşünülebilir, eğer f(u) = u2 /2 tanımlarsak, (1) formülü,


yani ut + f(u)x = 0, formül (2a) ile aynıdır. O zaman,

1
ut + f(u)x = 0, f(u) = u2 (2b)
2

İleride lazım olur, (1)’i açarsak [6, sf. 29],

∂u ∂u
+ f 0 (u) =0 (5)
∂t ∂x
df
denklemi de doğrudur, ki f 0 (u) = du
.
(2) türünden denklemleri tek boyutta çözmeyi işleyeceğiz öncelikle, çünkü çok
boyutta çözüm tek boyuta indirgenerek yapılabiliyor.
Hiperbolik denklemleri analitik, kesin (exact) çözmek için birkaç konuyu yakından
anlamak lazım. Birincisi Riemann problemleri; bu yaklaşımla hiperbolik PDE’nin
başlangıç koşulu kesintili (discontinuous) bir fonksiyonla belirtiliyor ve bu çözümleri
çoğu durumda daha rahatlaştırılıyor, diğeri hiperbolik muhafaza kanunlarının
entegral formu.
İleride hiperbolik denklemleri FV ile sayısal çözerken de Riemann yaklaşımı fay-
dalı olacak. Kesintili başlangıç içeren denklemler çözebilmek önemli çünkü FV ile
sayısal çözüm yaparken uzayı parçalara bölüyoruz, ve her iki parçayı bir kesintili
başlangıç içeren Riemann problemi olarak temsil ediyoruz, bu pek çok parça or-
taya çıkartır tabii, bu sebeple tipik bir FV yaklaşımı her adımda pek çok Riemann
problemini çözecektir.

1
Entegral form lazım, çünkü sınırlı farklılıklarda (finite difference) olduğu gibi
ayrıksal olan fonksiyonun eşit aralıklarda tanımlı bir ızgaranın seçilmiş belli nok-
taları değil, her bölge, parçanın ortalaması, yani entegrali.
Entegral form ile başlayalım. Aslında diferansiyel form entegral formden türetilmiştir
-bu türetim pürüzsüzlük faraziyesi üzerinden yapılmıştır-. Özellikle kesintili
başlangıç şartları olduğu durumlarda diferansiyel formun her yerde düzgün işlemesi
mümkün değil, çünkü kesintilerde türev alınamıyor. Ayrıca pür kesintisiz olsa
bile şok oluşumu denen sebeplerle türevsel fonksiyonlar çözülemiyor. Bu prob-
lemlerle başedebilmek için entegral formu kullanmak gerekecek.
Bu formu [12]’de bulabiliriz.
Riemann Problemi
Kesintili ve iki parça içeren bir fonksiyon ile Burgers denkleminin çözümü mümkün;
bu aslında basit, ut + uux = 0 denklemi için başlangıç şartları


ul x < 0
u(x, 0) =
ur x > 0

olduğu durumda çözüm özgün bir zayıf çözümdür, eğer ul > ur ise (bu mümkün
seçeneklerden birincisi)


ul x < st
u(x, t) =
ur x > st

ki s şok hızıdır. Ya da


ul x/t < s
u(x, t) =
ur x/t > s

Kesinti noktası s hızında sağa ilerler, t anında olacağı yer st’dir.

Karakteristik Eğriler
Üstteki çözümü anlamak, hatta ona ulaşmak için karakteristik eğriler faydalı
oluyor. Karakteristik eğrilerle x, t ilişkisine odaklanıyoruz, u’nun zamana göre

2
değişmediği duruma bakıyoruz (yani du/ dt = 0) ve bu başlangıçtan bir dx/ dt
türevine erişmeye uğraşıyoruz, ve seçilen bazı başlangıç noktaları ve sabit bir
eğim için ortaya çıkan grafiği inceliyoruz. Türev basit bir dalga denkleminde,

x 0 (t) = a, x(0) = x0

olur daha çetrefil dalgalarda farklı. dx/ dt elde etmek için t ve x değişkenleri
olduğunu ve x = x(t) olduğunu hatırlayalım, yani u = u(x, t) = u(x(t), t) olur.
İki değişkenli fonksionlar üzerinde genel zincirleme kanununu [10]’da gördük,
mesela g(x(t), y(t)) için dg/ dt

dg ∂g dx ∂g dy
= · + ·
dt ∂x dt ∂y dt

İki değişkenli u’nun zamana göre türevi o zaman [9, sf. 17],

1
d ∂u dx ∂u dt
u(x(t), t)) = + 
dt ∂x dt ∂t dt

d ∂u dx ∂u
u(x(t), t)) = +
dt ∂x dt ∂t

Üsttekini sıfıra eşitlersek,

ut + ux x 0 (t) = 0

(2a)’yı hatırlayalım ve üstteki formülle eşleştirelim, Burgers denklemi için x 0 (t) =


u elde ederdik. Karakteristik diferansiyel denklemi,

x 0 (t) = u(x(t), t), x(0) = x0

Not: İki üsttekini (5) ile eşleyerek

dx(t)
f 0 (u) =
dt

karakteristik diferansiyeli de doğru.


Bu denklemi grafiklemek için t, x yerine x, t bazlı düşünmek daha iyi (bir önceki
grafikle alakayı görmek için, her iki grafikte x değişkeni yatay kordinatta oluyor)
altta bir başlangıç x0 seçiyoruz, ve buradan yukarı doğru u(x0 ) eğiminde (çünkü
0
x = u demiştik) bir çizgi gidiyor. Ama dikkat hayal etmek için eğimi tersine
çevirmek lazım, giriş Calculus’ta eğimler y/t, z/t bazında düşünülür burada t/x.

3
Devam edelim, ayrıca Riemann problemi çözdüğümüzü unutmayalım, u değerleri
değişik x noktalarında bir değerden diğerine geçiyor, bir uL var, bir de uR var,
eğimler bu değerleri yansıtmalı. Grafikleme sonrası,

O zihindeki ters çevirme işleminden önceki hali göstermek gerekirse, alttaki gibi

Görüldüğü gibi sıfırdan küçük x’ler için uL devrede orada bizim klasik bildiğimiz
eğim daha fazla, sıfırdan yukarı çıkınca eğim azalıyor, çünkü orada uR daha
küçük.
Şimdi iki üstteki ana grafiğe tekrar bakarsak, orada bir problem gözüküyor [11,
10:13]. Soldan gelen ve sağdan gelen karakteristikler kesişiyor. O zaman o nok-
tada iki çözüm olurdu. Bu nasıl mümkün olabilir ki? Doğanın o noktada yaptığı
şudur; oraya bir şok yerleştirmek, o bölgeyi bir şok bölgesi haline getirmek. O
bölgede, çizgi üzerinde eğim s olacak ve bu s aslında uL ve uR ’nin ortalaması.
st değeri nereden geliyor? x, u, x, t grafiklerini x’ler çakışacak şekilde alt alta
gösterelim, ve x, t grafiğinde bir t noktası işaretleyelim (yatay çizgi), O çizginin
şok bölgesini kestiği yerden aşağı doğru x, u grafiğine inelim, alttaki grafikte o
noktadaki u değeri t anındaki çözüm u(x, t).

4
O noktada katedilmiş mesafe st çünkü o noktada x 0 (t) = s. Bu işlemi daha önceki
t zamanları için yaparsak, kesikli sarı çizgi ortaya çıkacaktır. Bu da dalganın sağa
doğru akışını gösteriyor bir bakıma.
Şok hızını cebirsel bulalım. Daha önce tek boyutlu lineer taşınım akımı (convec-
tion) ile gördüğümüz durum burada da var, orada çözüm u(x, y) = u0 (x−ct) idi,
dalga hızı c. Şimdi hız u bu s şok hızınını verir, Burgers için hesabı s = (ul +ur )/2.
Şok hızının hesabı için kesinti bölgesinin yeterince uzağında M ve −M nokta-
larını seçelim, bu iki nokta arasındaki toplam kütlenin / dalganın değişiminin
hızı şok hızı s olacaktır.

ZM
d
u(x, t) dx = f(ul ) − f(ur )
dt −M

Salt entegralin nasıl hesaplanacağına bakarsak [3, sf. 31],

ZM Z st ZM
u(x, t) dx = ul dx + ur dx
−M −M st

= (M + st)ul + (M − st)ur

Şimdi zaman türevini geri koyalım, bu sağ tarafta s(ul −ur ) verir, hepsi bir arada,

ZM
d
u(x, t) dx = s(ul − ur )
dt −M

(8)’in sağ tarafını üstteki formüle koyunca,

f(ul ) − f(ur ) = s(ul − ur )

5
f(ul ) − f(ur )
s=
ul − ur

Böylece genel bir ifade elde ettik. Burgers denklemi özelinde, f(u) = u2 /2 olduğuna
göre,

1 1
f(ul ) − f(ur ) = u2l − u2r
2 2

O zaman

1
(ul + ur )(ul − ur ) = s(ul − ur )
2

diyebiliriz [5, sf. 46], basitleştirince,

1
s = (ul + ur )
2

Seyreltilmiş Dalga
İkinci seçenek, seyreltilmiş dalga sonucu, bu zayıf çözüm başlangıçta ul < ur
olduğu zaman ortaya çıkıyor.

Daha önceki formu tekrarlarsak, karakteristik ve x, u grafiği alt alta,

6
Bu grafikte karakteristik çizgilerini bulmak kolay değil, uL , uR kısımları yapılabilir
ama ortadaki kısmı anlamak için bu sefer x, u grafiğinden dönerek x, t’ye gitmek
gerekiyor. Altta uR ·t ve uL ·t noktaları bulunduktan sonra doğal olan onların düz
çizgi ile birleştirilmesidir, bu çizgi de karakteristiklerdeki o yayılma (fan) şeklini
ortaya çıkartır, tam ortasnda da tabii ki şok cizgisi olacaktır.
Bir çözüm, ki zayıf çözümlerde (bu konu ileride işlenecek), alttaki gibi olabilir,

 ul x < u l t
u(x, t) = x/t ul t 6 x 6 ur t

ur x > u r t

Sağ taraf yine daha önce olduğu gibi şu hale çevirilebilir (ki birazdan görülecek
kodu anlamak için de bu form faydalı)

 ul x/t < ul
u(x, t) = x/t ul 6 x/t 6 ur

ur x/t > ur

Çözümün Burgers denklemi için doğru olduğunun sağlamasını yapabiliriz, [9, sf.
34], mesela orta şart ul 6 x/t 6 ur kısmına bakalım, bu çözümü (2a)’ya sokarsak,

∂u ∂u ∂ x x ∂ x x x1
+u = + =− 2 + =0
∂t ∂x ∂t t t ∂x t t tt

İlk ve üçüncü şartın çözüm olduğu bariz çünkü sabit sayılar, ve türevleri alınırken
sıfırlanacaklar.
Entropi
Aslında üstteki seyreltilmiş dalga çözümü tek mümkün çözüm değil. Bu çözüm
bir zayıf çözüm (ileride göreceğiz) bu sebeple özgün değiller. Mesela uL = 0,
uR = 1 örnekleri üzerinden alttakiler de birer çözüm olabilirdi [4, sf. 27],

7
Çözümler soldan sağa doğru,


0 x < 12 t
u(x, t) =
1 x > 12 t

Hız s tabii ki daha önceki formülden hesaplandı,

u2R /2 − u2L /2
s= = 1/2
uR − uL

Ve

 0 x < 31 t
2 1
u(x, t) = t < x < 56 t
 3 3
1 x > 65 t

Fakat bu çözümler fiziksel değildir. Niye? Çünkü grafiklere dikkat edersek her
iki durumda da bazı karakteristik çizgiler şoktan dışarı çıkıyorlar, kıyasla en başta
ilk karakteristik grafiğinde karakteristikler şoka doğru gidiyorlar. Karakteristik-
ler bir anlamda bilgi akışının temsil ediyorlar, deterministik bir denklemi baz alan
bir evrimsel, dinamik denklem her zaman başlangıç verisinden başlayarak ileri
gitmelidir. Fakat hemen üstteki iki çözümde şok noktasında yeni bilgi yaratılıyor.
Bir diğer açıdan [6, sf. 35] belirtmek gerekirse, istediğimiz, bir karakteristiği
zamanı geriye sararak başlangıç şartına bağlayabilmektir. Üstteki iki çözümde
bunu yapmak mümkün değil.
Animasyon
Altta Burgers denkleminin şok ve seyreltilmiş dalga formu için çözümlerini ani-
masyon olarak bulabiliriz.

def qf(q): return 0.5*q*q

def exact_riemann_solution(xi,u_l,u_r):
# Shock wave
if u_l > u_r:
shock_speed = (qf(u_l)-qf(u_r))/(u_l-u_r)
q = (xi < shock_speed)*u_l \
+ (xi >=shock_speed)*u_r
return q

8
# Rarefaction wave
else:
q = (xi<=u_l)*u_l \
+ (xi>=u_r)*u_r \
+ (u_l<xi)*(xi<u_r)*xi
return q

def shock():
u_l, u_r = 5.0, 1.0

for i,t in enumerate(np.linspace(0,1,6)):


outfile = 'rieout/shock-%02d.png' % i
fig, ax = plt.subplots(figsize=(5, 3))

x = np.linspace(-4, 4, 1000)

q = np.array([exact_riemann_solution(xi/(t+1e-10),u_l,u_r) for xi in x])

ax.set_xlim(-4,4)

ax.plot(x,q,'-k',lw=2)

ax.set_title('t=%f' % t)

plt.savefig(outfile)

shock()

def rarefaction():

9
u_l, u_r = 2.0, 4.0

for i,t in enumerate(np.linspace(0,1,6)):


outfile = 'rieout/rarefaction-%02d.png' % (t*10)

fig, ax = plt.subplots(figsize=(5, 3))

x = np.linspace(-4, 4, 1000)

q = np.array([exact_riemann_solution(xi/(t+1e-10),u_l,u_r) for xi in x])

ax.set_xlim(-4,4)

ax.plot(x,q,'-k',lw=2)

ax.set_title('t=%f' % t)

plt.savefig(outfile)

rarefaction()

Animasyon olarak

! convert -delay 20 -loop 0 rieout/shock*.png shock.gif

! convert -delay 20 -loop 0 rieout/rare*.png rarefaction.gif

Animasyon sonuç dosyaları [7] ve [8]’de bulunabilir.

10
Kaynaklar
[1] Bayramlı, Hesapsal Bilim, Hesapsal Sıvı Dinamiğine Giriş
[2] Bayramlı, Fizik, Gazlar, Sıvılar 1
[3] Leveque, Numerical Methods for Conservation Laws
[4] Mishra, Numerical methods for conservation laws and related equations
[5] Cooper, Introduction to PDEs with Matlab
[6] Hesthaven, Numerical Methods for Conservation Laws
[7] Bayramlı, Animasyon, Şok Dalgası, https://github.com/burakbayramli/
classnotes/raw/master/compscieng/compscieng_bpp50fv1/shock.gif
[8] Bayramlı, Animasyon, Seyrelen (Rarefaction) Dalga https://github.com/
burakbayramli/classnotes/raw/master/compscieng/compscieng_bpp50fv1/
rarefaction.gif
[9] Lee, AM 260, Computational Fluid Dynamics, https://users.soe.ucsc.
edu/˜dongwook/wp-content/uploads/2021/am260/html/
[10] Bayramli, Cok Degiskenli Calculus, Ders 11
[11] Muller, Learn CFD, Lecture 15 - Part b, https://youtu.be/f8fuMRFZYwQ
[12] Bayramlı, Fizik, Gazlar, Sıvılar 2

11
Sonlu Hacim (Finite Volume) Yöntemi - 2
Amaç bir diferansiyel denklemi sayısal olarak çözmek. Metot olarak sonlu farklılık
(finite difference -FD-) yöntemi daha önce işlendi, bu yöntemde bir sürekli fonksiy-
onun değerlerini ayrıksal noktalar üzerinden temsil etmeye uğraşıyorduk. Bu
noktalar bir ekseni eşit aralıklara bölerek ortaya çıkartılıyordu, mesela altta görülen
bir tepeyle başlayıp inen f fonksiyonu i − 2, i − 1, i, .. noktalarında xi değerleri
üzerinden ui = u(xi ) ile tanımlanıyordu.

Sonlu hacim (FV) yönteminde durum biraz farklı; bir fonksiyonu belli nokta-
larındaki noktasal değerlerle değil, belli aralıklar arasında kalan değerlerinin av-
erajı olarak temsil ediyoruz.

Farklı bir grafik

İki üstte görülen grafikte mesela i ile i + 1 noktası ortasındaki i + 1/2 noktası ve i
ile i − 1 noktası ortasındaki i − 1/2 arasında kalan fonksiyonun averajı alınacak,
ona < ui > ya da ui diyoruz.

1
Z xi+1/2
1
ui = u(x) dx
∆x xi−1/2

Dikkat; i−1, i−2 değerleri i referanslı olduğu için eksi içerikli, i = 4 olsaydı onlar
3, 2, .. diye gidebilirdi. Ayrıca FD yönteminin aksine, indis değerlerine tekabül
eden xi , xi+1 değerleri herhangi bir yerde olabilir, böylece eşit aralıklı olmayan
ızgaralarla çalışmamız mümkün olur, bu FV yönteminin kuvvetlerinden biri.
Gerçi biz bu anlatımda ve kodda eşit aralık farz edeceğiz, ∆x, hx burada devreye
girer.

Muhafaza Kanunu Hesaplamak


Notasyonda f akış (flux) için kullanılır [2], ∆x için hx ,

Z xi+1/2
1
ui = u(x) dx (1)
hx xi−1/2

[5] yazısında muhafaza kanununun entegral formunu görmüştük,

Z x2 Z x2 Z t2 Z t2
ρ(x, t2 ) dx = ρ(x, t1 ) dx + ρ(x1 , t)v(x1 , t) dt − ρ(x2 , t)v(x2 , t) dt
x1 x1 t1 t1

f(ρ) = ρ(x, t)v(x, t) denebilir, ya da herhangi daha genel olarak ρ yerine herhangi
bir ölçüm u için f(u) = u(x, t)v(x, t), o zaman, ve biraz yer değişim sonrası,

Z x2 Z x2 Z t2 Z t2
u(x, t2 ) dx − u(x, t1 ) dx + f(x2 , t) dt − f(x1 , t) dt = 0
x1 x1 t1 t1

Bu formülü her sonlu hacim hücresi için kullanacağız. Zaman indisleri t, t + 1


olacak, üstte t1 , t2 yerine. Yer için x1 , x2 yerine bir j indisi merkezli xj−1/2 ve xj+1/2 .
Devam edelim, u(x1 , t1 ) içinde xj−1/2 ve tl oluyor, (zaman l indisi) ona da ulj−1
diyelim. x2 yerine xj+1/2 , sonuncuda zamanın hala değişken olduğu durum uj+1
olsun. Eğer x değişken ise, zaman indisi t2 = tl+1 için ul . Üstteki formülü bu
notasyonla değiştirip istenen zaman ve yer aralıklarına uygularsak,

2
Z xj+1/2 Z xj+1/2 Z tl+1 Z tl+1
l+1 l
u dx − u dx + f(uj+1/2 ) dt − f(uj−1/2 ) dt = 0
xj−1/2 xj−1/2 tl tl

Her şeyi hx ile bölelim,

Z xj+1/2 Z xj+1/2 Z tl+1 Z tl+1


1 l+1 1 l 1 1
u dx− u dx+ f(uj+1/2 ) dt− f(uj−1/2 ) dt = 0
hx xj−1/2 hx xj−1/2 hx tl hx tl

Bu formülde (1)’de tanımlanan ortalama formunu görüyoruz, kısaltma amaçlı


uj,l notasyonu oralarda kullanabiliriz,

Z tl+1 Z tl+1
1 1
uj,l+1 − uj,l + f(uj+1/2 ) dt − f(uj−1/2 ) dt = 0
hx tl hx tl

Şimdi son iki terime dikkat edelim, bu iki entegral zaman üzerinden alınıyor,
fakat Riemann problemini hatırlarsak çözüm u(x, t) sadece x/t değişkeni üzerinden
düşünülebilir, ve eğer x değişmiyorsa (ki öyle çünkü üstteki iki entegral t üzerinden,
x aynı) o zaman dt üzerinden entegral yerine, sabit u ile bir ayrıksal ht çarpımı
yeterlidir. Öyle ya sabit u üzerinden ve yine sabit / bilinen t adımı ht üzerinden
alan bir dikdörtgendir, bu alanın hesabı için çetrefil entegral yerine direk çarpım
yeterli.. Mesela ilk entegral,

Z tl+1
1 ht
f(uj+1/2 ) dt = f(uj+1/2 )
hx tl hx

olarak hesaplanabilir, çünkü u değeri x = xj±1/2 üzerinde değişmiyor. Aynı du-


rum ikinci entegral için de geçerli, o zaman iki üstteki formül

ht
uj,l+1 = uj,l − (f(uj+1/2 ) − f(uj−1/2 )) (2)
hx

olacak. Böylece l anındaki j hücresinin ortalamasını bir sonraki zaman adımı


l + 1’e nasıl aktaracağımızı, oraya geçiş yapacağımızın formülünü bulmuş olduk.
Rt
Eğer h1x tll+1 f(uj+1/2 ) dt entegralini entegral içindekiler çarpı ht ile gösterebiliyorsak,
tüm entegrali ht ile bölmek bize yaklaşık, “sayısal” bir f(uj+1/2 ) verecektir, ona
büyük harf ile Flj+1/2 diyelim, formülü [4, sf. 103]

Z tl+1
1
Flj+1/2 = f(uj+1/2,l ) dt
ht tl

F’ye sayısal akış (numerical flux) ismi de veriliyor. O zaman (2) formülü “akış
diferansiyel formunda” da yazılabilir,

3
ht
uj,l+1 = uj,l − (Fj+1/2,l − Fj−1/2,l )
hx

Sayısal akışı elde etmek için bize bir sayısal u lazım, bunu FV ile bulacağız, sonra
bu u’ları bildiğimiz f() akışına verince sayısal F elde edilecek.
Bu kod alttaki gibidir,

import scipy.integrate as integrate


import matplotlib.pyplot as plt
import numpy as np

alpha = 0.0
beta = 1.0

def init(z, alpha, beta):


return alpha + beta*np.sin(z)

#
# u_t + f(u)_x = 0 denklemi icin akis (flux) fonksiyonu
#
def flux(u):
return 0.5*u**2

def godunov_flux(uval):
fhat = np.zeros((len(uval),1))

for i in range(0,len(uval)-1):
ul = uval[i]; ur = uval[i+1]

s=(ul+ur)/2;
if ul > ur:
if s < 0:
fhat[i] = flux(ur)
else:
fhat[i] = flux(ul)
elif ul < ur:
if ur < 0:
fhat[i] = flux(ur)
elif ul > 0.:
fhat[i] = flux(ul)
else:
fhat[i] = 0

return fhat

a = 0
b = 2*np.pi
N = 80
T = 2.0

x = np.linspace(a,b,N)
dx = (b-a)/(N-1);
u = np.zeros((len(x)-1,1));

4
for i in range(0,N-1):
u[i] = (1.0/dx)*integrate.quad(init, x[i], x[i+1], args=(alpha,beta))[0]

dt = dx/(2*np.amax(np.amax(u)))

t = 0.0
i = 0
while t < T:
fR = godunov_flux(u)
fL = np.roll(fR,1)
u -= dt/dx*(fR - fL)
t = t+dt
i += 1

if i % 5 == 0:
plt.figure()
plt.plot(u)
plt.ylim(-1,1)
plt.savefig('/tmp/out-%03d.png' % i)
plt.close('all')

Kodda ilk önce başlangıç fonksiyonu tanımlandı, içinde sinüs olan init bu; Bu
fonksiyonun hücre bazında integrate.quad ile entegrali alındı, böylece her hücreyi
temsil eden o tek değeri elde ettik.

FV yöntemi bundan sonra o hücreler üzerinden hesabını yapacak, dinamik den-


klemi zamanda ilerletirken bunun hücrelerdeki o temsili değer üzerinden ya-
pacak.
Hücrelerin FV matematiği şöyle; mesela yanyana iki hücreye bakarsak, üstteki
resimde xi−2 ve xi−1 diyelim, soldan ilk iki hücre, bu iki değer sanki bir Rie-
mann problemini andırmıyor mu? Evet; ve Godunov’un icat ettiği FV çözümü
için kullanılan teknik te zaten budur. İki hücre ortasındaki xi−1/2 noktası hücre
sınırı kabul edilir ve önceki sonraki değerler uL ve uR imiş gibi Riemann çözümü
işletilir. Bu işlem tüm yanyana hücreler için işletilince bir zaman dilimi çözümü
elde edilir, sonraki zaman dilimi için bu işlem tekrar baştan hesaplanır.
Şimdi xi ile xi+1 arasındaki x1+1/2 sınırını baz alıp, ve [3]’teki Riemann çözümünü
baz alarak şunu yazalım [4, sf. 109],
uli > uli+1 için,

5

uli eğer s > (x − xi+1/2 )/t
u?i+1/2 = l
ui+1 eğer s < (x − xi+1/2 )/t

Daha önce gördük s dalga hızı, bu örnekte s = (un n


i + ui+1 )/2.

uli < uli+1 için,


 l
 ui eğer (x − xi+1/2 )/t 6 uli
u?i+1/2 = (x − xi+1/2 )/t eğer uli < (x − xi+1/2 )/t < uli+1
 l
ui+1 eğer (x − xi+1/2 )/t > uli+1

Bir kez Riemann çözümü elde edilince Godunov sayısal akışı u?i+1/2 ile kolayca
hesaplanabilir, akış fonksiyonu f() üzerinden F = f(u?i+1/2 ).

Üstteki formülleri daha da kolaylaştırmak mümkün, Godunov akışlarını x =


xi+1/2 noktasında hesapladığımız için bunu formülde x yerine koyunca,
uli > uli+1 için,


uli eğer s > 0
u?i+1/2 = l
ui+1 eğer s < 0

uli < uli+1 için,


 l
 ui eğer 0 6 uli
u?i+1/2 = (x − xi+1/2 )/t eğer uli < 0 < uli+1
 l
ui+1 eğer 0 > uli+1

Kod içinde üstte görülen hesabı tüm hücreler için yaptık, i,i + 1,i + 2.. ve Fj+1/2,l
hesabından bir önceki Fj−1/2,l , kod içinde önceki fL sonraki fR, onun için np.roll
ile vektör içindeki değerleri bir ilerleterek önceki ve sonraki hücrelerin aynı hizaya
düşmesini sağlıyoruz böylece Fj+1/2,l − Fj−1/2,l hesabı kolay bir şekilde fR-fL ile
bulunabiliyor.
Belli t anlarından alınmış görüntüler altta bulunabilir.

6
Animasyon [1],

! convert -delay 20 -loop 0 /tmp/out-*.png wave.gif

Kaynaklar
[1] Bayramlı, Animasyon, Godunov Sonlu Hacim Yontemi ile Burgers Denklem Cozumu
https://github.com/burakbayramli/classnotes/raw/master/compscieng/
compscieng_bpp50fv2/wave.gif
[2] Kloeckner, Numerical Methods for Partial Differential Equations CS555 / MATH555
/ CSE510 https://relate.cs.illinois.edu/course/cs555-s20/
[3] Bayramlı, Sonlu Hacim (Finite Volume) Yöntemi - 1
[4] Lee, Computational Fluid Dynamics
[5] Bayramlı, Fizik, Gazlar, Sivilar - 2

7
Sonlu Hacim (Finite Volume) Yöntemi - 3
Euler Gaz Denkleminin Çözümü
[2]’de gösterilen tek boyutta Euler gaz dinamiği formülünü yazalım,

   
ρ ρu
 ρu  +  ρu2 + p  = 0
E t (E + p)u x

Üstteki formülü matris notasyonu ile tekrar yazarsak [3, sf. 88],

Ut + F(U)x = 0

ki U, F birer vektor olacaklar,

   
ρ ρu
U =  ρu  , F(U) =  ρu2 + p 
E (E + p)u

Şimdi aynen yatay iletim (lineer advection) ve Burgers’ın denklemlerini hatırlarsak


onları su formde gösterebiliyorduk,

ut + f 0 (u)ux = 0

ki yatay iletim için f(u) = au ve Burgers için f(u) = 12 u2 , bu fonksiyonların


türevleri sırasıyla f 0 (u) = a ve f 0 (u) = uux , sonuç olarak

ut + aux = 0

ve

ut + uux = 0

denklemleri elde ediliyordu. Matris formu için de benzer mantık geçerli, eğer F
türevine Zincirleme Kuralı uygulanırsa,

∂F(U) ∂F ∂U
=
∂x ∂U ∂x

ki ∂F/∂U türevi bir Jacobian matrisi ortaya çıkartır. Bu Jacobian’ı alabilmek için
önce u1 , .., un değişkenlerini U seviyesinde tanımlayalım, ayrıca F öğeleri de f1 , .., fn
olarak etiketlemek iyi olacak, o zaman

1
      
u1 ρ f1 ρu
U =  u2  =  ρu  , F(U) =  f2  =  ρu2 + p 
u3 E f3 (E + p)u

Ve Jacobian bu durumda,
 
∂f1 /∂u1 ... ∂f1 /∂um
 ∂f2 /∂u1 ... ∂f2 /∂um 
∂F/∂U = 
 
.. .. .. 
 . . . 
∂fm /∂u1 . . . ∂fm /∂um

Üstteki türevleri alabilmek için f1 , f2 , f3 akış formüllerini u1 , u2 , u3 bazlı temsil


etmek gerekiyor. U vektörüne bakıyoruz, u1 = ρ, u2 = ρu, u3 = E. Buna bakarak
f1 kolay, u2 ile aynı, f1 = u2 = ρu.
f2 , f3 içinde p terimi var o sebeple onların karşılığını bulmak için p’yi u1 , u2 , u3
üzerinden göstermek lazım. Daha önce [2]’de görmüştük ki

1
E = ρ( u2 + e)
2
ve

p
e= =⇒ p = (γ − 1)ρe
(γ − 1)ρ

p için bize ρe lazım. Ona erişmeye uğraşalım. Türetim sırasında ρu2 ortaya
çıkabileceğini görüyoruz, onu u1 ve u2 elde etmek kolay, u22 /u1 = ρu2 . Şimdi
E formülünü açarsak (ve onun u3 olduğunu hatırlayalım),

1
E = u3 = ρu2 + ρe
2

Üstteki ρu2 değerini yerine koyalım,

1 u22
u3 = + ρe
2 u1

1 u22
ρe = u3 −
2 u1

ρe elde edildi. p içinde yerine koyarsak,

1 u22
 
p = (γ − 1) u3 −
2 u1

2
O zaman

u22 1 u22
 
f2 = + (γ − 1) u3 −
u1 2 u1

oluyor. f2 ’yi basitleştirirsek,

u22 (γ − 1) u22
= + (γ − 1)u3 −
u1 2 u1

u2
 
γ−1
= 2 1− + (γ − 1)u3
u1 2

1 u2
f2 = (3 − γ) 2 + (γ − 1)u3
2 u1

Devam edelim, f3 türetelim. E, p biliniyor, ama bir u lazım, u2 = ρu demiştik,


u = u2 /ρ diyebiliriz, u1 = ρ olduğuna göre, u = u2 /u1 .

1 u22
 
u2
f3 = u3 + (γ − 1)(u3 − )
2 u1 u1

u2
 
u3 u2 u3 u2
= + (γ − 1) − 22
u1 u1 2u1

u3 u2 γu3 u2 γu32 u3 u2 u32


= + − − +
u1 u1 2u21 u1 2u21

γu3 u2 1 u3
= − (γ − 1) 22
u1 2 u1

Böylece F(U) sonucunu bulmuş oluyoruz,

  u2
 
f1
 1 u22
F(U) =  f2  =  2 (3 − γ) u1 + (γ − 1)u3 

u3
f3 γu 2
u1 3
u − 21 (γ − 1) u22
1

Üstteki F(U) matrisine bakarak onun Jacobian matrisini artık ortaya çıkartabiliriz,

0 1 0
 
u2 2
∂F/∂U = 
1
− 2 (γ − 3)( u1
) (3 − γ)( u2
u1
) γ−1 
γu2 u3 γu3
− u2 + (γ − 1)( u 2 3
u1
) u1
− 2 (γ − 1)( u1 ) γ( u
3 u2 2
u1
2
)
1

3
Tekrar ana değişkenler u, E bazında temsil etmek iyi olur, pek çok yerde u2 /u1
ifadesi var, bu gayet basit ρu/ρ = u demektir. Bir uu2 u2 3 görüyoruz, onu açarsak
1
ρuE/ρ2 = ρE/ρ, ve u3 /u1 ise E/ρ olur, o zaman,

0 1 0
 
1
∂F/∂U =  − 2 (γ − 3)u2 (3 − γ)u γ−1 
3(γ−1)u2
− γuE
ρ
+ (γ − 1)u3 γE
ρ
− 2
γu

sonucuna erişiriz [4, sf. 52].


Riemann Roe yöntemi

from collections import namedtuple


import matplotlib.pyplot as plt
import numpy as np

primitive_variables = ('Density', 'Velocity', 'Pressure')


Primitive_State = namedtuple('State', primitive_variables)

def primitive_to_conservative(rho, u, p, gamma=1.4):


mom = rho*u
E = p/(gamma-1.) + 0.5*rho*u**2
return rho, mom, E

def conservative_to_primitive(rho, mom, E, gamma=1.4):


u = mom/np.maximum(1.e-15,rho)
p = (gamma-1.)*(E - 0.5*rho*u**2)
return rho, u, p

def roe_averages(q_l, q_r, gamma=1.4):


rho_sqrt_l = np.sqrt(q_l[0])
rho_sqrt_r = np.sqrt(q_r[0])
p_l = (gamma-1.)*(q_l[2]-0.5*(q_l[1]**2)/q_l[0])
p_r = (gamma-1.)*(q_r[2]-0.5*(q_r[1]**2)/q_r[0])
denom = rho_sqrt_l + rho_sqrt_r
u_hat = (q_l[1]/rho_sqrt_l + q_r[1]/rho_sqrt_r)/denom
H_hat = ((q_l[2]+p_l)/rho_sqrt_l + (q_r[2]+p_r)/rho_sqrt_r)/denom
c_hat = np.sqrt((gamma-1)*(H_hat-0.5*u_hat**2))

return u_hat, c_hat, H_hat

def Euler_roe(q_l, q_r, t, gamma=1.4):


rho_l = q_l[0]
rhou_l = q_l[1]
u_l = rhou_l/rho_l
rho_r = q_r[0]
rhou_r = q_r[1]
u_r = rhou_r/rho_r

u_hat, c_hat, H_hat = roe_averages(q_l, q_r, gamma)

dq = q_r - q_l

4
s1 = u_hat - c_hat
s2 = u_hat
s3 = u_hat + c_hat

alpha2 = (gamma-1.)/c_hat**2 *((H_hat-u_hat**2)*dq[0]+u_hat*dq[1]-dq[2])


alpha3 = (dq[1] + (c_hat - u_hat)*dq[0] - c_hat*alpha2) / (2.*c_hat)
alpha1 = dq[0] - alpha2 - alpha3

r1 = np.array([1., u_hat-c_hat, H_hat - u_hat*c_hat])


r2 = np.array([1., u_hat, 0.5*u_hat**2])
q_l_star = q_l + alpha1*r1
q_r_star = q_l_star + alpha2*r2

states = np.column_stack([q_l,q_l_star,q_r_star,q_r])
speeds = [s1, s2, s3]
wave_types = ['contact','contact', 'contact']

xmax = 1.0
x = np.linspace(-xmax, xmax, 100)
xi = x/(t+1e-10)
rho = (xi<s1)*states[0,0] + (s1<=xi)*(xi<s2)*states[0,1] + \
(s2<=xi)*(xi<s3)*states[0,2] + (s3<=xi)*states[0,3]
mom = (xi<s1)*states[1,0] + (s1<=xi)*(xi<s2)*states[1,1] + \
(s2<=xi)*(xi<s3)*states[1,2] + (s3<=xi)*states[1,3]
E = (xi<s1)*states[2,0] + (s1<=xi)*(xi<s2)*states[2,1] + \
(s2<=xi)*(xi<s3)*states[2,2] + (s3<=xi)*states[2,3]

q = conservative_to_primitive(rho, mom, E, gamma=1.4)

fig, axes = plt.subplots(3, 1, figsize=(5, 6), sharex=True)


axes[0].plot(x,q[0]); axes[0].set_ylim(0,4)
axes[1].plot(x,q[1]); axes[0].set_ylim(0,1)
axes[2].plot(x,q[2]); axes[0].set_ylim(0,4)
axes[0].set_title('t = ' + str(t))
plt.savefig('euler-roe-%d.png' % (t*100))

left = Primitive_State(Density = 3.,


Velocity = 0.,
Pressure = 3.)

right = Primitive_State(Density = 1.,


Velocity = 0.,
Pressure = 1.)

q_l = np.array(primitive_to_conservative(*left))
q_r = np.array(primitive_to_conservative(*right))

Euler_roe(q_l, q_r, t=0.2)


Euler_roe(q_l, q_r, t=0.4)
Euler_roe(q_l, q_r, t=0.6)
Euler_roe(q_l, q_r, t=0.8)

5
[devam edecek]
Kaynaklar
[1] Leveque, Riemann Problems and Jupyter Solutions

6
[2] Bayramlı, Fizik, Gazlar, Sıvılar - 2
[3] Toro, Riemann Solvers and Numerical Methods for Fluid Dynamics
[4] Hesthaven, Numerical Methods for Conservation Laws

7
Vektör Alanları ve Hesaplar
Entegre Edilmiş Kinetik Enerji (Integrated Kinetic Enerji)
Bir kasırganın tahrip edici kuvveti nedir? Katrina, İvan, Ian gibi kasırgalar 1
ila 5 arası sayılar ile kategorize ediliyorlar. Bu sayılar Saffir-Simpson skalasıyla,
ölçüm sistemiyle alakalı, bu sisteme göre fırtanın bir dakika içindeki en yüksek
ani rüzgarı (gust) ölçülür, ve tüm fırtına bu ölçüme göre kategorize edilir [1].
Bu sayının problemi kasırgayı sadece varabildiği en yüksek rüzgar hızı üzerinden
ölçmesi. Bu en yüksek hızın ölçülmesinin teknik olarak çıkarttığı problemler bir
yana, bu sayı bize fırtınanın kapladığı alan ve bu alan içinde rüzgar şiddetinin
nasıl dağıldığı hakkında hiçbir şey söylemiyor.
Camille ve Katrina örneklerini düşünelim, birincisinde şiddetli rüzgarlar var ama
ufak alana odaklı, ikincisinin en yüksek rüzgar hızı daha az olmasına rağmen
daha geniş alana yayılı ve SS skalasında daha küçük bir kasırga olarak geçiyor.
Fakat Katrinanın çok daha zarar verici olduğunu biliyoruz.
Acaba daha iyi bir ölçüm olamaz mı? Kasırgalar tehlikelidir çünkü ittikleri, hareket
ettirdikleri hava bloklarında kinetik enerji vardır. Daha az yoğun olsa da havanın
bir kütlesi var, günlük hayatta fazla düşünmesek bile bu kütle yeteri kadar hiza
ulaştığında etraftaki nesnelere çarpıp onları darmadığın edebiliyorlar, ağaçlar, bi-
nalar, ve bunu yaparken bir enerji transferi gerçekleştirmiş oluyorlar.
Bazı bilimciler bu sebeple SS skalası yerine İKE adlı bir hesabı tercih ediyorlar.
Bu hesap
Z
1 2
IKE = ρU dV
v 2

ile yapılır, v hacim, ρ yoğunluk, U ise hızdır. Aslında burada yapılan standart
1/2mv2 hesabının bir çeşidi (son v hız, hacim değil). Üstteki formül enerji hesabını
tüm rüzgar vektör alanı üzerinden entegre ediyor, yani sonsuz ufak alanların
hızları üzerinden enerji hesaplayıp bunları topluyor, sayısal bağlamda elimizde
sonlu sayıda kutular olacak, her kutu içindeki hava miktarını biliyoruz. Bu ku-
tunun içindeki kütleyi referans alabiliriz, kütle hesabı için aslında tek alan hesabı
yeterli olacak çünkü hava yoğunluğu olarak 1 kg/m3 farzedeceğiz, kutu yüksekliği
olarak 1 metre, böylece kutu alanı hesabı sonrası çarpı 1 kg/m3 ve çarpı 1 metre
ile aynı sayıdır, kütleyi direk alandan elde etmiş oluruz.
Her kutu içindeki rüzgar hızı yatay ve dikey bileşenleri u, v ile gelecek, hız =

u2 + v2 ile hız hesaplanabilir ya da, nasıl olsa hız karesi enerji için lazım, u2 + v2
yeterli. 0.5 çarpı hız karesi çarpı üstte bahsedilen kütleyi çarpıp bunu kasırganın
etkili olduğu coğrafyadaki tüm kutular için yapıp toplarsak kasırga İKE’sini elde
etmiş oluruz
Katrina fırtınası İKE hesabı için NOAA kurumundan gerekli veriyi alabiliriz.
Script wdata.py içinde enlem 25 boylam -90 noktasında 2005 yılı Eylül 30 tar-

1
ihindeki 1400 x 1400 km büyüklüğündeki bir alanın rüzgar verisini indirmek
için gerekli kodlar var. Bu kodlar işletildi ve gerekli veri 'uwind.npz, 'vwind.npz
içinde.

u_wind = np.load('uwind.npz')['arr_0']
v_wind = np.load('vwind.npz')['arr_0']
# ufak bir bolgeyi grafikle
xx,yy = np.meshgrid(np.linspace(1,59,59),np.linspace(1,60,60))
mi,mj = np.meshgrid(np.array(range(35,55,1)),np.array(range(10,30,1)))
plt.quiver(xx[mi,mj],yy[mi,mj],u_wind[mi,mj],v_wind[mi,mj])
plt.savefig('compscieng_xpp01vec_01.png')

Tüm veri üzerinden IKE hesabını yapalım şimdi,

gi,gj = u_wind.shape
cell_count = gi*gj
area = 2000*1e9 # m2, bu alani veriyi alirken tanimlamistik
cell_area = area / cell_count

wspeedsquare = u_wind**2+v_wind**2
wspeedsquare = wspeedsquare.reshape(-1)
wspeedsquare = wspeedsquare[wspeedsquare > 30.0]
IKE = np.sum(0.5*wspeedsquare*cell_area) / 1e12
print (np.round(IKE,2), 'terrajoule')

340.98 terrajoule

Bu enerji Camille fırtınasının enerjisinden daha fazladır.


Kaynaklar
[1] Wired, https://www.wired.com/2012/11/what-is-the-true-measure-
of-a-storm

2
Ekler
Yunan Harfleri

You might also like