Newton-Raphson Metodu ile Fonksiyon Kök Bulma

Newton-Raphson metodu, sayısal analizde, eşitlik köklerinin bulunmasında en yaygın kullanılan metotlardan birisidir. Başlangıç için tahmini bir kök değeri seçilerek, yapılan iterasyon sonucu gerçek kök değerine oldukça yakın bir değere ulaşılır.

Newton-Raphson

Newton-Raphson metodunun C# dilinde yazılmış kaynak kodu yer almaktadır.

public class NewtonRaphson
{
    public uint MaxIteration { get; set; } = 50;
    public double Epsilon { get; set; } = 0.000001;

    public double Solve(Func<double, double> f, Func<double, double> df, double initialGuess)
    {
        var xn = initialGuess;

        for (var i = 0; i < this.MaxIteration; i++)
        {
            var xn1 = xn - f.Invoke(xn) / df.Invoke(xn);

            if (Math.Abs(xn - xn1) < this.Epsilon)
            {
                return xn1;
            }

            xn = xn1;
        }

        return xn;
    }
}

Örneğin f(x) = x^2 - 2 fonksiyonun köklerini bulmak için, metodu aşağıdaki şekilde çağırabiliriz. Tahmini kök değeri olarak 1 seçilmiştir.

var solver = new NewtonRaphson();
var root = solver.Solve(x => x * x - 2, x => 2 * x, 1);

Benzer şekilde, f(x) = x - Cos(x) fonksiyonun köklerini bulmak için ise, metodu aşağıdaki şekilde çağırabiliriz. f(x) = 1 + Sin(x) fonksiyonun türevidir.

var solver = new NewtonRaphson();
var root = solver.Solve(x => x - Math.Cos(x), x => 1 + Math.Sin(x), 2);
Etiketler:  C#

C# 6.0 Exception Filter

tip

try catch kullanımı sırasında, catch bloğunun çalışması için koşul yazılabilir.

Örnek

try
{
    // Code
}
catch (ArgumentException ex) when (ex.ParamName == "p1")
{
    // ex.ParamName == "p1" koşulu sağlanması durumunda catch bloğu çalışır.
}
Etiketler:  C#

LINQ Cheat Sheet

LINQ kod içerisinde SQL tarzı sorgular yapabilmemize olanak sağlayan bir teknolojidir.

lambda

Urun nesnelerinin ve tamsayı değerlerinin yer aldığı iki farklı dizi üzerinde sorgulama işlemleri gerçekleştirilecektir.

        public class Urun
        {
            public int Numara { get; set; }
            public string Ad { get; set; }
            public string Kategori { get; set; }
            public double Deger { get; set; }
        }

        var dizi = new[] { 2, 3, 7, 4, 5, 4, 9, 1, 3 };
        var urunler = new[]
        {
            new Urun { Numara = 1, Ad = "Kalem", Kategori = "Kırtasiye", Deger = 3 },
            new Urun { Numara = 2, Ad = "Elma", Kategori = "Manav", Deger = 4.2 }
        };

Süzme (Filter)

        // Değeri 3 olan dizi elemanları alınıyor
        var sonuc = (from c in dizi
                        where c == 3
                        select c);

        // 2 farklı kritere göre süzme
        var sonuc = (from c in urunler
                        where c.Kategori == "Manav" && c.Deger > 1
                        select c);

        // Lambda Syntax
        var sonuc = urunler.Where(c => c.Ad == "Elma");

Yansıtma (Projection)

        // Ürünlerin sadece belirli özellikleri listeleniyor.
        // Anonim tip geri döndürülüyor.
        var sonuc = (from c in urunler
                        select new
                        {
                            c.Numara,
                            c.Ad
                        });

        // Lambda Syntax
        var sonuc = urunler.Select(c => new
        {
            c.Numara,
            c.Ad
        });

