Yazan : Şadi Evren ŞEKER

Eski dilde saf tutmak anlamındaki saf kelimesinden türemiş  olan ve saf saf dizilmiş anlamına gelen masfuf. İngilizceden matris (matrix) olarak da Türkçeye sonradan girmiş ve masfuf kelimesi unutulmuştur.

Basitçe 2 boyutlu diziler olarak düşünülebilir. Yani satır ve sütün bazında verilerin durduğu bilgi öbekleridir. Bilindiği üzere bilgisayarların hafızasında (Rast gele erişilebilir bellek , RAM) tek boyutlu verileri tutabiliyoruz. Yani bilgisyar hafızaları ardışık veri ünitelerinden oluşuyor ve iki boyuta uygun değiller. Dolayısıyla masfufların hafızada ardışık olarak tutulmaları gerekir. Bu anlamda çözüm için satır bazlı (row major) veya sütun bazlı (column major) hafızada tutma teknikleri mevcuttur.

Masfufların hafızada tutulmaları ve tanımlanmaları

Temel olarak iki boyutlu bir matris programlama dillerinde iki boyutlu bir dizi (array) ile tutulur.

Örneğin JAVA , C , C++ veya C # dillerinin tamamında (hatta C dilinden yazım kuralları (syntax) türemiş diğer pek çok dilde) aşağıdaki tanım doğrudur.

int a[][];

Bu satır ile iki boyutlu bir dizi tanımlanmıştır.

Örneğin iki boyutlu dizimizi C++ dili ile tanımlayıp diziye ilk değerini atamaya çalışalım:

int a[3][3] =  { {1,2,3} , {7,3,4} , {3,4,5}};

Yukarıdaki satırda ilk değer ataması yapılmıştır. Her satır ayrı bir eleman ve her satırdaki elemanlarda ayrı ayrı verilmiştir. Yukarıdaki atamada a dizisinin boyutlarını 3×3 olduğu da belirtilmiştir. Aslında içine değer konduğu için bu belirtmeye gerek yoktur yani

int a[][] =  { {1,2,3} , {7,3,4} , {3,4,5}};

şeklindeki bir atama da C ve C++ derleyicileri için kabul edilir. Bunun sebebi dizinin boyutunun içindeki elemanların sayısından zaten çıkarılabiliyor olmasıdır.

Sonuç olarak yukarıdaki atama işleminden sonra aşağıdaki matrisi hafızada tanıttığımızı kabul edebiliriz:

1 2 3
7 3 4
3 4 5

Yukarıdaki matris gösterimi tamamen bir kabule dayanmaktadır. Yani yukarıdaki gösterim yerine aşağıdaki gösterim de doğrudur:

1 7 3
2 3 4
3 4 5

Yukarıdaki gösterim kolon bazlı (column major) gösterimdir ve bir önceki gösterim olan satır bazlı (row major) gösterimle aynıdır. Burada bilgisayarın arka planda nasıl tuttuğunun bir önemi yoktur ve gösterim kabule dayalıdır. Programcı kişi bu kabullerden birisini yapıp hayatının geri kalanında aynı kabul üzerinden devam edebilir.

Masfuflar üzerinde çıkarma işlemi

iki masfuf üzerinde yapılabilecek en temel işlemler toplama ve çıkarma işlemleridir. Bu durumu iki örnek masfuf üzerinden anlamaya çalışalım:

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

Yukarıdaki çıkarma işleminde sağdaki masfuftan soldaki masfuf çıkarılmış ve netice en sağda gösterilmiştir. Görüldüğü üzere iki masfuf işlenirken aynı satır ve sütundaki değerler birebir çıkarma işlemine tabi tutulmuştur. O halde kodumuz aşağıdaki şekilde olabilir:

int a[][] =  { {1,2,3} , {2,3,4} , {3,4,5}};
int b[][] =  { {1,1,1} , {1,2,2} , {1,2,2}};
int c[3][3]; // buraya kadar a-b = c işlemindeki masfuflari tanımladik
for(int i = 0;i<3;i++){
   for(int j =0 ;j< 3;j++){
      c[i][j]=a[i][j]-b[i][j];
   }
} // buraya kadar c içerisine çıkarma işlemi sonuçlarını koyduk
for(int i = 0;i<3;i++){
   for(int j =0 ;j< 3;j++){
      printf("%d ",c[i][j]);
   }
   printf("n");
} // burada da sonucu ekrana bastiriyoruz

Yukarıdaki kodun çalışan ve DEV-CPP derleyicisinde test edilmiş tam halini indirmek için tıklayınız.

Matrislerde toplama işlemi

Yukarıdaki çıkarma işleminden esinlenerek toplama işlemini kolayca yazabiliriz. Çünkü toplama işlemi ile çıkarma işlemi arasında sadece – işareti yerine + işareti koyacağız. Yine aynı örnek masfuflar üzerinden konuyu anlayacak olursak:

1 2 3    1 1 1     2 3 4
2 3 4  + 1 2 2  =  3 5 6
3 4 5    1 2 2     4 6 7

