1.3. Matematiksel Fonksiyonlar
Kayıt Tarihi:
Son Güncelleme:
Daha karmaşık matematiksel hesaplamalar için math gibi modülleri kullanmaya ihtiyacımız olur. Üstel, trigonometrik, logaritmik ve benzeri fonksiyonlar bu gibi modüller içindedir.
Anahtar Kelimeler: cmath · decimal · import · kompleks fonksiyonlar · kompleks sayılar · math · modül · scipy · yuvarlama hatasıŞimdi biraz daha karmaşık hesaplamalar yapalım. Varsayalım ki bir top belirli bir ilk hızla yerden fırlatılıyor ve topun verilen bir $y=y_1$ konumuna ne kadar zamanda ulaşacağını hesaplamamız isteniyor. Bu problemi çözmek için $$y_1=v_0t-\frac{1}{2}gt^2$$ formülünde $t$ değişkenini çözmemiz gerekiyor. Bunun için denklemi $$\frac{1}{2}gt^2-v_0t+y_1=0$$ biçiminde yazalım, bu denklem $t$'nin ikinci dereceden cebirsel bir denklemidir ve çözümü $$t_1=\frac{v_0-\sqrt{v_0^2-2gy_1}}{g}\quad\text{ve}\quad t_2=\frac{v_0+\sqrt{v_0^2-2gy_1}}{g}$$ biçimindedir. Bu iki çözümden birisi topun yükselirken diğeri de geri düşerken $y_1$ konumuna ulaştığı zamanı belirtir. Bu hesaplamayı Python'da yapmak için $\sqrt{x}$ işlemine ihtiyacımız olacak.
Math Modülü
Python'da özel amaçlı fonksiyonlar, adına modül denilen dosyalarda saklanır ve bu fonksiyonları kullanmak için ilgili modülü kullanacağımızı programımızın içinde belirtmemiz gerekir. Python'da $\sqrt{x}$, $\sin(x)$, $\cos(x)$, $\log(x)$ gibi matematiksel hesaplamalar math
modülü içinde tanımlıdır. $\sqrt{x}$ işlemi örneğin math
modülü içinde tanımlı olan sqrt()
fonksiyonu yardımıyla yapılır. Bir modül içindeki bir fonksiyonu kullanmadan önce programımızda from modul import fonksiyon
komutunu girmemiz gerekiyor, bu işleme modülden ilgili fonksiyonu ithal etme (import etme) denir. Dolayısıyla yukarıdaki hesaplamayı aşağıdaki program ile yapabiliriz.
from math import sqrt
v0 = 5
g = 9.81
y1 = 0.2
t1 = (v0 - sqrt(v0**2 - 2*g*y1))/g
t2 = (v0 + sqrt(v0**2 - 2*g*y1))/g
print t1, t2
Bu programın çıktısı şu şekilde olacaktır.
Terminal > python hesap12.py
0.0417063724983 0.977661619347
Burada print
ifadesinden sonra iki veriyi virgülle ayırarak yazdık, bu şekilde virgülle ayrılarak sıralanmış nesneler aynı satırda yazdırılır. Ayrıca programın okunaklı olması açısından genellikle import ifadeleri programın ilk satırlarında yazılır ve gerektiğinde boş satırlar bırakılır. Programımızda aynı modülden birden fazla fonksiyon kullanılacaksa bunları virgülle ayırarak from math import sqrt, sin, log, exp
biçiminde belirtebiliriz. Modüldeki tüm fonksiyonlara ihtiyacımız olacaksa from math import *
komutu ile modüldeki tüm fonksiyonları programımızda kullanılabilir hale getirmiş oluruz. Bunun yerine sadece import math
komutunu girersek de modülün tüm fonksiyonlarına erişim sağlamış oluruz, fakat bu durumda o fonksiyonları kullanırken modülün ismini ön ek olarak math.sqrt()
biçiminde belirtmemiz gerekir.
import math
v0 = 5
g = 9.81
y1 = 0.2
t1 = (v0 - math.sqrt(v0**2 - 2*g*y1))/g
t2 = (v0 + math.sqrt(v0**2 - 2*g*y1))/g
print t1, t2
Burada kullandığımız ön eki istersek değiştirebiliriz. import math as m
komutuyla fonksiyonları m.sqrt()
gibi kullanabiliriz.
import math as m
v0 = 5
g = 9.81
y1 = 0.2
t1 = (v0 - m.sqrt(v0**2 - 2*g*y1))/g
t2 = (v0 + m.sqrt(v0**2 - 2*g*y1))/g
print t1, t2
math
modülü içinde yukarıda bahsettiğimiz gibi matematiksel fonksiyonların yanında $\pi$ ve $\text{e}$ gibi bazı matematiksel sabitler de vardır.
from math import sin, cos, log, pi
x = 3*pi/2
s = sin(x-1)*cos(x+1) + log(2*x)
print s
Yukarıdaki program aşağıdaki çıktıyı üretecektir.
Terminal > python hesap15.py
1.7886934611
Kompleks Sayılar
İkinci dereceden cebirsel denklemlerin kompleks kökleri var olabilir, bu durumla hesaplamalarda sıklıkla karşılaşırız ve dolayısıyla programlarımızda kompleks sayılarla işlem yapmaya ihtiyacımız olabilir. Şimdi biraz da Python'da kompleks sayı işlemlerine değinelim. Bir kompleks sayı, $a$ ve $b$ reel sayılar olmak üzere $a + i\cdot b$ biçiminde ifade edilir. Buradaki $i$ sayısına sanal birim denir ve $i^2=-1$ yani $i=\sqrt{-1}$ eşitliği ile tanımlanır. Bu sayılar yardımıyla diskrıminantı negatif olan $x^2+2=0$ gibi denklemlerin çözümleri $x_{1,2}=\pm\sqrt{2}i$ biçiminde ifade edilebilir. Python'da sanal birim j
sembolü ile gösterilir, örneğin $1+2i$ kompleks sayısı 1 + 2j
biçiminde kodlanır. 2j
kısmını kodlarken arada *
çarpma işareti kullanmadığımıza dikkat edin, ayrıca Python'da pür sanal $i$ sayısını da 1j
olarak kodlarız. j
sembolünün önünde mutlaka bir sayı gelmeli ve arada çarpma işareti bulunmamalıdır. Bu şekilde tanımlanmış değişkenler Python'da bir complex
nesnesi olarak adlandırılır, Pythonda herhangi bir x
nesnesinin hangi türden olduğunu anlamak için type(x)
komutunu kullanırız. Bunları bir Python oturumunda gözlemleyelim.
>>> x = 3-2j
>>> type(x)
>>> y = 2-1j
>>> type(y)
type 'complex'>
Kompleks sayı nesneleriyle işlem yaparken Python bunların kompleks sayı olduğunu algılar ve otomatik olarak kompleks sayı aritmetiğini kullanır. Şimdi yukarıda tanımladığımız sayılarla bazı işlemler yapalım.
>>> x + y
(5-3j)
>>> 2*y
(4-2j)
>>> y + 2j
(2+1j)
Python'da kompleks sayıların girdiği işlemlerin sonucu her zaman bir complex
nesnesi olarak döndürülür. Ancak bir $x$ kompleks sayısının reel ve imajiner kısımları sırasıyla x.real
ve x.imag
komutlarıyla (Bir nesne üzerinde böyle çalıştırılan komutlara birer metod denir.) birer reel sayı (float) olarak elde edilebilir.
>>> x.real
3.0
>>> x.imag
-2.0
Bunların dışında sonucun her zaman bir complex
nesnesi olması bazı zorluklar yaratır. Örneğin bir kompleks sayı hesabının sonucunda imajiner kısım sıfır çıksa bile o sayı float
nesnesi yerine hala bir complex
nesnesi olarak döner.
>>> z = x - 2*y
>>> z
(-1+0j)
>>> type(z)
type 'complex'>
Hatta manuel olarak bile bu sayıyı bir float
nesnesine dönüştüremeyiz. Bunu denersek Python yazılımı bize complex
nesnelerinin float
nesnelerine dönüştürülemeyeceğini anlatan bir hata mesajı gösterir.
>>> a = float(z)
Traceback (most recent call last):
File "", line 1, in
TypeError: can't convert complex to float
Böyle bir sayıyı aşağıdaki gibi bir float
veya int
nesnesine dönüştürmek mümkündür.
>>> a = z.real
>>> a
-1.0
>>> type(a)
type 'float'>
Kompleks Fonksiyonlar
Python'da kompleks sayıları daha önce math
modülünde gördüğümüz matematiksel fonksiyonlar içinde kullanamayız, o fonksiyonlar float
nesneleriyle çalışacak şekilde tanımlanmışlardır. Mesela yukarıda tanımladığımız x
kompleks sayısının sinüs değerini hesaplatmaya çalışırsak aşağıdaki gibi bir hata mesajı ile karşılaşırız.
>>>import math
>>> math.sin(x)
Traceback (most recent call last):
File "", line 1, in
TypeError: can't convert complex to float
Kompleks değişkenler içeren matematiksel fonksiyonlar Python'un cmath
(complex math) modülü içinde tanımlanmıştır ve kompleks matematiksel işlemler için bu modülü kullanmalıyız.
>>> import cmath
>>> cmath.sin(x)
(0.5309210862485197+3.5905645899857794j)
Fakat cmath
modülündeki fonksiyonlarla işlem yaparken de sonuçta imajiner kısım sıfır çıkınca bu bir complex
nesnesi olarak döner. Bir hesaplama sonucunda imajiner kısım varsa bunun bir complex
, yoksa da bunun bir float
nesnesi olarak dönmesini arzularız. Bunun için cmath
yerine scipy
(SciPy
, Scientific Python) paketini kullanmalıyız. Burada da tüm matematiksel fonksiyonlar vardır ve hepsi sonuçta imajiner kısım varsa complex
, yoksa float
nesnesi döndürecek şekilde tanımlanmıştır.
>>> from scipy import sin, pi
>>> x = 3 - 2j
>>> sin(x)
(0.53092108624851975+3.5905645899857799j)
>>> sin(pi)
1.2246467991473532e-16
Yuvarlama Hataları
Bölümü bitirmeden önce biraz da yuvarlama hatalarından bahsetmek gerekiyor, aşağıdaki gözlemi yapalım.
>>> a = 1.0/49
>>> b = 49
>>> a*b
0.9999999999999999
Buradaki hata programlama hatası değildir, bilgisayarların çalışma prensipleri ile ilgili temel bir durumdur bu ve tüm programlama dillerinde böyle durumlarla karşılaşılır. Bir reel sayı aslında çok sayıda basamaktan oluşur (rasyonel değilse sonsuz) ve bilgisayar hafızaları sınırlı olduğundan sadece baştan bir kaç basamağı kullanılarak hafızada tutulurlar. Genellikle bilgisayarlarda 17 basamak kullanılır, dolayısıyla reel sayılarla (float
tipi veri) hesaplama yaparken aslında bir miktar hata payı ile çalışıyor oluyoruz, bu tür hatalara yuvarlama hatası denir. print
ifadesi ile bir float verisini yazdırırken kaç basamak gösterilmesi gerektiğini belirtmezsek, python az sayıda basamak kullanarak yazdırır ve yuvarlama hatalarını çoğu zaman farketmeyiz. Pythonda reel sayıları istenilen hata payı ile hesaplayabilen ve dolayısıyla sonuçta arzu edilen hata sınırları içinde kalmamızı sağlayan decimal
modulü, ve SciPy
paketi içinde bulunan mpmath
modülü vardır. Fakat bunlara genelde fazla ihtiyaç duymayız çünkü nümerik yöntemlerin geliştirilmesinde yapılan hatalar yuvarlama hatalarından genellikle çok daha büyüktür.
1.2. Değişkenler ve Basit Hesaplamalar
Python ve Bilimsel Hesaplama
2.1. While Döngüleri