Makale Özeti

Bu makalemde bir veri tipi olarak Matris(Matrix)'i nasıl kullanabileceğimizi açıklamaya çalışacağım. Daha açıkçası kendi veri tipimizi nasıl yazabileceğimizi ve bu veri tipi arasında toplama çarpım eşitlik vb. gibi operator işlemlerini nasıl yapacağımızı inceleyeceğiz. Makalenin ilerleyen kısımlarında kodlarla beraber matematiğin temel taşlarından olan Matris'lerin özelliklerini de inceleyip bu özelliklere uygun metod ve propertyleride yazacağız.

Makale

         Merhabalar,

         Bu makalemde bir veri tipi olarak Matris(Matrix)'i nasıl kullanabileceğimizi açıklamaya çalışacağım. Daha açıkçası kendi veri tipimizi nasıl yazabileceğimizi ve bu veri tipi arasında toplama çarpım eşitlik vb. gibi operator işlemlerini nasıl yapacağımızı inceleyeceğiz. Makalenin ilerleyen kısımlarında kodlarla beraber matematiğin temel taşlarından olan Matris'lerin özelliklerini de inceleyip bu özelliklere uygun metod ve propertyleride yazacağız. İnceleyeceğimiz matrisler 2 boyutlu matrisler olup aynı yolu izlemek suretiyle şekilde kendi veri tipinizi yazmayı başarıyor olacaksınız.

         Şimdi ise matrisin ne olduğunu kısaca inceleyelim; Satrılar ve sütunlar biçiminde dizilerek köşeli parantezler içine alınmış sayı ve sembol takımlarıdır, Mühendislik, fizik, ekonomi ve istatistikte, ayrıca matematiğin çeşitli dallarında yaygın olarak kullanılmaktadır.Denklem çözümleri gibi konularda kullanılmaktadır. Şimdi ise bir matris örneği inceleyelim.

          Biraz öncede bahsettiğimiz ve şekilde görüldüğü gibi matris bazı satır ve sütünlara düzgün olarak yerleştirilmiş sayılar gurubudur. Yatay elemanların bulunduğu çizgilere Satır(Row), dikey elemanların bulunduğu çizgilere ise Column(Sütun) adı verilir. Başka bir deyişle 1. matrisimizde 2. satır elemanları {3,4} iken 1. Sütun elemanları {2,3,4} dür. Matrislerin boyutlandırılmasında ise satır ve sütun sayıları önem taşırlar. Birinci matrisimizin boyutu 3x2 iken 2. matrisimizin boyutu 2x3 dür. Matrislerin elemanları ise bulundukları satır ve sütuna göre sınıflandırılırlar. ilk matrisimize A diyecek olursak A(3,2)=5 olacaktır. Bunun dışında kare matris gibi kavramlara metodlarımızı yazarken değineceğiz.
          Şimdi ise artık veri tipimizi yazmaya başlayabiliriz. Öncelikle bu veri tipini yazmaya başlamadan önce kullanacağımız temel yöntem olan operator overloading hakkında daha önce yazmış olduğum makaleyi buradan okuyabilirsiniz. Şimdi ise artık class'ımızı yazmaya başlayalım.

using System;
using System.Collections.Generic;
using System.Text;
namespace MatrixProject
{
      public class Matrix
      {
            private decimal[,] mInnerMatrix;

          Classımızı tanımladıktan hemen sonra 2 boyutlu verileri taşıyabilecek bir array tanımlıyoruz. Bu arrayde matrisimizin değerlerini tutacağız.

            private int mRowCount = 0;
            public int RowCount
            {
                  get { return mRowCount; }
            }
            private int mColumnCount = 0;
            public int ColumnCount
            {
                  get { return mColumnCount; }
            }

         Daha sonrasında ise yazdığımız member değişkenler ve bunları encapsule eden property'ler ise matrisimizin kaç satır ve sütundan oluşacağını belirlememize yazıyor. Değişken tipimizin Constructor(yapıcı metod)unda bulunan overloadlardan dolayı bu propertylerin get metodlarını kullanacağız. Bu propertyleri pek kullanmayacağızdan dolayı bu propertyleri readonly yazıyoruz.

            public Matrix()
            {
           
            }
            public Matrix(int rowCount, int columnCount)
            {
                  mRowCount = rowCount;
                  mColumnCount = columnCount;
                  mInnerMatrix = new decimal[rowCount, columnCount];
            }

