Kita sering perlu mengoperasikan dua array yang ukurannya berbeda namun maknanya saling melengkapi: harga di tiga toko (kolom 3×1) dikombinasikan dengan diskon empat hari (baris 1×4). Sebelum R2016b, MATLAB menolak kombinasi seperti itu; sejak R2016b, MATLAB dan Octave 10 (lingkungan uji kita) menerapkan implicit expansion otomatis: array berdimensi 1 direntangkan mengikuti pasangannya. Bab ini membedah aturannya, sejarahnya, galat ketika aturan dilanggar, dan praktik baiknya.

Sejarah: dari bsxfun ke Implicit Expansion #

Aturan lamanya ketat: operator elemen hanya menerima operand berukuran identik, sehingga + pada array 3×1 dan 1×4 memicu galat “Matrix dimensions must agree.” Solusi resmi sebelum R2016b adalah fungsi bsxfun (binary singleton expansion function): dimensi berukuran 1 (singleton) direplikasi di dalam satu pemanggilan, lalu operasi elemen diterapkan.

Sejak R2016b, mekanisme yang sama hidup langsung di dalam operator: a + b melakukan singleton expansion otomatis, dan bsxfun tetap tersedia hanya demi kompatibilitas. @plus pada contoh berikut adalah function handle untuk fungsi penjumlahan — dibahas tuntas pada Section Fungsi:

matlab
kolom = [10; 20; 30];          % 3x1
baris = [100 200 300 400];     % 1x4
total = kolom + baris;         % sejak R2016b: langsung 3x4
caraLama = bsxfun(@plus, kolom, baris);   % cara lama, hasil sama

fprintf('bsxfun(@plus, ...) sama dengan + : %d\n', isequal(caraLama, total));

Output yang Dihasilkan:

text
bsxfun(@plus, ...) sama dengan + : 1

Mari kita bedah baris-baris kode di atas:

  1. Baris 3 (total = kolom + baris): operator + mengenali pasangan 3×1 dan 1×4 sebagai kompatibel, lalu menghitung hasil 3×4 tanpa bantuan fungsi tambahan.
  2. Baris 4 (bsxfun(@plus, ...)): pemanggilan gaya lama menghasilkan array yang identik — fungsi isequal membandingkan dua array elemen-per-elemen dan mengembalikan 1 (true) karena keduanya sama persis.

Aturan Dimensi Kompatibel #

Aturan implicit expansion dapat dijelaskan dalam satu kalimat: dua array kompatibel bila pada setiap dimensi ukurannya sama atau salah satunya bernilai 1. Dimensi yang tidak dimiliki sebuah operand (misalnya vektor tidak punya dimensi ketiga) dihitung sebagai 1. Tabel berikut merangkum kasus-kasus penting:

Ukuran AUkuran BKompatibel?Ukuran hasil
3×43×4ya — identik3×4
3×11×4ya — tiap dimensi ada yang 13×4
1×13×4ya — skalar3×4
3×42×4tidak — baris 3 vs 2galat
3×13×4tidak — kolom 1 vs 4galat

Mekanisme di balik layar: operand berdimensi 1 direntangkan (direplikasi secara konseptual) mengikuti ukuran pasangannya, lalu operasi berjalan elemen-per-elemen. MATLAB mengoptimalkan proses ini sehingga penyalinan data nyata tidak selalu terjadi — yang penting bagi kita, hasilnya berukuran maksimum tiap dimensi.

Contoh: Kolom 3×1 + Baris 1×4 #

Contoh berikut menggabungkan tiga nilai kolom dengan empat nilai baris menjadi tabel 3×4 berisi seluruh dua belas kombinasi jumlah:

matlab
kolom = [10; 20; 30];          % 3x1
baris = [100 200 300 400];     % 1x4
total = kolom + baris;         % keduanya direntangkan -> 3x4

fprintf('size(kolom) = %dx%d, size(baris) = %dx%d\n', ...
        size(kolom,1), size(kolom,2), size(baris,1), size(baris,2));
fprintf('size(total) = %dx%d\n', size(total,1), size(total,2));
fprintf('baris 1: %d %d %d %d\n', total(1,:));
fprintf('baris 2: %d %d %d %d\n', total(2,:));
fprintf('baris 3: %d %d %d %d\n', total(3,:));

Output yang Dihasilkan:

text
size(kolom) = 3x1, size(baris) = 1x4
size(total) = 3x4
baris 1: 110 210 310 410
baris 2: 120 220 320 420
baris 3: 130 230 330 430

Mari kita bedah baris-baris kode di atas:

  1. Baris 3 (total = kolom + baris): dimensi pertama 3×1 direntangkan ke 3 baris, dimensi kedua 1×4 direntangkan ke 4 kolom — hasilnya 3×4.
  2. Baris 4-5 (size): ukuran operand dan ukuran hasil dicetak berdampingan sehingga aturan “sama atau 1” terlihat langsung.
  3. Baris 6-8 (total(i,:)): tiap baris hasil adalah kolom(i) ditambah seluruh isi baris — baris 1 memuat 10+100, 10+200, 10+300, 10+400.

