Pertumbuhan bunga berbunga, peluruhan panas, dan pertambahan populasi mengikuti pola eksponensial, sedangkan skala desibel, pH, dan perbedaan orde magnitudo diukur dengan logaritma. NumPy menyediakan kedua kelompok fungsi ini sebagai ufunc: np.exp untuk eksponensial dan np.log beserta variannya untuk logaritma. Keduanya bekerja elemen-per-elemen pada array, sehingga perhitungan untuk ribuan titik data sekaligus tetap satu baris kode.
Bab ini membahas:
np.expdan contoh pertumbuhan majemuk.np.expm1dannp.log1puntuk nilai input yang sangat kecil.np.log,np.log2, dannp.log10beserta perilakunya pada input nol dan negatif.
np.exp dan Pertumbuhan Majemuk #
Fungsi np.exp(x) menghitung e^x untuk setiap elemen, dengan e ≈ 2.718281828. Bentuk ini menjadi dasar rumus pertumbuhan majemuk kontinu V = V0 * e^(r * t), dengan r laju pertumbuhan per periode dan t waktu. Kita coba pada investasi Rp10.000.000 dengan laju 8% per tahun selama lima tahun:
import numpy as np
modal = 10_000_000
tahun = np.arange(0, 6)
nilai = modal * np.exp(0.08 * tahun)
for t, v in zip(tahun, nilai):
print(f"Tahun {t}: Rp{v:,.0f}")Output yang Dihasilkan:
Tahun 0: Rp10,000,000
Tahun 1: Rp10,832,871
Tahun 2: Rp11,735,109
Tahun 3: Rp12,712,492
Tahun 4: Rp13,771,278
Tahun 5: Rp14,918,247Mari kita bedah:
- Baris 3 (
modal = 10_000_000): pemisah garis bawah hanya memperjelas pembacaan angka; nilai tersimpan tetap10000000. - Baris 4 (
tahun = np.arange(0, 6)): interpreter membuat array[0, 1, 2, 3, 4, 5]sebagai sumbu waktu. - Baris 5 (
nilai = modal * np.exp(...)):np.exp(0.08 * tahun)menghitung e^(0,08t) untuk keenam titik waktu sekaligus, lalu hasilnya dikalikan modal. - Baris 6-7 (loop
for):zipmemasangkan tahun dengan nilainya, dan format{:,.0f}menampilkan pemisah ribuan tanpa angka desimal.
Bentuk dasarnya sendiri sederhana:
import numpy as np
x = np.array([0.0, 1.0, 2.0, 5.0])
print(np.exp(x))Output yang Dihasilkan:
[ 1. 2.71828183 7.3890561 148.4131591 ]expm1 dan log1p untuk Nilai Input Kecil #
Menghitung exp(x) - 1 dengan cara biasa memicu pembatalan presisi (catastrophic cancellation) ketika x sangat kecil: np.exp(1e-10) bernilai hampir sama persis dengan 1, sehingga pengurangan dengan 1.0 membuang sebagian besar angka signifikan. NumPy menyediakan np.expm1 yang menghitung e^x - 1 langsung tanpa melalui nilai mendekati 1. Pasangannya adalah np.log1p, versi akurat untuk log(1 + x):
import numpy as np
x = 1e-10
print(np.expm1(x))
print(np.exp(x) - 1.0)
print(np.log1p(x))
print(np.log(1.0 + x))Output yang Dihasilkan:
1.00000000005e-10
1.000000082740371e-10
9.999999999500001e-11
1.000000082690371e-10Nilai teoretis yang benar untuk expm1(1e-10) adalah 1e-10 + 5e-21, yang tampil sebagai 1.00000000005e-10. Hasil np.exp(1e-10) - 1.0 meleset sekitar 8x10^-8 secara relatif — kesalahan kecil bagi mata manusia, tetapi cukup besar saat hasilnya dipakai untuk perhitungan lanjutan. Pola yang sama terlihat pada log1p(1e-10) yang menghasilkan 9.999999999500001e-11, sedangkan np.log(1.0 + 1e-10) memberi nilai yang meleset lebih jauh.
Logaritma: log, log2, dan log10 #
np.log menghitung logaritma natural (basis e), np.log2 basis 2, dan np.log10 basis 10. Ketiganya adalah invers dari np.exp, np.exp2, dan 10 ** x:
import numpy as np
x = np.array([1.0, np.e, 8.0, 100.0])
print(np.log(x))
print(np.log2(np.array([8.0, 1024.0])))
print(np.log10(np.array([100.0, 1_000_000.0])))Output yang Dihasilkan:
[0. 1. 2.07944154 4.60517019]
[ 3. 10.]
[2. 6.]Setiap logaritma berpasangan dengan satu eksponensial sebagai inversnya, dan pemilihan basis menyesuaikan domain data:
| Fungsi eksponensial | Invers logaritmanya | Contoh pasangan |
|---|---|---|
np.exp | np.log | log(e^3) = 3.0 |
np.exp2 | np.log2 | log2(1024) = 10 |
10 ** x | np.log10 | log10(1_000_000) = 6 |
Logaritma natural lazim untuk pertumbuhan dan peluruhan, log2 untuk kecerdasan buatan dan teori informasi (ukuran bit), sedangkan log10 untuk skala seperti desibel dan besaran orde magnitudo.
Perilaku pada input tidak valid berbeda untuk nol dan bilangan negatif: log(0) menghasilkan -inf, sedangkan log(bilangan negatif) menghasilkan nan. NumPy mencetak runtime warning ketika operasi ini terjadi; bungkus pemanggilan dengan np.errstate agar output program tetap bersih:
import numpy as np
x = np.array([1.0, 0.0, -4.0])
with np.errstate(divide="ignore", invalid="ignore"):
print(np.log(x))Output yang Dihasilkan:
[ 0. -inf nan]