          Constructor'larımızı tanımladığımızda ise sizlerinde görebileceği gibi kullanacağımız esas ctor 2. dir. Bu metod bizden satır ve sütun sayısını parametre olarak aldıktan sonra bunların tutulacağı member değişkenlere değerlerini atamakta ve class'ımızın en başında tanımladığımız ve matrisimizin verilerini tutacağını söylediğimiz mInnerMatrix ismindeki dizi değişkenin boyutlarını belirleyerek referansını oluşturuyor.

            public decimal this[int rowNumber,int columnNumber]
            {
                  get
                  {
                        return mInnerMatrix[rowNumber, columnNumber];
                  }
                  set
                  {
                        mInnerMatrix[rowNumber, columnNumber] = value;
                  }
            }

          Bu property ise matrisimizde bulunan istediğimiz bir elemanın satır ve sütun sayısını belirleyerek o elemanın değerini okuyabilmemize veya elemana değer atamıza olanak verecek olan metoddur. Tek yapmamız gereken member olarak tanımladığımız 2 boyutlu array'de bulunan elemanı kullanıcıya geri döndürmek veya kullanıcıdan gelen değeri bu elemana tamak olacaktır.

            public decimal[] GetRow(int rowIndex)
            {
                  decimal[] rowValues = new decimal[mColumnCount];
                  for (int i = 0; i < mColumnCount; i++)
                  {
                        rowValues[i] = mInnerMatrix[rowIndex, i];
                  }
                  return rowValues;
            }
            public void SetRow(int rowIndex,decimal[] value)
            {
                  if (value.Length != mColumnCount)
                  {
                        throw new Exception("Boyut Uyusmazligi");
                  }
                  for (int i = 0; i < value.Length; i++)
                  {
                        mInnerMatrix[rowIndex, i] = value[i];
                  }
            }

          Bir matrisde bir satırda bulunan tüm sayıları almak istersek bu bizim için tek boyutlu bir diziye denk olacaktır. GetRow metodunda kullanıcıdan aldığımız sıra numarasını temsil eden parametrik değişken sayesinde tanımladığımız iki boyutlu değişkenin belirtilen sırasında bulunan tüm elemanlar içinde bir döngüyle dolaşarak bunları tek boyutlu bir diziye atayarak kullanıcıya geri döndürüyoruz. SetRow metodunda ise kullanıcıdan sıra numarasını ve bu sırada bulunmasını istediği elemanları bir dizi olarak alıyoruz. Ancak burada önemli bir nokta kullanıcıdan aldığımız dizinin boyutunun bizim matrisimizin sütun sayısına eşit olmasıdırö aksi durumda belirtilen sırada bazı elemanlar boşta kalacak veya değer atanmayacaktır. Sonrasında ise gelen dizinin elemanları içinde dönerek bunları belirtilen sıranın elemanlarına tek tek atıyoruz.

            public decimal[] GetColumn(int columnIndex)
            {
                  decimal[] columnValues = new decimal[mRowCount];
                  for (int i = 0; i < mRowCount; i++)
                  {
                        columnValues[i] = mInnerMatrix[i, columnIndex];
                  }
                  return columnValues;
            }
            public void SetColumn(int columnIndex,decimal[] value)
            {
                  if (value.Length != mRowCount)
                  {
                        throw new Exception("Boyut Uyusmazligi");
                  }
                  for (int i = 0; i < value.Length; i++)
                  {
                        mInnerMatrix[i, columnIndex] = value[i];
                  }
            }

          GetColumn ve SetColumn metodları ise GetRow ve SetRow metodlarının aynılarıdır ancak tek fark bizden sütun numarasını alarak satır bazında değilde sütun bazında işlem yapmasıdır.

            public static Matrix operator +(Matrix pMatrix1,Matrix pMatrix2)
            {
                  if (!(pMatrix1.RowCount == pMatrix2.RowCount && pMatrix1.ColumnCount == pMatrix2.ColumnCount))
                  {
                        throw new Exception("Boyut Uyusmazligi");
                  }
                  Matrix returnMartix = new Matrix(pMatrix1.RowCount, pMatrix2.RowCount);
                  for (int i = 0; i < pMatrix1.RowCount; i++)
                  {
                        for (int j = 0; j < pMatrix1.ColumnCount; j++)
                        {
                             returnMartix[i, j] = pMatrix1[i, j] + pMatrix2[i, j]
                        }
                  }
                  return returnMartix;
            }

