Uygulama Notları: 3

FİZ219 - Bilgisayar Programlama I | 23/10/2020

  • Vektörler
    • Vektörlerin elemanlarına erişim
    • Vektör bileşenlerine değer atama
    • Sütun vektörleri
    • Vektörleri devirmek (transpose)
  • Vektörlerin dahil olduğu çarpımlar
    • Bir vektörün bir skalerle çarpımı
    • İki vektörün skaler çarpımı
    • İki vektörün vektör çarpımı
  • Matrisler
  • Aralık operatörü (:)
  • Matris İşlemleri
    • Devrik matrisler
    • Matrislerin toplaması, çıkarılması
  • Özel Matrisler (Sıfır, Bir, Birim)
    • Matrislerin çarpılması
      • Skaler-matris çarpımı
      • Matris-matris çarpımı
      • İki matrisin eleman bazında çarpımı
    • Matrisin Tersi

Emre S. Tasci emre.tasci@hacettepe.edu.tr

Vektörler

Fizikte gördüğümüz vektörlerin skalerlerden ayırt edici özelliği belli bir büyüklüğe ve yöne sahip olmalıydı. Yönlerini bileşenlerinin büyüklüğü belirliyordu. Fizikte, yaşadığımız evrene uygun olarak, genel olarak 3 boyutlu vektörlerle ilgilendik (sicim teorisi 10 (M-teoriye giderseniz 11'miş hatta) boyutlu vektörlerle çalışmakta), ama matematikten biliyoruz ki, 3'ten çok, n- boyutlu vektörler de mevcut. Hatta bir vektör illaki fiziksel bir niceliğe işaret etmek zorunda da değil. Bir excel çalışma sayfasını açıp, bir sütuna sırası ile yukarıdan aşağıya adınızı, soyadınızı, numaranızı, boyunuzu, derslerden aldığınız notları vs. yazdığınızda bu da bir vektördür (sütun vektörü); bu verileri bir sütun boyunca değil de, satır boyunca soldan sağa yazdığınızda ise yine bir vektör elde edersiniz (satır vektörü). Yeter ki tek bir derecede (yani ya bir sütunda, ya da bir satırda kalın). Vektörünüzün kaç bileşeni varsa, vektörünüz o boyutlu vektör olur.

İşe bilgisayar açısından bakarsak, vektör dediğimiz şey, birden fazla değeri yan yana (ve önemli: sıralı) tutan kutulardan ibaret. Örneğin, nasıl ki $\vec{a} = 3\hat{\imath}+4\hat{\jmath}$ vektörünü bileşenleri cinsinden $(3,4)$ olarak da temsil edebiliyoruz, bu şekilde düşündüğümüzde, vektörleri sayı dizileri olarak da kafamızda canlandırabiliriz.

Önce eski dost skaler değişkenleri hatırlayalım:

In [1]:
a = 5
a =  5

a bir skaler değişken, sadece bir değeri tutar, diyelim ki, iki değişkeni içinde tutan bir sayı dizisi olarak Ayı tanımlamak istedik:

In [2]:
A = [3, 4]
A =

   3   4

Notasyona dikkat! Sayı dizisini köşeli parantez içinde tanımlayıp, değerleri de virgülle ayırdık. Birinci bileşeni 3, ikinci bileşeni 4 olan, iki elemanlı bir sayı dizimiz oldu. Bunu eşdeğer şekilde: "x yönündeki bileşeni 3 birim uzunluğunda, y yönündeki bileşeni 4 birim uzunluğunda bir vektör" olarak da yorumlayabilirdik. Böyle bir vektörün boyutunu gerek Pisagor Teoremi'nden, gerekse de vektörlerin büyüklüğünü veren: $$ \|\vec{A}\| = \sqrt{\sum_{i}{a_i^2}}$$

formülünden hesaplayabiliriz:

In [3]:
power(3**2 + 4^2, 0.5)
ans =  5

(burada, üs almak için üç farklı ve eşdeğer yöntemi birlikte kullanmamız, züppelikten başka bir şey değildir!.. 8P 8) Ayrıca, bir vektörün boyunu (yani norm'unu) hesaplamak için, adı üstünde, norm komutunu da kullanabiliriz:

In [4]:
norm(A)
ans =  5

Vektörlerin elemanlarına erişim

Bir vektörün (/sayı dizisinin) elemanlarının bulunduğu konumlara indis adı verilir ve Octave'da sayma işlemi 1'den başlar: A vektörümüzün 1. indisi 3'e, 2. indisi ise 4'e eşittir. İstediğimiz indislere erişmek için parantezleri kullanırız:

In [5]:
# A'nın 2. indisine erişelim:
A(2)
ans =  4
In [6]:
# A'nın 1. indisine erişelim:
A(1)
ans =  3
In [7]:
# i diye bir skaler tanımlayıp, değerini 2 yapalım:
i = 2
i =  2
In [8]:
# Şimdi de A'nın i. indisli elemanına erişelim:
A(i)
ans =  4

Hiç şaşırtıcı olmadı. Sonuçta 'A(i)' diye bir komut gönderdiğimizde, yorumlayıcı, 'i' gördüğü yere, değeri olan '2'yi yerleştirdiğinden, ha A(i) yazmışız, ha A(2). Peki, ya A'nın 2. ve 1. indisli elemanlarını çağırmak istersek?

In [9]:
A([2,1])
ans =

   4   3

Dikkat edin, indis olarak, parantez içine parametre olarak istediğimiz indisleri tutan bir sayı dizisi gönderdik: [2,1]. Bunu istediğimiz kadar tekrarlayabiliriz, örneğin, A'nın 2., sonra 1., sonra tekrar 1., sonra tekrar 2. indisli bileşenlerini(/elemanlarını) çağıralım:

In [10]:
A([2,1,1,2])
ans =

   4   3   3   4

Değişkenleri parametre olarak kullanmayı A(i)den biliyoruz, buraya da uygulayalım:

In [11]:
n = [2,1,1,2]
A(n)
n =

   2   1   1   2

ans =

   4   3   3   4

Vektör bileşenlerine değer atama

Elemanlara ulaşabildiğimiz gibi, hazır ulaşmışken onların değerlerini de atayabiliriz -- tek yapmamız gereken yeni değerlerini tanımlamak:

In [13]:
# A'nın 2 indisli elemanını getir:
A(2)

# A'nın 2 indisli elemanına -1.5 değerini ata:
A(2) = -1.5
ans =  5
A =

   3.0000  -1.5000

In [14]:
norm(A)
ans =  3.3541
In [15]:
sqrt(3^2+(-1.5)**2)
ans =  3.3541
In [16]:
A = [1 2 3]
B = [9 5 7]
A =

   1   2   3

B =

   9   5   7

Sütun vektörleri

A ve B vektörlerinin ikisi de satır vektörleri (çünkü satır üzerinde tanımlandılar). Bir de sütun vektörleri var: onları da bileşenlerini alt alta yazarak tanımlayabiliriz:

In [17]:
C = [4
7
2]
C =

   4
   7
   2

Bu şekilde tanımlamak, yazarken pratik olsa da, sonrasında gidip düzeltme yapabilme açısından çok pratik değildir (alternatifler için bkz. hemen aşağıdaki alt-başlık).

Virgül & Boşluk | Noktalı virgül & Enter

Satır vektörleri tanımlarken virgül yerine boşluk; sütun vektörleri tanımlarken ise yeni satıra geçmek (yani "enter'a basmak") yerine, noktalı virgül kullanabiliriz. Örneğin:

In [18]:
A = [1 2 3]
# virgül ve boşluğu geçişli olarak da kullanabiliriz.
# Ayrıca, kaç boşluk bıraktığınız da önemli değildir.
B = [9, 5   7 ]
A =

   1   2   3

B =

   9   5   7

In [19]:
C = [4; 7;  2]
C =

   4
   7
   2

Vektörleri devirmek (transpose)

Bir satır vektörünü sütun vektörüne, veya bir sütun vektörünü satır vektörüne çevirmek için onu deviririz (yani transpose'unu alırız):

In [20]:
transpose(A)
ans =

   1
   2
   3

In [21]:
transpose(C)
ans =

   4   7   2

Bu işlem sıklıkla yapıldığı için, kolaylık olsun diye kesme işareti (') ile de tanımlanmıştır:

In [22]:
A'
C'
ans =

   1
   2
   3

ans =

   4   7   2

(Aslında kesme işareti tam olarak transpose() komutunun eşdeğeri değildir, devirme işlemine ek olarak, kompleks konjugesini de alır ama kompleks sayılar bizim göreceklerimizin dışında olduğundan, dersimizde güvenle kullanabiliriz ;)

Vektörlerin dahil olduğu çarpımlar

Vektörler 3 çeşit çarpıma dahil olurlar:

  1. Bir vektörün bir skalerle çarpımı
  2. İki vektörün skaler çarpımı
  3. İki vektörün vektör çarpımı

Bir vektörün bir skalerle çarpımı

Bir vektör bir skalerle çarpıldığında doğrultusu (yani üzerinde bulunduğu doğrunun açısı) değişmez, yalnızca büyüklüğü değişir. Eğer çarptığımız skaler negatif bir sayı ise, o zaman vektör ters yönde, fakat yine aynı doğru üzerinde yer alır. Vektörün boyu ise çarpıldığı skalerin mutlak değeri oranında değişir.

Örnek
$\vec{A} = \hat{\imath}+4\hat{\jmath}+3\hat{k}$ vektörünü $s=5$ sayısı ile çarpalım:

In [2]:
A = [1,4,3]
s = 5
s*A
A =

   1   4   3

s =  5
ans =

    5   20   15

In [3]:
# A'nın boyu:
norm(A)

# çarpımın boyu:
norm(s*A)
ans =  5.0990
ans =  25.495
In [4]:
# Boyların oranı
25.495 / 5.0990
ans =  5

İki vektörün skaler çarpımı

Vektörlerin skaler çarpımının İngilizcesi'ne "scalar product" denmekte. Product kelimesi de hem "çarpım", hem de "ürün" anlamına geldiğinden, "scalar product" terimini "skaler ürün" olarak da okuyabiliriz: yani, sonucumuz (ürünümüz) bir skaler olacak -- işleme iki vektör girip, dışarıya bir skaler çıkacak.

Octave'da, iki vektörü skaler çarpmak için kullandığımız komut, işlemin diğer adı olan "nokta çarpım"dan ("dot product") gelen dot komutu (aritmetikte çarpmayı hem nokta, hem de çarpım işaretiyle temsil ettiğimizden, vektörlere dair iki farklı çarpma işleminden birini nokta, diğerini ise çarpım işaretiyle temsil ediyoruz).

Matematiksel olarak, $\vec{A}$ ve $\vec{B}$ vektörlerinin skaler çarpımı şu şekilde tanımlanır:

$$\vec{A}\cdot\vec{B} = \|\vec{A}\|\,\|\vec{B}\|\,\cos\theta$$

(burada $\theta$, iki vektör arasındaki açı olmakta). Bu formülü kullanarak, birim vektörler arasındaki ilişkiyi çıkartabiliriz:

$$\left. \begin{array}{c} \hat\imath \perp \hat\jmath, \hat{k} \\ \hat\jmath \perp \hat\imath, \hat{k} \\ \hat k \perp \hat\jmath, \hat{\imath} \end{array}\right\}\rightarrow \begin{array}{c} \hat\imath\cdot\hat\imath = \hat\jmath\cdot\hat\jmath = \hat{k}\cdot\hat{k} = 1\\ \hat\imath\cdot\hat\jmath = \hat\jmath\cdot\hat{k} = \hat{k}\cdot\hat\imath = 0 \end{array}$$

$\vec{A}$ ve $\vec{B}$ vektörlerinin skaler çarpımının vektörlerin bileşenler üzerinden tanımı ise şöyledir:

$$\vec{A}\cdot\vec{B} = \sum_{i}{a_i .b_i}$$

Bu iki formülü birlikte kullanarak, iki vektör arasındaki açı kolayca hesaplanabilir. Örnek olarak $\vec{A} = \hat{\imath}+4\hat{\jmath}+3\hat{k}$ ile, $\vec{B} = 9\hat{\imath}+5\hat{\jmath}+7\hat{k}$ vektörleri arasındaki açıyı hesaplayalım:

In [5]:
A = [1,4,3]
B = [9,5,7]
AB = A(1)*B(1) + A(2)*B(2) + A(3)*B(3)
A =

   1   4   3

B =

   9   5   7

AB =  50

Bileşen çarpımlarını uzun uzun elle yapmak yerine, doğrudan dot komutunu kullanabiliriz:

In [6]:
AB = dot(A,B)
AB =  50

Çarpım için iki eşitliğimiz olduğundan bir tanesini kullanarak bulduğumuz bu sonucu diğerine eşitleyip, açı terimini yalnız bırakırsak: $$\cos\theta = \frac{\vec{A}\cdot\vec{B}}{\|\vec{A}\|\|\vec{B}\|}$$

In [7]:
costheta = dot(A,B)/(norm(A)*norm(B))
costheta =  0.78762

Buradan da bulduğumuz değerin $\cos^{-1}$ ($\arccos$) değerini alırsak açıyı radyan cinsinden elde ederiz:

In [8]:
theta_radyan = acos(costheta)
theta_radyan =  0.66386

Radyan cinsinden verilmiş bir açıyı derece cinsine çevirmek için pi'ye bölüp 180 ile çarparız:

In [9]:
theta_derece = theta_radyan / pi * 180
theta_derece =  38.036

Açıları sıklıkla derece ile temsil ettiğimizden dolayı, trigonometrik fonksiyonların doğrudan derece cinsinden açılarla çalışan versiyonları vardır: cosd, sind, tand, acosd gibi, sonlarına derece'nin (degree) "d"sini alırlar. Bu şekilde, tekrar hesaplarsak:

In [10]:
costheta = dot(A,B)/(norm(A)*norm(B))
theta_derece = acosd(costheta)
costheta =  0.78762
theta_derece =  38.036

Çok karmaşık görünmeyecekse, bütün işlemleri tek bir komutta toplayabiliriz:

In [12]:
aci = acosd(dot(A,B)/(norm(A)*norm(B)))
aci =  38.036

Vektörlerin koordinat sistemindeki görüntüleri şu şekilde; aralarındaki açı bakın bakalım $38^o$'ye benziyor mu? ;) 3DVectors_CalcPlot3D.png

Şekli CalcPlot3D yardımıyla çizdim, bu işler için gayet faydalı bir araç, aklınızda bulunsun.

İki vektörün vektör çarpımı

Vektör çarpım ("vector product"), "adı üzerinde", sonuç olarak vektör çıkartan bir çarpımdır. Sonucun vektör olmasından ötürü, hem boyu, hem de yönü vardır. Yönü de çarpılan iki vektöre dik yöndedir. Nasıl ki iki nokta bir doğru tanımlıyorsa (bir başka deyişle "iki noktadan bir doğru geçer"), iki vektör de bir düzlem tanımlar (yani, rasgele iki vektör aldığınızda, bir dosya kağıdını bükmeden bunların ikisini de içerecek şekilde tutabilirsiniz). Bir düzleme dik iki doğrultu olduğundan, çarpım sırası önemlidir, sonuç vektörünün yönünü sağ el kuralı ile belirleriz.

Birbirine paralel ya da anti-paralel iki vektöre sonsuz sayıda dik doğrultu olduğundan, bu şekilde yönlenmiş iki vektörün vektör çarpımı sıfır olur. Bunu sonuç vektörünün büyüklüğünü veren formüldeki $\sin\theta$ çarpanının 0 ve $180^o$ derecelerde otomatikman 0 getirmesinden de anlayabiliriz.

Çarpım vektörünün boyu: $$\vec{A}\times\vec{B} = \|\vec{A}\|\,\|\vec{B}\|\,\sin\theta$$ ile tanımlanır. Sinüs fonksiyonunun tek fonksiyon olmasından ötürü $\left(\sin{-\theta} = -\sin{theta}\right)$:

$$\vec{A}\times\vec{B} = -\vec{B}\times\vec{A}$$

olduğu da açıktır.

Yönü ise, yukarıda da belirttiğimiz üzere iki çarpan vektöre de dik olacak şekilde çıkar.

Yönünü de içeren çarpım formülü biraz karışık görünse de: $$\vec{A}\times\vec{B} = \left(a_y b_z - a_z b_y\right)\hat{\imath} +\left(a_z b_x - a_x b_z\right)\hat{\jmath} +\left(a_x b_y - a_y b_x\right)\hat{k}$$

determinant tanımından kolay şekilde yazılabilir:

$$\vec{A}\times\vec{B} = \begin{vmatrix} \hat\imath & \hat\jmath & \hat{k}\\ a_x & a_y & a_z\\ b_x & b_y & b_z \end{vmatrix}$$

Bu formüllerden, birim vektörler arasındaki ilişki ise:

$$\left. \begin{array}{c} \hat\imath \perp \hat\jmath, \hat{k} \\ \hat\jmath \perp \hat\imath, \hat{k} \\ \hat k \perp \hat\jmath, \hat{\imath} \end{array}\right\}\rightarrow \begin{array}{c} \hat\imath\times\hat\imath = \hat\jmath\times\hat\jmath = \hat{k}\times\hat{k} = 0\\ \hat\imath\times\hat\jmath = \hat{k};\; \hat\jmath\times\hat{k} = \hat{\imath};\;\hat{k}\times\hat\imath = \hat{\jmath} \end{array}$$

olarak bulunur.

Octave'da vektör çarpım işlemi ("cross product"), cross komutu ile gerçekleştirilir.

Örnek #1
Anlaşılma kolaylığı açısından, örneklerimize x ve y yönlerinde iki vektörün çarpımıyla başlayalım:

$$\vec{Q} = 5\hat{\imath}$$$$\vec{R} = 3\hat{\jmath}$$

olsun.

Çarpım vektörü ikisine de dik olacağından, ya +z, ya da -z yönünde olmalıdır. Sağ el kuralını kullanarak, $\vec{Q}\times\vec{R}$ nin +z yönünde; $\vec{R}\times\vec{Q}$ nun ise -z yönünde olacağını görürüz. Büyüklüğü ise, $\sin{90^o} = 1$ olduğundan, $5\times 3=15$ olur.

$$\vec{Q}\times\vec{R} = 5\hat{\imath} \times 3\hat{\jmath} = \left(5\,.\,3\right)\left(\hat{\imath} \times \hat{\jmath}\right) = 15 \hat{k}$$

Bu işlemleri Octave'da yapalım:

In [14]:
Q = [5 0 0]
R = [0 3 0]
S = cross(Q,R)
Q =

   5   0   0

R =

   0   3   0

S =

    0    0   15

Çarpım sonucu ortaya çıkan vektöre S adını verdik; bakalım $\vec{S}$ gerçekten de $\vec{Q}$ ile $\vec{R}$ vektörlerine dik mi?

In [15]:
# Doğrudan skaler çarpımda ürettiğimiz komutu kullanıyoruz:
aci_QS = acosd(dot(Q,S)/(norm(Q)*norm(S)))
aci_RS = acosd(dot(R,S)/(norm(R)*norm(S)))
aci_QS =  90
aci_RS =  90

Tabii, dikliği çok daha kolay bir şekilde de kontrol edebilirdik: birbirine dik iki vektörün skaler çarpımının 0 olacağını biliyoruz, o halde:

In [16]:
dot(Q,S)
dot(Q,R)
ans = 0
ans = 0

Örnek #2
$\vec{A} = \hat{\imath}+4\hat{\jmath}+3\hat{k}$ ile, $\vec{B} = 9\hat{\imath}+5\hat{\jmath}+7\hat{k}$ vektörlerimizi vektörel çarpımla çarpalım:

In [19]:
A = [1, 4, 3]
B = [9, 5, 7]
C = cross(A,B)
A =

   1   4   3

B =

   9   5   7

C =

   13   20  -31

In [20]:
# A ile B'nin arasındaki açı:
aci = acosd(dot(A,B)/(norm(A)*norm(B)))
aci =  38.036
In [21]:
# Formülden C=AxB'nin boyu:
boy_C = norm(A)*norm(B)*sind(aci)
# (Dikkat: aci derece cinsinden olduğundan, "sind" kullanıyoruz)
boy_C =  39.115
In [22]:
# C'nin bileşenlerinden hesaplanan boyu:
norm_C = norm(C)
norm_C =  39.115
In [23]:
# C ile A ve B arasındaki açı:
aci_CA = acosd(dot(C,A)/(norm(C)*norm(A)))
aci_CB = acosd(dot(C,B)/(norm(C)*norm(B)))
aci_CA =  90
aci_CB =  90

Matrisler

Vektörleri bir excel çalışma sayfasındaki satır veya sütun boyunca sıralanan veriler olarak gözümüzde canlandırmıştık; matrisleri ise bir çalışma sayfasının tamamı olarak görebiliriz. Bir matrisin 1'den fazla satırı ve 1'den fazla sütunu olur (satır veya sütun sayısı 1 olursa, o zaman alt kümesi olan vektörlerden bahsediyoruz demektir).

Matrislerde satırlar önceliklidir, yani her zaman için önce satırı, ardından sütunu kast ederiz.

2 satırlı, 3 sütunlu bir matrisi, vektörleri tanımladığımıza benzer olarak tanımlarız, örneğin:

In [24]:
M = [11 12 13; 21 22 23]
M =

   11   12   13
   21   22   23

(tıpkı vektörlerde olduğu gibi, boşluklarla virgülleri; noktalı virgüllerle de Enter tuşunu geçişli olarak kullanabiliriz)

Matrislerin elemanlarına ulaşmak için yine parantezler içinde ulaşmak istediğimiz indisi belirtiriz (her zaman için önce satır, sonra sütun numarası!)

Örnekler

In [25]:
# 2. satırın, 3. sütunundaki eleman:
M(2,3)
ans =  23
In [27]:
# 1. satırın, 2. sütunundaki eleman:
M(1,2)
ans =  12
In [28]:
# Vektörlerde yaptığımız gibi, birden fazla elemanı seçebiliriz:
# 2. satırın, 2. ve 3. sütunlarındaki elemanlar:
M(2,[2,3])
ans =

   22   23

In [29]:
# 1. ve 2. satırların, 3. sütunundaki elemanlar:
M([1,2],3)
ans =

   13
   23

In [30]:
# 1. ve 2. satırların, 1. ve 3. sütunlarındaki elemanlar:
M([1,2],[1,3])
ans =

   11   13
   21   23

In [31]:
# Sütunları ters sırayla çağıralım:
M([1,2],[3,2,1])
ans =

   13   12   11
   23   22   21

In [32]:
# Satırları ve sütunları ters sırayla çağıralım:
M([2,1],[3,2,1])
ans =

   23   22   21
   13   12   11

Alıştırma:
$M$ matrisinin köşelerindeki elemanları çağırabilir misiniz? Yani: $$\begin{bmatrix}11 & 13\\ 21 & 23\end{bmatrix}$$ olacak şekilde.

Aralık operatörü (:)

Az sayıda satır/sütunlu matrislerle uğraşırken belki tek tek belirtilebilir ama eninde sonunda boyumuzu aşan boyutlarda matrislerle çalışmamız gerekecek. Bu tür durumlarda ise aralık operatörünü kullanırız.

En basit haliyle, iki sayının arasına : koyduğumuzda, bu "ilk sayıdan ikincisine kadar, onu geçmeden, birer birer arttır" anlamına gelir:

In [33]:
# 1'den 5'e:
1:5
ans =

   1   2   3   4   5

In [36]:
# 2.3'ten 5.2'ye:
2.3:5.2
ans =

    2.3000    3.3000    4.3000

Görüldüğü üzere, ondalıklı sayılarda da sorunsuz çalışıyor: 2.3'ten başlayıp, 1 arttırarak gidiyoruz: 2.3, 3.3, 4.3... 5.3'e gelindiğinde ise, bu sayı sınırımız olan 5.2'nin dışında olduğundan içerilmiyor ve sayım orada duruyor.

In [37]:
# -pi'den +2pi'ye:
-pi:2*pi
ans =

 Columns 1 through 8:

   -3.1416   -2.1416   -1.1416   -0.1416    0.8584    1.8584    2.8584    3.8584

 Columns 9 and 10:

    4.8584    5.8584

Tabii ki birer birer arttırmak yaygın olsa da, genel bir tercih olmamalı. Diyelim ki, 10'dan geriye birer birer saymak istiyoruz, ya da 3.1'den 4.0'a 0.1 adımlarla saymak istiyoruz... Bu durumda devreye, aralık operatörünün 3. parametresi olarak adım parametresi girer. Adım parametresi, başlangıç ve bitiş sınırlarının arasına yazılır: başlangıç:adım:bitiş şeklinde:

In [38]:
# 10'dan 0'a geri geri sayalım:
10:-1:0
ans =

   10    9    8    7    6    5    4    3    2    1    0

In [39]:
# 3.1'den 4.0'a, 0.1'lik adımlarla sayalım:
3.1:0.1:4.0
ans =

 Columns 1 through 8:

    3.1000    3.2000    3.3000    3.4000    3.5000    3.6000    3.7000    3.8000

 Columns 9 and 10:

    3.9000    4.0000

Aralık operatörlerini birbirleriyle köşeli parantezler ([] - yani sayı dizileri içerisinde) birleştirebiliriz:

In [50]:
[-10:-7, 5:-2:1, 6:9]
ans =

  -10   -9   -8   -7    5    3    1    6    7    8    9

Bu yeni öğrendiğimiz aralık operatörünü kullanarak, elemanları 1'den 42'e olan 7x6'lık (yani 7 satırlı ve 6 sütunlu) bir matris tanımlayalım:

In [44]:
N = [1:6;7:12;13:18;19:24;25:30;31:36;37:42]
N =

    1    2    3    4    5    6
    7    8    9   10   11   12
   13   14   15   16   17   18
   19   20   21   22   23   24
   25   26   27   28   29   30
   31   32   33   34   35   36
   37   38   39   40   41   42

In [45]:
# 1., 3. ve 5. satırlarını çağıralım:
N(1:2:5,[1,2,3,4,5,6])
ans =

    1    2    3    4    5    6
   13   14   15   16   17   18
   25   26   27   28   29   30

satır kısmı tamam da, sütun kısmına öyle tek tek hepsini girmek biraz kabaca oldu, daha iyi şekilde yapamaz mıyız?

In [46]:
# Daha güzel bir şekilde 1., 3. ve 5. satırlarını çağıralım:
N(1:2:5,1:6)
ans =

    1    2    3    4    5    6
   13   14   15   16   17   18
   25   26   27   28   29   30

Bu sefer gayet şık oldu. Buna ek olarak, eğer aralığımız "hepsi" ise, o zaman sadece ":" yazmamız yeterli olur (satır kısmına yazarsak "tüm satırlar", sütun kısmına yazarsak da "tüm sütunlar" anlamına gelir):

In [47]:
# En şık şekilde 1., 3. ve 5. satırlarını çağıralım:
N(1:2:5,:)
ans =

    1    2    3    4    5    6
   13   14   15   16   17   18
   25   26   27   28   29   30

In [48]:
# (Bütun satırların) 2., 5. ve 6. sütunlarını çağıralım:
N(:,[2,5,6])
ans =

    2    5    6
    8   11   12
   14   17   18
   20   23   24
   26   29   30
   32   35   36
   38   41   42

Tıpkı vektörlerde olduğu gibi, matrislerde de çağırdığımız kısma dilersek yeni bir değer atayabiliriz:

In [49]:
N([1,7],[1,2,5,6]) = -999
N =

  -999  -999     3     4  -999  -999
     7     8     9    10    11    12
    13    14    15    16    17    18
    19    20    21    22    23    24
    25    26    27    28    29    30
    31    32    33    34    35    36
  -999  -999    39    40  -999  -999

Matris İşlemleri

Matrisin elemanlarına nasıl ulaşıp, nasıl değiştirebileceğimizi gördüğümüze göre, temel matris işlemlerine geçebiliriz.

Devrik matrisler

Bir matrisi devirmek (transpose'unu almak), tıpkı vektörleri devirmeye benzer:

In [51]:
M = [11 12 13; 21 22 23]
M =

   11   12   13
   21   22   23

In [52]:
transpose(M)
ans =

   11   21
   12   22
   13   23

In [53]:
M'
ans =

   11   21
   12   22
   13   23

Matrislerin toplaması, çıkarılması

İki matrisin birbiriyle toplanabilmesi / birbirlerinden çıkarılabilmesi için bariz şekilde aynı boyutlarda olmaları gerekmektedir. Toplama ve çıkarma işlemleri birbirine karşılık gelen elemanlar arasında yapılır. Eğer taraflardan biri skaler ise, otomatik olarak matrisin her bir elemanıyla işleme girer.

In [54]:
K = [-3:3;-2:4;-1:5]
K =

  -3  -2  -1   0   1   2   3
  -2  -1   0   1   2   3   4
  -1   0   1   2   3   4   5

In [55]:
L = [1,1,1,1,1,1,1;1,1,1,1,1,1,1;1,1,1,1,1,1,1]
L =

   1   1   1   1   1   1   1
   1   1   1   1   1   1   1
   1   1   1   1   1   1   1

In [56]:
K+L
ans =

  -2  -1   0   1   2   3   4
  -1   0   1   2   3   4   5
   0   1   2   3   4   5   6

In [57]:
K-L
ans =

  -4  -3  -2  -1   0   1   2
  -3  -2  -1   0   1   2   3
  -2  -1   0   1   2   3   4

In [58]:
3 + K
ans =

   0   1   2   3   4   5   6
   1   2   3   4   5   6   7
   2   3   4   5   6   7   8

In [59]:
8 - L
ans =

   7   7   7   7   7   7   7
   7   7   7   7   7   7   7
   7   7   7   7   7   7   7

Özel Matrisler (Sıfır, Bir, Birim)

Üstteki L matrisi gibi her seferinde uzun uzadıya yazmayalım diye, birkaç özel matris hazırda tanımlanmıştır. Bunlar:

  • Sıfırlardan oluşan zeros matrisi
  • Birlerden oluşan ones matrisi
  • Köşegenlerinde birlerin olduğu, eye birim matrisi
In [60]:
Z = zeros(3,5)
Z =

   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0

In [61]:
M1 = ones(3,5)
M1 =

   1   1   1   1   1
   1   1   1   1   1
   1   1   1   1   1

In [63]:
I = eye(3,3)
I =

Diagonal Matrix

   1   0   0
   0   1   0
   0   0   1

Matrislerin çarpılması

Matrisler de, tıpkı vektörler gibi, farklı türden çarpma işlemlerine girerler:

  • Skaler-matris çarpımı
  • Matris-matris çarpımı
  • İki matrisin eleman bazında çarpımı

Skaler-matris çarpımı

Bir matris skalerle çarpıldığında, her bir elemanı o skalerle çarpılır.

In [65]:
# Örneğin, her bir elemanı 5 olan 3x7'lik bir matris tanımlayalım:
M5 = 5*ones(3,7)
M5 =

   5   5   5   5   5   5   5
   5   5   5   5   5   5   5
   5   5   5   5   5   5   5

Matris-matris çarpımı

İki matrisin birbirleri ile çarpılabilmesi için, sol taraftaki matrisin sütun sayısının, sağ taraftaki matrisin satır sayısına eşit olması gerekmektedir. Sonuç matrisinin satır sayısı sol matrisinkine; sütun sayısı da sağ matrisinkine eşit olur:

$$A_{(m\times n)}\cdot B_{(n\times k)}=C_{(m\times k)}$$

Çarpımda, sol matrisin satırları ile sağ matrisin sütunlarının kesiştiği hücrenin sonuç matrisindeki değeri, karşılıklı elemanların sıralı çarpımlarının toplanmasıyla bulunur (böyle resmi yazınca karmaşık, ciddi bir şey gibi oldu ama aslında gayet basit ve doğrudan, şöyle ki):

Matrix_multiplication_diagram.svg
Kaynak: Wikiwand

$$\overset{4\times 2 \text{ matris}}{\begin{bmatrix} {a_{11}} & {a_{12}} \\ \cdot & \cdot \\ {a_{31}} & {a_{32}} \\ \cdot & \cdot \\ \end{bmatrix}}_{(4\times 2)} \overset{2\times 3\text{ matris}}{\begin{bmatrix} \cdot & {b_{12}} & {b_{13}} \\ \cdot & {b_{22}} & {b_{23}} \\ \end{bmatrix}}_{(2\times 3)}= = \overset{4\times 3\text{ matris}}{\begin{bmatrix} \cdot & c_{12} & c_{13} \\ \cdot & \cdot & \cdot \\ \cdot & c_{32} & c_{33} \\ \cdot & \cdot & \cdot \\ \end{bmatrix}}_{(4\times 3)} $$

Şekilde daire ile işaretlenmiş $c_{12}$ ve $c_{33}$ elemanlarının değeri:

$$\begin{align} c_{12} & = {{a_{11}}}{{b_{12}}} + {{a_{12}}}{{b_{22}}} \\ c_{33} & = {{a_{31}}}{{b_{13}}} + {{a_{32}}}{{b_{23}}} \end{align}$$

şeklinde hesaplanır.

Örnek: $$A=\begin{bmatrix}1 & 2 & 3\\4 & 5 & 6\end{bmatrix}_{(2\times 3)},\;B=\begin{bmatrix}7 & 8\\9 & 10\\ 11&12\end{bmatrix}_{(3\times 2)}\rightarrow C=A\cdot B=?$$

Daha hiçbir işlem yapmadan, $C$ sonuç matrisinin $(2\times 2)$lik bir matris olacağını görebiliriz. Bu $C$ matrisinin üst-sol elemanı, $A$'nın üst satırı ile $B$'nin sol sütununun kesişmesine karşılık geldiğinden: $$\begin{align*}c_{11} &= a_{11} b_{11} + a_{12} b_{21} + a_{31} b_{13}\\ &=1\times7+2\times9+3\times11 = 7+18+33\\ &=58\end{align*}$$

olarak bulunur. Geriye kalan diğer 3 elemanı da benzer şekilde kesişimlerden hesaplarız:

  • $c_{12}$ (üst-sağ): $A$'nın üst satırı ile $B$'nin sağ sütunu
  • $c_{21}$ (alt-sol): $A$'nın alt satırı ile $B$'nin sol sütunu
  • $c_{22}$ (alt-sağ): $A$'nın alt satırı ile $B$'nin sağ sütunu

Octave'da ise doğrudan çarpım operatörü ile iki matrisi çarpabiliriz:

In [67]:
A = [1:3;4:6]
B = [7,8;9,10;11,12]
C = A * B
A =

   1   2   3
   4   5   6

B =

    7    8
    9   10
   11   12

C =

    58    64
   139   154

İki matrisin eleman bazında çarpımı

Bazen de, iki matrisi toplamada olduğu gibi, eleman bazında çarpmak isteriz (bunun için tabii ki ikisinin de boyutlarının aynı olması gerekmektedir). İşlemin eleman bazında olacağını belirtmek için, işleme dair operatörün başına nokta (.) koyarız.

Bir A matrisini kendisi ile çarpmak istediğimizi düşünelim (yani karesini almak istediğimizi). Bu durumda ya A*A yazarız, ya da A**2. Örnek üzerinden gidersek:

$$ A=\begin{bmatrix}1 & 2 \\ 3& 4\end{bmatrix}$$

şeklinde $(2\times 2)$lik bir matris olsun. Bu durumda:
$$A^2 = A\cdot A = \begin{bmatrix}1 & 2 \\ 3& 4\end{bmatrix}\cdot \begin{bmatrix}1 & 2 \\ 3& 4\end{bmatrix}$$ olarak yazılır, bu da, bir önceki bölümde gördüğümüz üzere:

In [70]:
A = [1 2; 3 4];
A*A
A**2
ans =

    7   10
   15   22

ans =

    7   10
   15   22

olarak bulunur. Bazı durumlarda biz eleman bazlı çarpım yapmak istiyoruz (yani 1'leri birbirleriyle, 2'leri birbirleriyle, kısaca her elemanın karesini almak istiyoruz). Bu derdimizi, işlem operatöründen önce "." koyarak Octave'a iletiriz:

In [71]:
A.*A
ans =

    1    4
    9   16

In [72]:
A.**2
ans =

    1    4
    9   16

... gibi. 8)

Matrisin Tersi

Matrislerde bölme işlemi bulunmadığından, sadeleştirme işlemleri "bölerek" yapılamaz. Onun yerine, bir matrisle çarpıldığında, sonucun çarpmaya göre etkisiz eleman olan birim matris olduğu özel matrisleri kullanırız. Bu matrislere ilgili matrisin ters matrisi denir. Normalde hesaplaması biraz (epey) karışık olabilir ama neyse ki Octave'da bunun için inv komutu vardır.

$$A^{-1}\cdot A = A\cdot A^{-1} = \mathbb{1}$$
In [73]:
A
A =

   1   2
   3   4

In [75]:
Ai = inv(A)
Ai =

  -2.00000   1.00000
   1.50000  -0.50000

In [76]:
A * Ai
ans =

   1.00000   0.00000
   0.00000   1.00000

In [77]:
Ai * A
ans =

   1.00000   0.00000
   0.00000   1.00000

%%\usepackage{cancel}

Uygulama: Denklem çözümü

Elimizde şöyle bir denklem olsun: $$\begin{gather*}3x+5y = 1\\ x-y=3\end{gather*}$$

(evet, bildiğimiz 2 bilinmeyenli, iki denklem ;)

Normalde bunun 1 bilinmeyenli hali olsaydı, mesela:

$$ 5z = 20$$

gibi bir denklem, yapacağımız iş basitti: iki tarafı da 5'e bölerdik, sol tarafta 5'ler sadeleşir, 1 olur, sağ tarafta da 4 kalırdı, böylelikle çat diye $\boxed{z=4}$ yazardık:
$\require{cancel}$ $$\frac{\cancel{5}z}{\cancel{5}} = \frac{\cancelto{4}{20}}{\cancel{5}}$$

Ama aslında yaptığımız şey bambaşka (ortaokula giden biri görse aynı şey olduğunu iddia edecek olsa da... 8): eşitliğin iki tarafını da, soldan, 5'in çarpmaya göre tersi olan $\frac{1}{5}$ ile çarpıyoruz.

$$\frac{1}{\cancel{5}}.\cancel{5}z = \frac{1}{\cancel{5}}.\cancelto{4}{20}$$

(Elimizde skalerler olduğundan) matematiksel açıdan birbirine tamamıyla eşdeğer iki sadeleştirmenin "yorum" açısından farkını anlamaya çalışın, benim vaktim var, beklerim...


Düşünüp kavradıysanız, devam edelim: bu bölümün başındaki iki bilinmeyenli iki denklemimizi bir daha yazalım:

$$\begin{gather*}3x+5y = 1\\ x-y=3\end{gather*}$$

Bunu matris çarpımı şeklinde yazabiliriz (çarpan matris $(2\times 2)$lik, çarpılan ve sonuç matrisleri $(2\times 1)$lik, yani aslında sütun vektörleri:

$$\begin{pmatrix}3&5\\1 &-1\end{pmatrix}_{(2\times 2)}\cdot\begin{pmatrix}x\\y\end{pmatrix}_{(2\times 1)} = \begin{pmatrix}1\\3\end{pmatrix}_{(2\times 1)}$$

Çarpmayı yapıp, gerçekten de iki denklemi elde ediyor olduğumuzu doğrulamanızı çok tavsiye ederim.

Gördüğümüz şey, tam olarak $$A\cdot x = b$$ şeklinde bir eşitlik: $x$ ve $b$ iki boyutlu sütun vektörler, $A$ da $(2\times 2)$lik bir matris. O halde bu eşitliğin iki tarafını da soldan, $A^{-1}$ ile çarparsak, sol tarafta $\begin{pmatrix}x\\y\end{pmatrix}$ vektörü, sağ tarafta da $A^{-1}\cdot b$ vektörü kalır, yani şöyle bir şey:

$$\begin{gather*}A\cdot x = b\\ \underbrace{A^{-1}\cdot A}_{\mathbb{1}} \cdot x = A^{-1}\cdot b\\ \boxed{x = A^{-1}\cdot b} \end{gather*}$$

Bu kadar laf salatası gözünüzü korkutmasın, Octave'da iki adımlık iş, haydi yapalım!

In [1]:
A = [3 5; 1 -1]
b = [1; 3]
Ai = inv(A)
xy = inv(A)*b
A =

   3   5
   1  -1

b =

   1
   3

Ai =

   0.12500   0.62500
   0.12500  -0.37500

xy =

   2
  -1

Demek ki $x=2$, $y=-1$ imiş, kontrol edelim bakalım:

In [2]:
x=2;y=-1;
3*x+5*y
x-y
ans =  1
ans =  3

... işlem tamamdır! 8)