From: Faré <fa...@gm...> - 2009-11-19 17:26:37
|
OK, here is another attempt for my patch to SBCL's PRNG initialization. Once again, it compiles cleanly for me (on 1.0.32.30 on linux/amd64), and appears to pass run-tests.sh. The differences wrt previous patch are as follows: * my reviewer Dominic Schulz suggested I compare the output of my patch to what the upstream authors have. And I indeed found two bugs in my patch, one in the initialization of the counter (I left the old 1 instead of the new 624), and one in my reading of a C conditional (I read it as "min", it was "max"). * With the understanding of iterations as "max" of input length and N, I updated the code to NOT strip the input length to 19968 bits anymore. Mix as much noise as you want! * I moved a few defconstants up and created a deftype, so I could use a little more abstraction in the initialization algorithm (just in case anyone decides to implement the more general version of MT, or just the standard 64-bit variant). Here is the code I used to compare the output of the patched SBCL to that of the original authors: (defun print-random-state (&optional (x *random-state*)) (loop :with s = (random-state-state x) :for i :from 2 :below 627 :do (progn (format t "~10D " (aref s i)) (when (= 1 (mod i 5)) (terpri))))) (defparameter *random-state-1* (make-random-state 1234567)) (print-random-state *random-state-1*) (defparameter *random-state-2* (make-random-state (make-array 4 :element-type '(unsigned-byte 32) :initial-contents '(#x123 #x234 #x345 #x456)))) (print-random-state *random-state-2*) (let ((*random-state* (make-random-state *random-state-2*))) (format t "1000 outputs of genrand_int32()~%") (loop :for i :below 1000 :do (progn (format t "~10D " (random-chunk *random-state*)) (when (= 4 (mod i 5)) (terpri))))) And for the original authors, I modified the main function of their mt19937ar.c into: void print_state (void) { int i; int n; for(n=mti,i=-1;i<N;i++,n=mt[i]) { printf("%10lu ", n); if (i%5==3) printf("\n"); } } int main(void) { int i; unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4; printf("state of init_genrand(1234567UL);\n") ; init_genrand(1234567UL); print_state(); printf("\n\n") ; printf("state of init_by_array({0x123, 0x234, 0x345, 0x456}, 4);\n") ; init_by_array(init, leng\ th); print_state(); printf("\n\n") ; printf("1000 outputs of genrand_int32()\n"); for (i=0; i<1000; i++) { printf("%10lu ", genrand_int32()); if (i%5==4) printf("\n"); } return 0; } Please don't take my word for it and triple check as you apply the patch. http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c Once again, many thanks to Nikodemus, Sydney, Christophe, Dominic and Adlai. [ François-René ÐVB Rideau | Reflection&Cybernethics | http://fare.tunes.org ] The naturalistic fallacy: "if it's natural, it's good." The anti-naturalistic fallacy: "if it's natural, it's bad." The a-naturalistic fallacy: "nature has no relationship to good and bad." |