Sıralama (Order)

        // Dizi tersten sıralanıyor.
        var sonuc = (from c in dizi
                        orderby c descending
                        select c);

        // Birden fazla alana göre sıralanıyor.
        // İlk olarak değere, daha sonra kategoriye göre sıralanır. (sondan başa doğru)
        var sonuc = (from c in urunler
                        orderby c.Kategori, c.Deger descending
                        select c);

        // Lambda Syntax
        var sonuc = urunler.OrderByDescending(c => c.Deger).ThenBy(c => c.Kategori);

Birleştirme (Join)

        // İki liste birleştirilerek, listelerin sadece belirli özellikleri alınıyor.
        var sonuc = (from c in dizi
                        join urun in urunler on c equals urun.Numara
                        select new
                        {
                            c,
                            urun.Ad
                        });

        // Left join
        var sonuc = (from c in dizi
                        join u1 in urunler on c equals u1.Numara into u2
                        from urun in u2.DefaultIfEmpty()
                        select new
                        {
                            c,
                            urun.Ad
                        });

Gruplama (Group)

        // Ürünler kategorilerine göre gruplanıyor.
        // Her bir kategori grubunda kaç adet ürün bulunduğu ve kategorinin toplam değeri listeleniyor.
        var sonuc = (from c in urunler
                        group c by c.Kategori into g
                        select new
                        {
                            Kategori = g.Key,
                            Adet = g.Count(),
                            ToplamDeger = g.Sum(k => k.Deger)
                        });

        // Birden fazla alana göre gruplama
        var sonuc = (from c in urunler
                        group c by new { c.Ad, c.Kategori } into g
                        select new
                        {
                            g.Key.Kategori,
                            Adet = g.Count(),
                            ToplamDeger = g.Sum(k => k.Deger)
                        });
Etiketler:  C#

C# Nesne Özelliklerine Varsayılan Değer Atama

tip

Bir nesne üzerindeki özelliklerin varsayılan değerlerini atama işlemi yapıcı içerisinde yapılmaktadır. C# 6.0 ile beraber bu işlem, artık özelliğin tanımlandığı yerde yapılabilmektedir.

Eski kullanım

    public class Ogrenci
    {
        public int Numara { get; }
        public string AdSoyad { get; set; }

        public Ogrenci()
        {
            this.Numara = 3;
            this.AdSoyad = "Selami Güngör";
        }
    }

Yeni kullanım

    public class Ogrenci
    {
        public int Numara { get; } = 3;
        public string AdSoyad { get; set; } = "Selami Güngör";
    }
Etiketler:  C#

C# 6.0 Null Kontrolü

tip

Bir nesnenin özelliklerine ya da metotlarına erişmeden önce, nesne değerinin null olup olmadığının kontrol edilmesi gerekmektedir. Aksi halde NullReferenceException hatası fırlatılır.

Örneğin, str adı tanımlanmış bir string nesnesinin uzunluğu alınmak isteniyor. Uzunluk alınmadan önce ilk olarak str değerinin null olup olmadığının kontrol edilmesi gerekiyor. C# 6.0 ile beraber, bu kontrol aşağıdaki gibi ?. operatörü ile yapılabilir.

var length = str?.Length;

İşlem sonunda, eğer str değeri null ise, null değeri döndürülür. Aksi halde string uzunluğu elde edilir.

Etiketler:  C#

Generic Singleton Pattern & C#

Generic Singleton pattern with C# and .NET 4 (or higher)

// T is a class and must have a public default constructor.

public sealed class Singleton<T> where T : class, new()
{
    private static readonly Lazy<T> instance = new Lazy<T>(() => new T());
        
    public static T Instance
    {
        get
        {
            return instance.Value;
        }
    }

    private Singleton() { }
}

Usage:

var myClass = Singleton<MyClass>.Instance;
Etiketler:  C#

Julia Fraktal Çizimi & C#

Fraktal; matematikte, çoğunlukla kendine benzeme özelliği gösteren karmaşık geometrik şekillerin ortak adıdır. En bilinen fraktal kümelerinden birisi olan Julia kümesinin C# ile oluşturulmuş hali aşağıdadır.

