From issues-return-69190-archive-asf-public=cust-asf.ponee.io@commons.apache.org Thu Aug 16 01:08:07 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 046CB18067A for ; Thu, 16 Aug 2018 01:08:06 +0200 (CEST) Received: (qmail 75513 invoked by uid 500); 15 Aug 2018 23:08:03 -0000 Mailing-List: contact issues-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: issues@commons.apache.org Delivered-To: mailing list issues@commons.apache.org Received: (qmail 75418 invoked by uid 99); 15 Aug 2018 23:08:03 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 15 Aug 2018 23:08:03 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 2CC2C1A2C65 for ; Wed, 15 Aug 2018 23:08:03 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -110.301 X-Spam-Level: X-Spam-Status: No, score=-110.301 tagged_above=-999 required=6.31 tests=[ENV_AND_HDR_SPF_MATCH=-0.5, RCVD_IN_DNSWL_MED=-2.3, SPF_PASS=-0.001, USER_IN_DEF_SPF_WL=-7.5, USER_IN_WHITELIST=-100] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id 7pnhUBmFK5zb for ; Wed, 15 Aug 2018 23:08:02 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with ESMTP id 307735F4A9 for ; Wed, 15 Aug 2018 23:08:01 +0000 (UTC) Received: from jira-lw-us.apache.org (unknown [207.244.88.139]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 613A7E1013 for ; Wed, 15 Aug 2018 23:08:00 +0000 (UTC) Received: from jira-lw-us.apache.org (localhost [127.0.0.1]) by jira-lw-us.apache.org (ASF Mail Server at jira-lw-us.apache.org) with ESMTP id 191E223F99 for ; Wed, 15 Aug 2018 23:08:00 +0000 (UTC) Date: Wed, 15 Aug 2018 23:08:00 +0000 (UTC) From: "Gilles (JIRA)" To: issues@commons.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Commented] (RNG-55) UnitSphereSampler MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 [ https://issues.apache.org/jira/browse/RNG-55?page=3Dcom.atlassian.jir= a.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=3D16581723= #comment-16581723 ]=20 Gilles commented on RNG-55: --------------------------- bq. check for zero length dimension That would be good. bq. The user will find out when they call nextVector() with an NegativeArra= ySizeException anyway. No, because zero size is allowed. bq. NormalizedGaussianSampler returns 0=20 Indeed, the implementation must check for that condition. If not fulfilled, I'd suggest to recursively call {{nextVector()}}. I'd guess that the probability of exhausting the stack is vanishingly small= . bq. infinite loop if the NormalizedGaussianSampler always returns 0 With the above fix, it cannot happen (even with a broken RNG since a {{Stac= kOverflowError}} will occur). > UnitSphereSampler > ----------------- > > Key: RNG-55 > URL: https://issues.apache.org/jira/browse/RNG-55 > Project: Commons RNG > Issue Type: Bug > Components: sampling > Affects Versions: 1.1 > Reporter: Alex D Herbert > Priority: Trivial > > The {{UnitSphereSampler}}=C2=A0does not check for zero length dimension. = This doesn't cause a fail but maybe should be raised as an error? The user = will find out when they call {{nextVector()}} with an {{NegativeArraySizeEx= ception}} anyway. > However the algorithm can fail under the extremely unlikely condition tha= t the {{NormalizedGaussianSampler}} returns {{0}} for each dimension. This = is more likely when using {{dimension=3D=3D1}}. > The returned vector will be {{Double.NaN}} for each dimension due to the = use of {{1 / Math.sqrt(0)}}: > {code:java} > // f will be Double.POSITIVE_INFINITY > final double f =3D 1 / Math.sqrt(normSq); > for (int i =3D 0; i < dimension; i++) { > // v will be Double.NaN as 0 * Double.POSITIVE_INFINITY is Double.NaN > v[i] *=3D f; > } > {code} > Here is a test that demonstrates it. All it requires in the RNG to provid= e a long of 0 to the internal {{ZigguratNormalizedGaussianSampler}}: > {code:java} > @Test > public void testBadRNG() { > final UniformRandomProvider rng =3D new UniformRandomProvider() { > public long nextLong(long n) { return 0; } > public long nextLong() { return 0; } > public int nextInt(int n) { return 0; } > public int nextInt() { return 0; } > public float nextFloat() { return 0; } > public double nextDouble() { return 0;} > public void nextBytes(byte[] bytes, int start, int len) {} > public void nextBytes(byte[] bytes) {} > public boolean nextBoolean() { return false; } > }; > UnitSphereSampler s =3D new UnitSphereSampler(1, rng); > double[] v =3D s.nextVector(); > Assert.assertNotNull(v); > Assert.assertEquals(1, v.length); > Assert.assertTrue(Double.isNaN(v[0])); > } > {code} > This can be fixed by an outer loop: > {code:java} > /** > * @return a random normalized Cartesian vector. > */ > public double[] nextVector() { > final double[] v =3D new double[dimension]; > // Pick a point by choosing a standard Gaussian for each element, > // and then normalize to unit length. > double normSq =3D 0; > while (normSq =3D=3D 0) { > for (int i =3D 0; i < dimension; i++) { > final double comp =3D sampler.sample(); > v[i] =3D comp; > normSq +=3D comp * comp; > } > } > final double f =3D 1 / Math.sqrt(normSq); > for (int i =3D 0; i < dimension; i++) { > v[i] *=3D f; > } > return v; > } > {code} > But this can then infinite loop if the {{NormalizedGaussianSampler}} alwa= ys returns 0 (as for the dummy test case above). > Q. What is the lesser evil of a vector with NaN (as with the current impl= ementation) or never returning in an extreme edge case? > Throwing an exception would change the API. > Returning the vector [1,0,0,....] would fix the edge case but not alert t= he user to a broken RNG: > {code:java} > /** > * @return a random normalized Cartesian vector. > */ > public double[] nextVector() { > final double[] v =3D new double[dimension]; > // Pick a point by choosing a standard Gaussian for each element, > // and then normalize to unit length. > double normSq =3D 0; > for (int i =3D 0; i < dimension; i++) { > final double comp =3D sampler.sample(); > v[i] =3D comp; > normSq +=3D comp * comp; > } > =20 > if (normSq =3D=3D 0) { > // Extreme edge case > if (dimension !=3D 0) > v[0] =3D 1; > return v; > } > final double f =3D 1 / Math.sqrt(normSq); > for (int i =3D 0; i < dimension; i++) { > v[i] *=3D f; > } > return v; > } > {code} > This is all extremely unlikely however I noticed as I was reviewing new c= lasses in V1.1 and saw this problem that I have hit before in a random walk= simulation. -- This message was sent by Atlassian JIRA (v7.6.3#76005)