Analisis yang hasilnya berubah setiap dijalankan sulit di-debug dan sulit dipercaya: rekan kerja tidak bisa mengonfirmasi temuan kita, dan galat yang muncul “kadang-kadang” jadi perburuan tanpa jejak. Reproducible results adalah disiplin menjaga eksekusi program memberikan hasil yang identik dari waktu ke waktu dan dari mesin ke mesin. Chapter ini memetakan sumber non-determinisme di MATLAB, lalu memberi resep menanganinya:

  • Menetapkan seed generator angka acak dengan rng.
  • Menyimpan hasil ke berkas .mat dan membandingkannya ulang.
  • Perbandingan bertoleransi untuk aritmetika floating point.
  • Checksum berkas data dan dokumentasi lingkungan eksekusi.

Sumber Non-Determinisme #

Sebelum membereskan, kita perlu tahu musuhnya. Tabel berikut merangkum penyebab paling umum hasil berubah antar eksekusi:

SumberGejalaPenanganan
rand/randn tanpa seedangka berbeda tiap runrng(42) di awal skrip
Waktu sistem (now, clock, date)keluaran/label berubahsimpan waktu sebagai data, jangan masuk hitungan
Urutan isi folder (dir)iterasi berkas beda urutansort() hasil dir sebelum diproses
Paralel / timing (parfor)urutan penulisan tak menentuhasil digabung setelah semua worker selesai
Floating point lintas platformdigit terakhir berbedabandingkan dengan toleransi, bukan isequal mentah
Versi MATLAB/toolbox berbedaalgoritma bawaan berubahkunci versi + uji ulang saat upgrade

Mekanisme di balik layar: generator angka acak MATLAB sebenarnya fungsi deterministik — angka “acak” hanyanya urutan yang dihitung dari state internal. Tanpa seed, state diambil dari sumber yang berubah (waktu/idle sistem), sehingga urutan berbeda tiap eksekusi. Menetapkan seed berarti mengembalikan state ke titik yang sama, dan urutan yang sama pun keluar.

RNG dengan Seed dan Perbandingan Bertoleransi #

Aturannya sederhana: setiap skrip yang memakai angka acak memanggil rng(seed) di baris pertama. Potongan dari contoh.m di bawah halaman ini menunjukkan kedua uji tersebut:

matlab
% --- 1. Angka acak: seed tetap membuat urutan dapat diulang ---
rng(42);
a = rand(1, 5);
rng(42);
b = rand(1, 5);
fprintf('[1] rng(42) dua kali   : konsisten = %d\n', isequal(a, b));

% --- 4. Floating point: isequal vs perbandingan bertoleransi ---
kiri = 0.1 + 0.2;
fprintf('[4] isequal(0.1+0.2, 0.3) : %d\n', isequal(kiri, 0.3));
selisih = abs(kiri - 0.3);
fprintf('    toleransi 1e-9      : lolos = %d\n', selisih < 1e-9);

Ekspresi 0.1 + 0.2 tidak tepat sama dengan 0.3 karena 0.1 dan 0.2 tidak dapat diwakili persis dalam biner; isequal mengembalikan 0 (false) meskipun selisihnya hanya sekitar 5.551e-17. Perbandingan abs(a - b) < toleransi (atau isequaln untuk NaN) adalah cara yang benar membandingkan hasil komputasi numerik.

Simpan, Muat Ulang, Bandingkan #

Untuk hasil yang perlu dikonfirmasi di lain waktu, pola bekerjanya: hitung → simpan ke .mat → muat ulang → bandingkan dengan isequal. Potongan dari contoh.m:

matlab
% --- 3. Roundtrip save/load: hasil identik saat dibaca ulang ---
hasilRil = struct('rata', rata, 'jumlah', numel(data), 'maks', max(data));
save('-v7', 'hasil_uji.mat', 'hasilRil');
clear hasilRil
load('hasil_uji.mat');
fprintf('[3] roundtrip .mat      : identik = %d (rata = %.2f)\n', ...
        isequal(hasilRil.rata, rata), hasilRil.rata);
delete('hasil_uji.mat');

Mekanisme di balik layar: save menulis variabel workspace ke berkas biner .mat (format v7 default; -v7.3 untuk berkas di atas 2 GB), dan load mengembalikan variabel tersebut ke workspace dengan nama dan nilai aslinya — roundtrip ini identik bit per bit untuk array numerik dan struct.