julia

using System.Drawing;
using System.Numerics;

namespace SG.Algoritma
{
    public class JuliaFractal
    {
        // Julia kümesinde, yarıçağı 2'den büyük her karmaşık sayı çemberi sonsuza götürmektedir.
        private const int MaxMagnitude = 2;

        // Maksimum iterasyon sayısı
        private const int MaxIterations = 1000;

        // Karmaşık sayı koordinat sisteminde, Julia kümesinin bölgesi.
        // Julia kümesinin sadece bir kısmını çizmek için farklı bir bölge verilebilir. 
        private static Complex AreaMin = new Complex(-2, -2);
        private static Complex AreaMax = new Complex(2, 2);

        private Complex C;

        public JuliaFractal(Complex c)
        {
            this.C = c;
        }

        /// <summary>
        /// Julia kümesi imajı oluşturuluyor
        /// </summary>
        /// <param name="dimension">Oluşacak imajın genişlik ve yükseklik değeri (Kare imaj oluşturulacak)</param>
        public Bitmap GenerateBitmap(int dimension)
        {
            return this.GenerateBitmap(dimension, JuliaFractal.AreaMin, JuliaFractal.AreaMax);
        }

        /// <summary>
        /// Julia kümesi imajı oluşturuluyor
        /// </summary>
        /// <param name="width">Oluşacak imajın genişliği. Yükseklik, çizilmek istenen bölgeyenin genişlik ve yükseklik değerlerine bakılarak belirlenecek.</param>
        /// <param name="areaMin">Karmaşık sayo kooordinat sisteminde, Julia kümesinin sadece belirli bir bölgeye karşılık düşen kısmı çizdirilmek istendiği zaman, bu bölgenin sol alt kösesi</param>
        /// <param name="areaMax">Sağ üst köşe</param>
        public Bitmap GenerateBitmap(int width, Complex areaMin, Complex areaMax)
        {
            var height = (int)(width * (areaMax - areaMin).Imaginary / (areaMax - areaMin).Real);

            // Boş bir bitmap oluştur
            var bitmap = new Bitmap(width, height);

            // Oluşturulacak imajın her piksel değerine karşılık düşen karmaşık sayı oluşturulacak.
            // Oluşturacağımız karmaşık sayıların, seçtiğimiz bölge içerisinde kalması gerekmektedir.

            var rScale = (areaMax - areaMin).Real / width;
            var iScale = (areaMax - areaMin).Imaginary / height;

            for (var x = 0; x < width; x++)
            {
                // Karmaşık sayısının real kısmı
                var real = areaMin.Real + x * rScale;

                for (var y = 0; y < height; y++)
                {
                    // Karmaşık sayısının imaginary kısmı
                    var imaginary = areaMin.Imaginary + y * iScale;

                    // Julia kümesi iterasyon değeri hesaplanıyor.
                    var iteration = this.CalculateIteration(new Complex(real, imaginary));

                    // Iterasyon değerine göre noktanın rengi ayarlanıyor.
                    bitmap.SetPixel(x, y, JuliaFractal.GetColor(iteration));
                }
            }

            return bitmap;
        }

        private int CalculateIteration(Complex z)
        {
            var iteration = 0;

            while (iteration < JuliaFractal.MaxIterations && z.Magnitude < JuliaFractal.MaxMagnitude)
            {
                z = z * z + this.C;
                iteration++;
            }

            return iteration;
        }

        /// <summary>
        /// // Iterasyona karşılık renk seçiliyor.
        /// </summary>
        private static Color GetColor(int iteration)
        {
            // Rasgele bir renk seçiliyor.
            // 256 tane rengin olduğu bir liste oluşturularak, listeden iteration % 256. renk de seçilebilir.
            // Ya da renk oluşturmak için farklı bir yöntem izlenebilir.

            return Color.FromArgb(0, iteration % 256, 0);
        }
    }
}