          İki matrisin toplanması demek iki matriste aynı sıra ve sütunda bulunan elemanların birbirleriyle tek tek toplanması ve sonuç matrisinde aynı sıre ve sütun numarasına karşılık gelecek şekilde yazılmalarıdır. Bu işlemde sizlerinde anlayacağı gibi toplanacak iki matrisin boyutlar(sıra ve sütun sayıları) aynı olmalıdır. Bu metodda yaptığımız işlem ise verilen matrislerden birinin boyutunda(zaten her ikisininde boyutları aynı olmalıdır) bir dönüş matrisi tanımlıyoruz. ve verilen iki matiste aynı koordinatta bulunan elemanları toplayıp dönüş matrisinin aynı koordinatına yazıyor ve bunu kullanıcıya geri döndürüyoruz.

            public static Matrix operator *(decimal scalarValue, Matrix pMatrix)
            {
                  Matrix returnMartix = new Matrix(pMatrix.RowCount, pMatrix.RowCount);
                  for (int i = 0; i < pMatrix.RowCount; i++)
                  {
                        for (int j = 0; j < pMatrix.ColumnCount; j++)
                        {
                             returnMartix[i, j] = pMatrix[i, j] * scalarValue;
                        }
                  }
                  return returnMartix;
            }

          Bir matrisin skalar bir sayıyla çarpılması demek her elemanın tek tek bu çarpan ile çarpılması demektir. Bu metodda yaptığımız ise her elemanı bu değişkenle çarpıp dönüş matrisine atamak ve dönüş matrisini geri döndürmektir.

            public static Matrix operator -(Matrix pMatrix1, Matrix pMatrix2)
            {
                  return pMatrix1 + (-1 * pMatrix2);
            }

          Bir matrisi diğerinden çıkarmak demek o matrisi -1 ile çarpıp ilk matrisle toplamak demektir. Şimdiye kadar yazdığımız metodlar arasında çarpma ve toplama metodları vardı. bundan dolayı bu metodu bu ikisinin birleşimi olarak kullanabiliriz.

            public static bool operator ==(Matrix pMatrix1, Matrix pMatrix2)
            {
                  if (!(pMatrix1.RowCount == pMatrix2.RowCount && pMatrix1.ColumnCount == pMatrix2.ColumnCount))
                  {
                        //boyut uyusmazligi
                        return false;
                  }
                  for (int i = 0; i < pMatrix1.RowCount; i++)
                  {
                        for (int j = 0; j < pMatrix1.ColumnCount; j++)
                        {
                             if (pMatrix1[i, j] != pMatrix2[i, j])
                             {
                                   return false;
                             }
                        }
                  }
                  return true; ;
            }

          İki matrisin eşitliğinden bahsedebilmemiz için tek tek bütün elemanlarının karşı matriste aynı koordinatta bulunan elemanlara eşit olması gerekmektedir. Bu metodda ise iç içe for dongulerinde bunu kontrol edip eşit olmayan ilk elemana rastladığımızda kullanıcya false değerini döndürüyoruz.

            public static bool operator !=(Matrix pMatrix1, Matrix pMatrix2)
            {
                  return !(pMatrix1 == pMatrix2);
            }

          İki matrisin eşit olmaması durumu ise eşit olma durumunun zıttıdır. Zaten eşitlik kontrol metodunu yazdığımız için bu metoddan dönen değerin tersini kullanıcıya döndürüyoruz.

            public static Matrix operator -(Matrix pMatrix)
            {
                  return -1 * pMatrix;
            }

          Bir matrisi negatifize etmek demek bütün elemanlarını tek tek -1 skalar değişkeni ile çarpmak demektir. Bunu kullanabileceğimiz metodları önceden yazdığımız için sorun olmayacaktır.

            public static Matrix operator ++(Matrix pMatrix)
            {
                  for (int i = 0; i < pMatrix.RowCount; i++)
                  {
                        for (int j = 0; j < pMatrix.ColumnCount; j++)
                        {
                             pMatrix[i, j] += 1;
                        }
                  }
                  return pMatrix ;
            }

          Bır arttırım yapan bu metodda ise matrisin tüm elemanlarının değerlerini bir arttırıyoruz. Bu metodun mantığı tamamen bize kalmış, matematik tarafında böyle bir kural tanımlı değildir.

            public static Matrix operator --(Matrix pMatrix)
            {
                  for (int i = 0; i < pMatrix.RowCount; i++)
                  {
                        for (int j = 0; j < pMatrix.ColumnCount; j++)
                        {
                             pMatrix[i, j] -= 1;
                        }
                  }
                  return pMatrix;
            }

Bu makalenin ilk kısmında belirlediğimiz bir değişkeni nasıl yazabileceğimizin temel metodlarını inceledik. İkici kısımda ise daha gelişmiş metodları yazmaya aynı örnek üzerinden devam edeceğiz.

oztamer@hotmail.com
tamer.oz@yazgelistir.com
oztamer@hotmail.com
Ornek Uygulama