Versi MATLAB dan Lingkungan Eksekusi #

Hasil dapat berubah antar versi karena MathWorks menyempurnakan fungsi bawaan (misalnya algoritma interp1 atau solver ODE). Dua alat dokumentasi:

  • ver menampilkan tabel versi MATLAB beserta daftar toolbox terpasang — catat keluarannya ke catatan rilis hasil analisis (di GNU Octave, ver menampilkan versi Octave; version() hanya mengembalikan string versi).
  • verLessThan('matlab', '9.9') (MATLAB-ONLY) membandingkan versi aktif dengan ambang — berguna sebagai penjaga versi di awal skrip: if verLessThan('matlab','9.9'), error(...); end mencegah skrip berjalan di versi yang belum teruji.

Checksum Berkas Data #

Bila analisis membaca berkas data, tambahkan checksum: satu angka yang dihitung dari isi berkas. Angka ini dicatat di catatan rilis; saat berkas berubah satu byte pun, checksum ikut berubah sehingga perbedaan data langsung terdeteksi tanpa membaca isi berkas secara manual. MATLAB tidak menyediakan fungsi hash berkas bawaan (umumnya via Java MessageDigest atau File Exchange), sehingga contoh.m memakai checksum bergulir 32-bit dari aritmetika double murni yang portabel:

matlab
c = 0;
for k = 1:numel(bytes)
    c = mod(c * 31 + double(bytes(k)), 4294967296);
end

Output yang Dihasilkan (dari contoh.m lengkap):

text
[1] rng(42) dua kali   : konsisten = 1
[2] mean data tetap     : 87.20
[3] roundtrip .mat      : identik = 1 (rata = 87.20)
[4] isequal(0.1+0.2, 0.3) : 0
    selisih absolut     : 5.551e-17
    toleransi 1e-9      : lolos = 1
[5] checksum baca ulang : sama = 1 (nilai = 2416758383)
    setelah data berubah: berubah = 1 (nilai = 3770068080)
[6] engine versi        : 10.3.0
    catat juga: daftar toolbox dan sistem operasi

Mari kita bedah baris-baris kode di atas:

  1. Baris [1]: dua panggilan rng(42) menghasilkan urutan rand yang identik — isequal mengembalikan 1 meskipun angka spesifiknya tidak perlu dicetak (angka acak nilai internal yang berbeda antar engine).
  2. Baris [3]: hasil save/load dibandingkan ulang dengan isequal — roundtrip .mat tidak mengubah nilai sedikit pun.
  3. Baris [4]: isequal(0.1+0.2, 0.3) bernilai 0 karena representasi biner; selisih 5.551e-17 lolos uji toleransi 1e-9 — pasangan inilah bukti “isequal untuk data, toleransi untuk komputasi”.
  4. Baris [5]: checksum berkas identik saat dibaca ulang (sama = 1) dan berubah total setelah satu nilai data diganti 90 → 91 — deteksi perubahan berkas tanpa inspeksi manual.
  5. Baris [6]: versi engine tercatat sebagai bagian laporan; lengkapi dengan daftar toolbox (keluaran ver) dan sistem operasi pada dokumentasi proyek.

Checklist Reproducibility #

ItemContoh pemakaian
Seed acak tetaprng(42) di baris pertama skrip
Data sumber dikuncisimpan data_uji.csv + catat checksum-nya
Waktu tidak masuk hitungannow() hanya untuk stempel laporan
Urutan iterasi ditetapkansort setelah dir
Hasil disimpan & dibandingkansave/load + isequal/toleransi
Versi terdokumentasikeluaran ver di catatan rilis
Penjaga versi bila wajibverLessThan (MATLAB-ONLY) di awal skrip

Ringkasan #

Non-determinisme datang dari angka acak tanpa seed, waktu sistem, urutan berkas, paralelisme, dan floating point lintas platform. Disiplinnya: rng(seed) di awal, waktu hanya sebagai stempel, sort untuk urutan, perbandingan isequal untuk data dan toleransi untuk komputasi numerik, roundtrip save/load untuk konfirmasi hasil, checksum untuk berkas data, dan dokumentasi ver/version() agar pembaca tahu di lingkungan mana hasil dihasilkan. verLessThan hanya untuk jalur khusus MATLAB. Seluruh resep portabel dibuktikan di contoh.m.