Julia kümesini fraktal resmini oluşturmak için, ilgili metot aşağıdaki şekilde çağrılabilir. Bu durumda en üstte yer alan resim oluşacaktır.

var fractal = new JuliaFractal(new Complex(0.285, 0.01));
var bitmap = fractal.GenerateBitmap(800);

bitmap.Save(@"D:\julia.png", ImageFormat.Png);

Julia fraktalının sadece belirli bir bölgesini çizdirmek için, ilgili metot aşağıdaki şekilde çağrılabilir. Böylece fraktalın istenilen bölgesi daha detaylı bir şekilde çizdirilebilir.

var bitmap = fractal.GenerateBitmap(800, new Complex(-0.85, 0.1), new Complex(-0.45, 0.37));

julia

Etiketler:  C#

Mandelbrot Fraktal Çizimi & C#

Fraktal; matematikte, çoğunlukla kendine benzeme özelliği gösteren karmaşık geometrik şekillerin ortak adıdır. En bilinen fraktal kümelerinden birisi olan Mandelbrot kümesinin C# ile oluşturulmuş hali aşağıdadır.

mandelbrot

using System;
using System.Drawing;
using System.Numerics;

namespace SG.Algoritma
{
    public class Fractal
    {
        // Mandelbort kümesinde, yarıçağı 2'den büyük her karmaşık sayı çemberi sonsuza götürmektedir.
        private const int MaxMagnitude = 2;

        // Maksimum iterasyon sayısı
        private const int MaxIterations = 1000;

        // Karmaşık sayı koordinat sisteminde, Mandelbort kümesinin bölgesi.
        // Mandelbort kümesinin sadece bir kısmını çizmek için farklı bir bölge verilebilir. 
        private static Complex AreaMin = new Complex(-2, -2);
        private static Complex AreaMax = new Complex(2, 2);

        /// <summary>
        /// Mandelbort kümesi imajı oluşturuluyor
        /// </summary>
        /// <param name="dimension">Oluşacak imajın genişlik ve yükseklik değeri (Kare imaj oluşturulacak)</param>
        public static Bitmap GenerateBitmap(int dimension)
        {
            return Fractal.GenerateBitmap(dimension, Fractal.AreaMin, Fractal.AreaMax);
        }

        /// <summary>
        /// Mandelbort kümesi imajı oluşturuluyor
        /// </summary>
        /// <param name="width">Oluşacak imajın genişliği. Yükseklik, çizilmek istenen bölgeyenin genişlik ve yükseklik değerlerine bakılarak belirlenecek.</param>
        /// <param name="areaMin">Karmaşık sayo kooordinat sisteminde, Mandelbort kümesinin sadece belirli bir bölgeye karşılık düşen kısmı çizdirilmek istendiği zaman, bu bölgenin sol alt kösesi</param>
        /// <param name="areaMax">Sağ üst köşe</param>
        public static Bitmap GenerateBitmap(int width, Complex areaMin, Complex areaMax)
        {
            var height = (int)(width * (areaMax - areaMin).Imaginary / (areaMax - areaMin).Real);

            // Boş bir bitmap oluştur
            var bitmap = new Bitmap(width, height);

            // Oluşturulacak imajın her piksel değerine karşılık düşen karmaşık sayı oluşturulacak.
            // Oluşturacağımız karmaşık sayıların, seçtiğimiz bölge içerisinde kalması gerekmektedir.
            
            var rScale = (areaMax - areaMin).Real / width;
            var iScale = (areaMax - areaMin).Imaginary / height;

            for (var x = 0; x < width; x++)
            {
                // Karmaşık sayısının real kısmı
                var real = areaMin.Real + x * rScale;

                for (var y = 0; y < height; y++)
                {
                    // Karmaşık sayısının imaginary kısmı
                    var imaginary = areaMin.Imaginary + y * iScale;

                    // Mandelbort kümesi iterasyon değeri hesaplanıyor.
                    var iteration = Fractal.CalculateIteration(new Complex(real, imaginary));

                    // Iterasyon değerine göre noktanın rengi ayarlanıyor.
                    bitmap.SetPixel(x, y, Fractal.GetColor(iteration));
                }
            }

            return bitmap;
        }

