Kode MATLAB pemula yang datang dari bahasa lain sering penuh for dan if per elemen — dan berjalan lambat, karena tiap iterasi melewati lapisan interpreter. Vectorization adalah cara berpikir khas MATLAB: nyatakan operasi pada seluruh array sekaligus dan biarkan mesin memproses blok data secara internal di level C. Hasilnya dua arah sekaligus: kode lebih pendek (bug lebih sedikit) dan lebih cepat. Chapter ini memetakan pola-pola idiomatiknya dari contoh loop → bentuk vektornya. Cakupan chapter ini:
- Loop penjumlahan →
sumdansum(..., 2) - Filter dengan
if→ mask logical - Total berjalan →
cumsum,cumprod,diff - Loop ganda grid →
meshgrid+ operator elemen - Mengapa vectorized lebih cepat, dan kapan loop tetap perlu
Loop ke Vector: Contoh Kunci #
Aturannya: bila badan loop hanya memproses elemen secara mandiri — hasil iterasi i tidak dibutuhkan iterasi i+1 — loop tersebut kandidat kuat vectorization. Mekanismenya: sum((1:n) .^ 2) membuat satu array berisi seluruh kuadrat, lalu fungsi sum menjumlahkannya dalam satu panggilan tingkat rendah; tidak ada baris kode MATLAB yang berjalan seribu kali:
n = 1000;
totalLoop = 0;
for k = 1:n
totalLoop = totalLoop + k^2;
end
totalVec = sum((1:n) .^ 2);
fprintf('loop : %d\n', totalLoop);
fprintf('vector : %d\n', totalVec);
fprintf('identik: %d\n', isequal(totalLoop, totalVec));Output yang Dihasilkan:
loop : 333833500
vector : 333833500
identik: 1Kedua cara menghasilkan angka yang persis sama (isequal = 1) — vectorization bukan pendekatan hampiran, melainkan cara penulisan ulang yang setara. Pada array seribu elemen selisih waktunya kecil; pada array jutaan elemen (atau loop bersarang), selisihnya bisa mencapai puluhan kali lipat.
Mask Logical: Filter Tanpa if #
Aturannya: perbandingan array menghasilkan logical mask — array true/false sepanjang data — dan indeksasi logical x(mask) memilih elemen yang lolos dalam satu ekspresi. Mekanismenya: harga < 1000 mengevaluasi perbandingan untuk seluruh elemen sekaligus, lalu indeksasi memakai mask itu sebagai saringan posisi:
harga = [1200 3500 800 2200 950];
murah = harga < 1000;
fprintf('mask : %d %d %d %d %d\n', murah);
fprintf('murah : %d %d\n', harga(murah));
fprintf('jumlah : %d\n', sum(murah));
fprintf('diskon : %d %d %d\n', harga(harga >= 1000) * 0.9);Output yang Dihasilkan:
mask : 0 0 1 0 1
murah : 800 950
jumlah : 2
diskon : 1080 3150 1980Pola harga(harga >= 1000) * 0.9 menggantikan loop “jika harga di atas 1000, kalikan 0.9” — seleksi dan transformasi menyatu. sum(murah) menghitung banyaknya elemen yang lolos, idiom untuk frekuensi.
cumsum, cumprod, dan diff #
Aturannya: cumsum menghasilkan total berjalan (elemen k = jumlah elemen 1..k), cumprod hasil kali berjalan, dan diff selisih antar elemen berturutan. Mekanismenya: ketiganya adalah akumulator yang sudah dikompilasi — pekerjaan yang di loop membutuhkan variabel sementara dan dua baris, di sini menjadi satu nama fungsi:
setoran = [100 200 150 50];
saldo = cumsum(setoran);
fprintf('setoran: %d %d %d %d\n', setoran);
fprintf('saldo : %d %d %d %d\n', saldo);
fprintf('kembali: %d %d %d\n', diff(saldo));
fprintf('faktorial (cumprod 1:5): %d %d %d %d %d\n', cumprod(1:5));Output yang Dihasilkan:
setoran: 100 200 150 50
saldo : 100 300 450 500
kembali: 200 150 50
faktorial (cumprod 1:5): 1 2 6 24 120Saldo rekening Budi tumbuh 100, 300, 450, 500 dari empat setoran — dan diff(saldo) memulihkan kenaikan per periode: diff adalah kebalikan alami cumsum (dengan satu elemen pertama yang tidak terpulihkan). cumprod(1:5) menghasilkan faktorial 1!, 2!, …, 5!.
sum dengan Dimensi #
Aturannya: sum(M, 1) menjumlahkan menurun per kolom, sum(M, 2) menyamping per baris — pola yang berlaku juga untuk mean, max, cumsum, dan kawanannya. Mekanismenya: argumen kedua adalah dimensi array yang “diruntuhkan” oleh agregasi; tanpa argumen, sum menjatuhkan dimensi non-singleton:
M = [1 2 3; 4 5 6];
fprintf('sum kolom: %d %d %d\n', sum(M, 1));
fprintf('sum baris: %d %d\n', sum(M, 2));Output yang Dihasilkan:
sum kolom: 5 7 9
sum baris: 6 15Konsekuensinya penting untuk data berorientasi observasi: dengan baris = observasi dan kolom = variabel, sum(data, 2) memberi skor total per observasi, sedangkan mean(data, 1) rata-rata tiap variabel — satu perbedaan angka kecil yang mengubah seluruh hasil.
meshgrid: Operasi Grid Tanpa Loop Ganda #
Aturannya: meshgrid mengubah dua vektor koordinat menjadi dua matriks berpasangan sehingga fungsi dua variabel dievaluasi dengan operator elemen, tanpa for luar dan for dalam. Mekanismenya: X mereplikasi vektor x per baris dan Y per kolom — pasangan (X(i,j), Y(i,j)) mengunjungi seluruh kombinasi koordinat tepat satu kali:
[X, Y] = meshgrid(0:2, 0:2);
Z = X .^ 2 + Y .^ 2;
fprintf('Z baris 1: %d %d %d\n', Z(1,:));
fprintf('Z baris 2: %d %d %d\n', Z(2,:));
fprintf('Z baris 3: %d %d %d\n', Z(3,:));Output yang Dihasilkan:
Z baris 1: 0 1 4
Z baris 2: 1 2 5
Z baris 3: 4 5 8Nilai Z(3,3) = 8 berasal dari 2² + 2² — seluruh matriks 3×3 terisi dalam satu ekspresi X .^ 2 + Y .^ 2. Pola ini adalah fondasi surface plot dan contour plot yang kita pakai di Section Visualisasi Data.
Tabel Konversi dan Alasan Performa #
| Pola loop | Idiom vector | Fungsi kunci |
|---|---|---|
total = 0; for i, total = total + x(i) | total = sum(x) | sum |
for i, if x(i) > t, kumpulkan | x(x > t) | logical indexing |
for i, s(i) = s(i-1) + x(i) | s = cumsum(x) | cumsum |
for i, d(i) = x(i+1) - x(i) | d = diff(x) | diff |
for i, for j, Z(i,j) = f(...) | Z = f(X, Y) lewat meshgrid | meshgrid |
for i, y(i) = sqrt(x(i)) | y = sqrt(x) | fungsi elementwise |
Mengapa bentuk kanan lebih cepat? Loop MATLAB yang ditulis pengguna berjalan di interpreter: tiap iterasi diterjemahkan, diperiksa, dan dicek batasnya. Fungsi seperti sum bekerja di loop internal yang dikompilasi ke level C — satu kali penerjemahan untuk seluruh array, akses memori berurutan yang ramah cache. JIT compiler MATLAB modern menutup sebagian jurang untuk loop sederhana, tetapi vectorized tetap unggul untuk array besar dan hampir selalu lebih pendek.
Kapan Loop Tetap Perlu #
Vectorization bukan dogma. Loop tetap tepat ketika: iterasi saling bergantung (iterasi k memakai hasil iterasi k−1 yang tidak dinyatakan sebagai kumulatif sederhana, misalnya simulasi dinamis); kita butuh early exit (pencarian yang berhenti di temuan pertama — find dengan batas juga bisa, tapi loop eksplisit jelas); atau array hasil terlalu besar untuk memori (matriks grid 20000×20000 membutuhkan ~3 GB — memproses per blok lebih realistis). Keputusannya: data besar + operasi mandiri → vectorize; algoritme sekuensial → loop yang jujur.
Ringkasan #
Vectorization mengganti loop per elemen dengan operasi array: sum dan sum(...,2) untuk agregasi, mask logical untuk seleksi, cumsum/cumprod/diff untuk akumulasi berjalan, meshgrid + operator elemen untuk grid dua dimensi. Semua contoh chapter ini terverifikasi menghasilkan nilai identik dengan versi loop-nya, dengan kode yang jauh lebih pendek. Mesin yang menjanjikan angka identik ini bekerja dalam angka pecahan biner — dan di sanalah letak jebakan halus berikutnya: presisi numerik.