Diagram berikut memvisualisasikan proses rentang tersebut:

Teks diagram: operand K hanya punya satu kolom, sehingga nilainya diulang ke empat kolom; operand B hanya punya satu baris, sehingga nilainya diulang ke tiga baris; array hasil berukuran 3×4 berisi penjumlahan setiap pasangan posisi.

Praktik: Menghitung Selisih dari Rata-rata Kolom #

Penerapan sehari-hari: menghitung penyimpangan tiap nilai dari rata-rata kolomnya (langkah awal statistik dan normalisasi). Fungsi mean(nilai, 1) menghasilkan vektor baris 1×4 berisi rata-rata tiap kolom; pengurangan nilai - rataKolom lalu bekerja lewat implicit expansion — vektor 1×4 “diulang” ke tiga baris:

matlab
nilai = [90 85 78 92; 70 75 80 68; 60 65 70 75];
rataKolom = mean(nilai, 1);    % rata-rata tiap kolom -> 1x4
selisih = nilai - rataKolom;   % 3x4 - 1x4 -> 3x4

fprintf('rataKolom  : %.2f %.2f %.2f %.2f\n', rataKolom);
fprintf('selisih r1 : %.2f %.2f %.2f %.2f\n', selisih(1,:));
fprintf('selisih r2 : %.2f %.2f %.2f %.2f\n', selisih(2,:));
fprintf('selisih r3 : %.2f %.2f %.2f %.2f\n', selisih(3,:));

Output yang Dihasilkan:

text
rataKolom  : 73.33 75.00 76.00 78.33
selisih r1 : 16.67 10.00 2.00 13.67
selisih r2 : -3.33 0.00 4.00 -10.33
selisih r3 : -13.33 -10.00 -6.00 -3.33

Mari kita bedah baris-baris kode di atas:

  1. Baris 2 (mean(nilai, 1)): argumen 1 memerintahkan mean menghitung rata-rata sepanjang dimensi 1 (per kolom) — hasilnya 1×4, satu nilai per kolom.
  2. Baris 3 (nilai - rataKolom): matriks 3×4 dikurangi vektor 1×4 — kompatibel karena dimensi pertama 1 direntangkan menjadi 3.
  3. Baris 5-7 (selisih(i,:)): elemen pertama baris pertama adalah 90 − 73.33 = 16.67 — tiap elemen dikurangi rata-rata kolomnya sendiri.

Galat Bila Tidak Kompatibel #

Implicit expansion melonggarkan syarat, bukan menghapusnya. Matriks 3×1 dan 2×4 tidak kompatibel (dimensi pertama 3 vs 2, dimensi kedua 1 vs 4), sehingga operasi tetap ditolak:

matlab
a = ones(3, 1);     % 3x1
b = ones(2, 4);     % 2x4
a + b               % 3 vs 2 dan 1 vs 4: tidak ada yang cocok
text
Error using +
Arrays have incompatible sizes for this operation.

Operasi yang Mendukung dan Praktik Baik #

Implicit expansion berlaku pada seluruh operasi biner yang bekerja elemen-per-elemen: aritmetika +, -, .*, ./, .\, .^, operator perbandingan ==, ~=, <, <=, >, >=, serta operator logika elemen &, |. Adapun operator matriks *, /, \, ^ tidak menerapkannya — pasangan skalar dengan matriks tetap diizinkan karena skalar memang kasus khusus yang sudah sah sejak lama.

Praktik baik yang perlu kita jaga:

  • Periksa orientasi vektor sebelum mengoperasikan: 1×4 dan 4×1 terlihat mirip di layar, tetapi keduanya rentang ke arah yang berbeda dan menghasilkan galat atau hasil 3×4 yang tak diinginkan.
  • Perlakukan implicit expansion sebagai alat kombinasi yang memang bermakna (tiap pasangan baris-kolom), bukan untuk “menambal” dua array yang seharusnya sama ukurannya.
  • Gunakan size saat ragu; dua baris cetak ukuran operand jauh lebih murah daripada menebak-nebak dari pesan galat.

Ringkasan #

Implicit expansion (sejak R2016b) menggantikan bsxfun untuk kode baru: operand berdimensi 1 direntangkan otomatis, hasil berukuran maksimum tiap dimensi, dan skalar tetap menjadi kasus khusus yang universal. Aturan “sama atau 1” menentukan kompatibilitas pada seluruh operator elemen; operator matriks tidak ikut menerapkan aturan ini. Berkas contoh.m pada bagian bawah halaman memverifikasi seluruh contoh bab ini di Octave 10 yang mendukung implicit expansion.