        private static int CalculateIteration(Complex c)
        {
            var z = new Complex();
            var iteration = 0;

            // MaxIterations adedince f(z) = z^2 + c işlemini uygula
            // İşlem sonucu Mandelbort kümesi içerisinde kalmaya devam ettiği sürece işlemi tekrarla
            while (iteration < Fractal.MaxIterations && z.Magnitude < Fractal.MaxMagnitude)
            {
                z = z * z + c;
                iteration++;
            }

            return iteration;
        }

        /// <summary>
        /// // Iterasyona karşılık renk seçiliyor.
        /// </summary>
        private static Color GetColor(int iteration)
        {
            // Rasgele bir renk seçiliyor.
            // 256 tane rengin olduğu bir liste oluşturularak, listeden iteration % 256. renk de seçilebilir.
            // Ya da, oluşan imajın tek renkten oluşmasını istiyorsak, Color.FromArgb(iteration % 256, 0, 0) rengi seçilebilir. Bu durumda kırmızı toplanda imaj oluşacaktır.

            return Color.FromArgb((iteration * iteration * iteration) % 256, (iteration * iteration) % 256, (iteration) % 256);
        }
    }
}

Mandelbrot kümesini fraktal resmini oluşturmak için, ilgili metot aşağıdaki şekilde çağrılabilir. Bu durumda en üstte yer alan resim oluşacaktır.

var bitmap = Fractal.GenerateBitmap(800);

bitmap.Save(@"D:\mandelbort.png", ImageFormat.Png);

Mandelbrot fraktalının sadece belirli bir bölgesini çizdirmek için, ilgili metot aşağıdaki şekilde çağrılabilir. Böylece fraktalın istenilen bölgesi daha detaylı bir şekilde çizdirilebilir.

var bitmap = Fractal.GenerateBitmap(800, new Complex(-0.4, -1.3), new Complex(0.1, -0.5));

mandelbrot

Etiketler:  C#

Encrypt & Decrypt a String in C#

Encrypt and decrypt data using a symmetric key in C#.

Usage

var str = "String to be encrypted";
var password = "p@SSword";
var strEncryptred = Cipher.Encrypt(str, password);
var strDecrypted = Cipher.Decrypt(strEncryptred, password);

Encryption