Yukarıdaki çıkarma işleminde sağdaki masfuftan soldaki masfuf çıkarılmış ve netice en sağda gösterilmiştir. Görüldüğü üzere iki masfuf işlenirken aynı satır ve sütundaki değerler birebir çıkarma işlemine tabi tutulmuştur. O halde kodumuz aşağıdaki şekilde olabilir:

int a[][] =  { {1,2,3} , {2,3,4} , {3,4,5}};
int b[][] =  { {1,1,1} , {1,2,2} , {1,2,2}};
int c[3][3]; // buraya kadar a-b = c işlemindeki masfuflari tanımladik
for(int i = 0;i<3;i++){
   for(int j =0 ;j< 3;j++){
      c[i][j]=a[i][j]+b[i][j];  // sadece burasi degisti
   }
} // buraya kadar c içerisine toplama işlemi sonuçlarını koyduk
for(int i = 0;i<3;i++){
   for(int j =0 ;j< 3;j++){
      printf("%d ",c[i][j]);
   }
   printf("n");
} // burada da sonucu ekrana bastiriyoruz

Yukarıdaki kodun çalışan ve DEV-CPP derleyicisinde test edilmiş tam halini indirmek için tıklayınız.

Masfufun sabit ile çarpımı

Bir matrisin skalar (scalar) ile çarpımı olarak da seslendirilen konu ise masfuftaki bütün elemanların bir değer ile çarpılması şeklindedir. Yine bir örnek üzerinden konuyu inceleyelim:

1 2 3         2 4 6
2 3 4  x 2  = 4 6 8
3 4 5         6 8 10

Yukarıdaki örnekte görüldüğü üzere masfuftaki bütün elemanlar teker teker aynı sabit ile çarpılmıştır. Şimdi bu kodu yazmaya çalışalım:

int a[][] =  { {1,2,3} , {2,3,4} , {3,4,5}};
int b=2; // bu defa sabit ile carpiyoruz
int c[3][3]; // buraya kadar a-b = c işlemindeki masfuflari tanımladik
for(int i = 0;i<3;i++){
   for(int j =0 ;j< 3;j++){
      c[i][j]=a[i][j]*b;  // sadece burasi degisti
   }
} // buraya kadar c içerisine çarpma işlemi sonuçlarını koyduk
for(int i = 0;i<3;i++){
   for(int j =0 ;j< 3;j++){
      printf("%d ",c[i][j]);
   }
   printf("n");
} // burada da sonucu ekrana bastiriyoruz

Yukarıdaki kodun çalışan ve DEV-CPP derleyicisinde test edilmiş tam halini indirmek için tıklayınız.

İki masfufun çarpımı

Öncelikle iki masfufun çarpımını hatırlayalım:

masfuf_carpim

Yukarıdaki şekilde görüldüğü üzere C= AxB şeklindeki bir işlemde C matrisinin içerisinde biriktirme yapılırken A’nın i. satırı ile B’nin j. sütunu çarpılmaktadır. O halde algoritmamızı aşağıdaki şekilde tasarlayabiliriz. Müsvette kod (Pseudo code ) olarak:

for i = 1 to n
       for j = 1 to n
        for k = 1 to n
                   C(i,j) = C(i,j) + A(i,k) * B(k,j)

Yukarıdaki bu algoritmayı C / C++dilinde dökecek olursak:

   int a[3][3] =  { {1,2,3} , {2,3,4} , {3,4,5}};
    int b[3][3] =  { {1,1,1} , {1,2,2} , {1,2,2}};
    int c[3][3]=  { {0,0,0} , {0,0,0} , {0,0,0}};
    //toplama olduğundan ilk değer atamasi gerekir
    for(int i = 0;i<3;i++){
       for(int j =0 ;j< 3;j++){
          for(int k = 0;k<3;k++){       
             c[i][j]=c[i][j] + a[i][k]*b[k][j];
          }
       }
    } // buraya kadar c içerisine çarpma işlemi sonuçlarını koyduk
    for(int i = 0;i<3;i++){
       for(int j =0 ;j< 3;j++){
          printf("%d ",c[i][j]);
       }
       printf("n");
    } // burada da sonucu ekrana bastiriyoruz

Yukarıdaki kodda çarpma işlemi yapılmıştır ve kodun DEV-CPP derleyicisi ile test edilmiş çalışan tam halini almak için tıklayınız.

Yorumlar

  1. wide

    bir arkadasın sizden yardım istemesi ve onun üzerine bu konuyu açıklamanız…Takdire şayan.Her zaman bilgilerinizi bizle paylaşmanız dileğiyle..Kolay gelsin

  2. bora ersoy

    ben bir meslek lisesi öğrencisiyim, matrislerin bilgisayarda nerelerde kullanım alanı bulunduğuyla ilgili ödevim vardı. Bu konu çok yardımcı oldu. Böyle bir paylaşımda bulunduğunuz için teşekkürler.

  3. hatem

    hocom c++ da pointer kullanmadan matrisin satir ve sutunlarını nasıl kullanıcıdan alabiliriz yani satır ve sutun klavyedn girilecek….

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir