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
.matdan 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:
| Sumber | Gejala | Penanganan |
|---|---|---|
rand/randn tanpa seed | angka berbeda tiap run | rng(42) di awal skrip |
Waktu sistem (now, clock, date) | keluaran/label berubah | simpan waktu sebagai data, jangan masuk hitungan |
Urutan isi folder (dir) | iterasi berkas beda urutan | sort() hasil dir sebelum diproses |
Paralel / timing (parfor) | urutan penulisan tak menentu | hasil digabung setelah semua worker selesai |
| Floating point lintas platform | digit terakhir berbeda | bandingkan dengan toleransi, bukan isequal mentah |
| Versi MATLAB/toolbox berbeda | algoritma bawaan berubah | kunci 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:
% --- 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:
% --- 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:
vermenampilkan tabel versi MATLAB beserta daftar toolbox terpasang — catat keluarannya ke catatan rilis hasil analisis (di GNU Octave,vermenampilkan 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(...); endmencegah 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:
c = 0;
for k = 1:numel(bytes)
c = mod(c * 31 + double(bytes(k)), 4294967296);
endOutput yang Dihasilkan (dari contoh.m lengkap):
[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 operasiMari kita bedah baris-baris kode di atas:
- Baris
[1]: dua panggilanrng(42)menghasilkan urutanrandyang identik —isequalmengembalikan 1 meskipun angka spesifiknya tidak perlu dicetak (angka acak nilai internal yang berbeda antar engine). - Baris
[3]: hasilsave/loaddibandingkan ulang denganisequal— roundtrip.mattidak mengubah nilai sedikit pun. - Baris
[4]:isequal(0.1+0.2, 0.3)bernilai 0 karena representasi biner; selisih5.551e-17lolos uji toleransi1e-9— pasangan inilah bukti “isequal untuk data, toleransi untuk komputasi”. - 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. - Baris
[6]: versi engine tercatat sebagai bagian laporan; lengkapi dengan daftar toolbox (keluaranver) dan sistem operasi pada dokumentasi proyek.
Checklist Reproducibility #
| Item | Contoh pemakaian |
|---|---|
| Seed acak tetap | rng(42) di baris pertama skrip |
| Data sumber dikunci | simpan data_uji.csv + catat checksum-nya |
| Waktu tidak masuk hitungan | now() hanya untuk stempel laporan |
| Urutan iterasi ditetapkan | sort setelah dir |
| Hasil disimpan & dibandingkan | save/load + isequal/toleransi |
| Versi terdokumentasi | keluaran ver di catatan rilis |
| Penjaga versi bila wajib | verLessThan (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.