Cipher class

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace SG.Algoritma
{
    public static class Cipher
    {
        /// <summary>
        /// Encrypt a string.
        /// </summary>
        /// <param name="plainText">String to be encrypted</param>
        /// <param name="password">Password</param>
        public static string Encrypt(string plainText, string password)
        {
            if (plainText == null)
            {
                return null;
            }

            if (password == null)
            {
                password = String.Empty;
            }

            // Get the bytes of the string
            var bytesToBeEncrypted = Encoding.UTF8.GetBytes(plainText);
            var passwordBytes = Encoding.UTF8.GetBytes(password);

            // Hash the password with SHA256
            passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

            var bytesEncrypted = Cipher.Encrypt(bytesToBeEncrypted, passwordBytes);

            return Convert.ToBase64String(bytesEncrypted);
        }

        /// <summary>
        /// Decrypt a string.
        /// </summary>
        /// <param name="encryptedText">String to be decrypted</param>
        /// <param name="password">Password used during encryption</param>
        /// <exception cref="FormatException"></exception>
        public static string Decrypt(string encryptedText, string password)
        {
            if (encryptedText == null)
            {
                return null;
            }

            if (password == null)
            {
                password = String.Empty;
            }

            // Get the bytes of the string
            var bytesToBeDecrypted = Convert.FromBase64String(encryptedText);
            var passwordBytes = Encoding.UTF8.GetBytes(password);

            passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

            var bytesDecrypted = Cipher.Decrypt(bytesToBeDecrypted, passwordBytes);

            return Encoding.UTF8.GetString(bytesDecrypted);
        }

        private static byte[] Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
        {
            byte[] encryptedBytes = null;

            // Set your salt here, change it to meet your flavor:
            // The salt bytes must be at least 8 bytes.
            var saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            using (MemoryStream ms = new MemoryStream())
            {
                using (RijndaelManaged AES = new RijndaelManaged())
                {
                    var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);

                    AES.KeySize = 256;
                    AES.BlockSize = 128;
                    AES.Key = key.GetBytes(AES.KeySize / 8);
                    AES.IV = key.GetBytes(AES.BlockSize / 8);

                    AES.Mode = CipherMode.CBC;

                    using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                        cs.Close();
                    }

                    encryptedBytes = ms.ToArray();
                }
            }

            return encryptedBytes;
        }

        private static byte[] Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
        {
            byte[] decryptedBytes = null;

            // Set your salt here, change it to meet your flavor:
            // The salt bytes must be at least 8 bytes.
            var saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            using (MemoryStream ms = new MemoryStream())
            {
                using (RijndaelManaged AES = new RijndaelManaged())
                {
                    var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);

                    AES.KeySize = 256;
                    AES.BlockSize = 128;
                    AES.Key = key.GetBytes(AES.KeySize / 8);
                    AES.IV = key.GetBytes(AES.BlockSize / 8);
                    AES.Mode = CipherMode.CBC;

                    using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                        cs.Close();
                    }

                    decryptedBytes = ms.ToArray();
                }
            }

            return decryptedBytes;
        }
    }
}
Etiketler:  C#

Monte Carlo İntegrali Alan Hesabı

Bir eğrinin altında yer alan alanı istatiksel bir yöntemle hesaplamak için Monte Carlo integral algoritması kullanılabilir. Bu algoritma ile, rasgele üretilen N adet noktanın kaç tanesinin fonksiyon eğrisinin altında yer aldığına bakılır. Rasgele seçilen noktaların yüzde kaçının eğri altında yer aldığına bakılarak, yaklaşık olarak alan hesabı yapılabilir.

Algoritma adımları aşağıdaki şekilde sıralanabilir:

  • Fonksiyonun verilen aralıktaki tüm değerlerini içine alacak şekilde bir dikdörtgen belirlenir.
  • Bu dörtgen içerisinde, N adet nokta rastgele olarak oluşturulur.
  • Bu noktaların ne kadarının, fonksiyonun belirlediği alanın altında olduğuna bakılır.
  • N değerinin, eğri altında olan nokta sayısına oranı, bize yaklaşık olarak, dikdörtgenin alanın fonksiyon eğrisi alanına oranını verecektir.

Aşağıda, Monte Carlo algoritmasının C# dilinde yazılmış kaynak kodu yer almaktadır.

using System;

namespace SG.Algoritma
{
    partial class MonteCarlo
    {
        // Deneme adet
        public uint N { get; set; }

        public MonteCarlo(uint n)
        {
            if (n == 0)
            {
                throw new ArgumentException(nameof(N));
            }

            this.N = n;
        }

