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:
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
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
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.
hocom c++ da pointer kullanmadan matrisin satir ve sutunlarını nasıl kullanıcıdan alabiliriz yani satır ve sutun klavyedn girilecek….