From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 58D5ABBAF for ; Thu, 3 Dec 2009 12:01:05 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AqsAAP8oF0uBrw8EmWdsb2JhbACEOIt2i2EBAQEBAQgLCgcTqXOQcYEvgixXBIFn X-IronPort-AV: E=Sophos;i="4.47,334,1257116400"; d="scan'208";a="51431009" Received: from ext.lri.fr ([129.175.15.4]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/ADH-AES256-SHA; 03 Dec 2009 12:01:04 +0100 Received: from localhost (localhost [127.0.0.1]) by ext.lri.fr (Postfix) with ESMTP id B7165A4402 for ; Thu, 3 Dec 2009 12:01:04 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at lri.fr Received: from ext.lri.fr ([127.0.0.1]) by localhost (ext.lri.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9OL8Hp-J4JRW for ; Thu, 3 Dec 2009 12:01:04 +0100 (CET) Received: from lri4-139 (lri4-139 [129.175.4.139]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ext.lri.fr (Postfix) with ESMTP id 8E700A42BA for ; Thu, 3 Dec 2009 12:01:04 +0100 (CET) Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes To: caml-list@inria.fr Subject: Re: [Caml-list] Random questions References: <91a3da520911180259s585b5ef5j311bd0448ed3c02f@mail.gmail.com> Date: Thu, 03 Dec 2009 12:00:59 +0100 MIME-Version: 1.0 Content-Transfer-Encoding: Quoted-Printable From: AUGER Organization: ProVal Message-ID: In-Reply-To: <91a3da520911180259s585b5ef5j311bd0448ed3c02f@mail.gmail.com> User-Agent: Opera Mail/10.00 (Linux) X-Spam: no; 0.00; lri:01 0100,:01 buenzli:01 bool:01 bool:01 beginner's:01 ocaml:01 bug:01 paris-sud:01 lri:01 umr:01 orsay:01 2009:98 -or-:98 beginners:01 Le Wed, 18 Nov 2009 11:59:08 +0100, Daniel B=C3=BCnzli = a =C3=A9crit: > I know little about PRGN and unfortunately in a lot of cases the > functions in the Random module don't provide me the right > interface. Could anybody tell me if the following functions preserve > the quality of the underlying PRGN and/or if there's a better way to > achieve that : > (* preliminary function: negate_minus_1 : int -> int : n |-> -n-1 *) let negate_minus_1 =3D (lor) (-(max_int/2)-1) (* or inline the constant = *) > 1) Generate an arbitrary int > > let rint () =3D Random.bits () lor ((Random.bits () land 1) lsl 30) It seems ok to me even if this variant seems slightly more efficient, since we don't have to bother with making a single bit; note the use of the xor instead of the or, which keeps the probability o= f = one bit to 1/2 (in your example, this probability was kept since one of the bit was = forced to be 0): let rint () =3D (Random.bits () lsl 1) lxor (Random.bits ());; -or- let rint () =3D let r =3D Random.bits () in if Random.bool () then negate_minus_1 r (* or inline negate_minus= _1 = *) else r note these functions don't rely on the fact ints are on 31 bits if Random.bool is more efficient than Random.bits, the latter seems the = = best; to be benchmarked... > > > 2) Generate an arbitrary int in [0;max] (bounds included) > > let random_uint ?(max =3D max_int) =3D > if max < 0 then invalid_arg "negative max" else > if max =3D max_int then Random.bits else > let bound =3D max + 1 in > fun () -> Random.int bound Seems correct. I don't know if use of exception is more efficient or not, it is to try:= let random_uint ?(max =3D max_int) () =3D try if max =3D max_int then Random.bits () else Random.int (max + 1) with Invalid_argument "Random.int" -> invalid_arg "negative max" > > > 3) Generate an arbitrary int in [-max;max] (bounds included) > > let random_int ?(max =3D max_int) =3D > if max < 0 then invalid_arg "negative max" else > if max =3D max_int then > let rec aux () =3D > let v =3D rint () in if v =3D min_int then aux () else v in > aux > else > let bound =3D (2 * max) + 1 in > if 0 < bound && bound < max_int then > fun () -> -max + Random.int bound > else > let bound =3D Int32.add (Int32.mul 2l (Int32.of_int max)) 1l in > let min =3D Int32.of_int (-max) in > fun () -> Int32.to_int (Int32.add min (Random.int32 bound)) > > I think it is better to use the bool trick; simpler and doesn't use Int32: let random_int ?(max =3D max_int) =3D if max < 0 then invalid_arg "negative max" else if max =3D 0 then 0 else if Random.bool () then if max =3D max_int then Random.bits () else Random.int max else negate_minus_1 (Random.int (max - 1)) (* inline? *) > 5) Generate an arbitrary float in [0;max] (bounds included) > > let after_one =3D 1. +. epsilon_float > let random_ufloat ?(max =3D max_float) =3D > if max < 0. then invalid_arg "negative max" else > fun () -> (Random.float after_one) *. max This function is less interesting than Random.float: only less or as many as values as floats in [0.;1.] can be generated so you will miss many values only to be able to produce max (for example, you cannot 1+eps if you try random_ufloat ~max:2. ()) The best would be to have a succ function for floats > > > 6) Generate an arbitrary float in [-max;max] (bounds included) > > let after_one =3D 1. +. epsilon_float > let random_float ?(max =3D max_float) =3D > if max < 0. then invalid_arg "negative max" else > fun () -> (-1. +. (Random.float after_one) *. 2.) *. max > same remark > > Thanks for your answers, > > Daniel > > _______________________________________________ > Caml-list mailing list. Subscription management: > http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list > Archives: http://caml.inria.fr > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs -- = C=C3=A9dric AUGER Univ Paris-Sud, Laboratoire LRI, UMR 8623, F-91405, Orsay