        /// <summary>
        /// Verilen fonksiyon eğrisinin altında bulunan alan hesaplanıyor.
        /// </summary>
        /// <param name="func">Fonksiyon</param>
        /// <param name="x1">X ekseni üzerinde, aralık başlangıcı</param>
        /// <param name="x2">Aralık bitiş</param>
        public double CalculateArea(Func<double, double> func, double x1, double x2)
        {
            // Verilen aralıkta, fonksiyonun aldığı minimum ve maksimum değerler
            double min;
            double max;

            // Fonksiyonun minimum ve maksimum değeri hesaplanıyor
            this.CalculateMinMaxValue(func, x1, x2, out min, out max);

            // Denemelerden kaç tanesi, fonksiyon eğrisinin altında
            var hit = 0;

            // Rasgele sayı üretici
            var rand = new Random();

            // N adet dememe yap
            for (int i = 0; i < this.N; i++)
            {
                // Dikdörtgen içerisinde rasgele bir nokta üret
                var x = x1 + (x2 - x1) * rand.NextDouble();
                var y = min + (max - min) * rand.NextDouble();

                // Rasgele seçilen nokta ve fonksiyonun değeri, eğrinin aynı tarafındaysa. (İki negatif sayının çarpımı pozitiftir)
                if (func(x) * y > 0)
                {
                    // Fonksiyon değeri pozitifse
                    if (func(x) > 0)
                    {
                        // Rasgele üretilen y değeri fonsiyon eğrisinin altındaysa
                        if (func(x) > y) hit++;
                    }
                    else
                    {
                        // Rasgele üretilen y değeri fonsiyon eğrisinin üstündeyse
                        if (y < 0 && func(x) < y) hit++;
                    }
                }
            }

            var areaRectangle = Math.Abs(x2 - x1) * (max - min);

            // Seçilen rasgelen noktaların yüzde hit / N kadarı dikdörtgenin içerisinde.
            // Noktaların yüzde kaçının dikdörtgen içerisinde olduğuna bakılarak alan hesabı yapılıyor.

            return areaRectangle * (double)hit / this.N;
        }

        /// <summary>
        /// Verilen aralıkta, fornksiyonun minimum ve maksimum değerleri hesaplanıyor.
        /// </summary>
        /// <param name="func">Fonksiyon</param>
        /// <param name="x1">Aralık başlangıç</param>
        /// <param name="x2">Aralık bitiş</param>
        /// <param name="min">Hesaplanan minimum değer</param>
        /// <param name="max">Hesaplanan maksimum değer</param>
        private void CalculateMinMaxValue(Func<double, double> func, double x1, double x2, out double min, out double max)
        {
            min = double.MaxValue;
            max = double.MinValue;

            // Aralık N parçaya bölünüyor.
            var h = (x2 - x1) / this.N;

            // Verilen aralıkta, N adet nokta için, her bir noktanın fonksiyon değeri hesaplanıyor.
            for (int i = 0; i <= this.N; i++)
            {
                var x = x1 + i * h;
                var y = func(x);

                if (y < min) min = y;
                if (y > max) max = y;
            }
        }
    }
}

Monte Carlo alan hesabı algoritması ile, istediğiniz fonksiyon grafiği altında yer alan bölgenin alanını çok rahat bir şekilde hesaplayabiliriz. Fonksiyonun ne kadar karmaşık olduğunu bir önemi yok. Örneğin f(x) = x - sin(x) - 1 fonksiyon eğrisinin x ekseni {0,3} aralığındaki alanı hesaplamak için, alan hesaplama metodunu aşağıdaki gibi çalıştırabiliriz.

var mc = new MonteCarlo(1000);
var area = mc.CalculateArea(x => x - Math.Sin(x) - 1, 0, 3);

Bu durumda aşağıdaki eğri altında yer alan alan yaklaşık olarak hesaplanacaktır. Daha hassas bir hesaplamak için N değerinin artırılması gerekmektedir.

Monte Carlo Integration

Aynı algoritmada yapılacak küçük bir değişiklikle, fonksiyonun integral değeri de rahatlıkla hesaplanabilir. İntegral hesabında, pozitif alanlardan negatif alanlar çıkarılacağı için, bu alanlara düşen noktalar ayrı ayrı sayılır.

Etiketler:  C#

Kategoriler

Algoritma (4), Cheat Sheet (2), İpucu (4), Kendime Not (1), Kitap (3), Kod (5), Proje (4), Veritabanı (3), Workshop (3)

Etiketler

C# (10) HTML (1) JavaScript (2) SQL (3)

İngilizce / Türkçe

İngilizce / Türkçe kelime listesi kendime not