From f3b94bd3264c64613c15597def735834009726aa Mon Sep 17 00:00:00 2001 From: Serge Stinckwich Date: Tue, 23 Feb 2021 12:19:26 +0800 Subject: [PATCH 1/5] Some basic cleaning on various Distributions classes --- .../PMNormalDistribution.class.st | 31 +++++++++---------- .../PMCauchyDistribution.class.st | 6 ++-- .../PMExponentialDistribution.class.st | 3 +- .../PMFisherTippettDistribution.class.st | 8 ++--- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/Math-Core-Distribution/PMNormalDistribution.class.st b/src/Math-Core-Distribution/PMNormalDistribution.class.st index e0a948d7a..151946584 100644 --- a/src/Math-Core-Distribution/PMNormalDistribution.class.st +++ b/src/Math-Core-Distribution/PMNormalDistribution.class.st @@ -8,7 +8,7 @@ Class { #classVars : [ 'NextRandom' ], - #category : 'Math-Core-Distribution' + #category : #'Math-Core-Distribution' } { #category : #information } @@ -41,20 +41,19 @@ PMNormalDistribution class >> new: aNumber1 sigma: aNumber2 [ { #category : #information } PMNormalDistribution class >> random [ "Answer a random number distributed according to a (0,1) normal distribution." + | v1 v2 w y | - NextRandom isNil - ifTrue: [ [ v1 := Number random * 2 - 1. - v2 := Number random * 2 - 1. - w := v1 squared + v2 squared. - w > 1 ] whileTrue: []. - y := ( ( w ln * 2 negated) / w) sqrt. - v1 := y * v1. - NextRandom := y * v2. - ] - ifFalse:[ v1 :=NextRandom. - NextRandom := nil. - ]. - ^v1 + NextRandom + ifNil: [ [ v1 := Number random * 2 - 1. + v2 := Number random * 2 - 1. + w := v1 squared + v2 squared. + w > 1 ] whileTrue: [ ]. + y := (w ln * 2 negated / w) sqrt. + v1 := y * v1. + NextRandom := y * v2 ] + ifNotNil: [ v1 := NextRandom. + NextRandom := nil ]. + ^ v1 ] { #category : #information } @@ -78,10 +77,8 @@ PMNormalDistribution >> distributionValue: aNumber [ { #category : #initialization } PMNormalDistribution >> initialize: aNumber1 sigma: aNumber2 [ - mu := aNumber1. - sigma := aNumber2. - ^self + sigma := aNumber2 ] { #category : #information } diff --git a/src/Math-Numerical/PMCauchyDistribution.class.st b/src/Math-Numerical/PMCauchyDistribution.class.st index 50e2bffbc..6b8d05e11 100644 --- a/src/Math-Numerical/PMCauchyDistribution.class.st +++ b/src/Math-Numerical/PMCauchyDistribution.class.st @@ -59,10 +59,10 @@ PMCauchyDistribution >> distributionValue: aNumber [ { #category : #initialization } PMCauchyDistribution >> initialize: aNumber1 scale: aNumber2 [ - "Private - Initialize the parameters of the receiver. " + "Initialize the parameters of the receiver. " + mu := aNumber1. - beta := aNumber2. - ^self + beta := aNumber2 ] { #category : #information } diff --git a/src/Math-Numerical/PMExponentialDistribution.class.st b/src/Math-Numerical/PMExponentialDistribution.class.st index 495f5e3ac..962727adb 100644 --- a/src/Math-Numerical/PMExponentialDistribution.class.st +++ b/src/Math-Numerical/PMExponentialDistribution.class.st @@ -66,8 +66,7 @@ PMExponentialDistribution >> initialize: aNumber [ aNumber > 0 ifFalse: [ self error: 'Illegal distribution parameters' ]. - beta := aNumber. - ^ self + beta := aNumber ] { #category : #information } diff --git a/src/Math-Numerical/PMFisherTippettDistribution.class.st b/src/Math-Numerical/PMFisherTippettDistribution.class.st index fa9e30269..a10cc84ad 100644 --- a/src/Math-Numerical/PMFisherTippettDistribution.class.st +++ b/src/Math-Numerical/PMFisherTippettDistribution.class.st @@ -68,12 +68,12 @@ PMFisherTippettDistribution >> distributionValue: aNumber [ { #category : #initialization } PMFisherTippettDistribution >> initialize: aNumber1 scale: aNumber2 [ - "Private - Initialize the parameters of the receiver." + "Initialize the parameters of the receiver." + aNumber2 > 0 - ifFalse: [ self error: 'Illegal distribution parameters']. + ifFalse: [ self error: 'Illegal distribution parameters' ]. alpha := aNumber1. - beta := aNumber2. - ^self + beta := aNumber2 ] { #category : #information } From df0a1a8d923bd704e3c0d07119115a88ff491c9f Mon Sep 17 00:00:00 2001 From: Serge Stinckwich Date: Tue, 23 Feb 2021 16:51:50 +0800 Subject: [PATCH 2/5] =?UTF-8?q?-=20Remove=20whileTrue:[]=C2=A0and=20whileF?= =?UTF-8?q?alse:=20[]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PMNormalDistribution.class.st | 2 +- .../PMFisherTippettDistribution.class.st | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Math-Core-Distribution/PMNormalDistribution.class.st b/src/Math-Core-Distribution/PMNormalDistribution.class.st index 151946584..981416d2e 100644 --- a/src/Math-Core-Distribution/PMNormalDistribution.class.st +++ b/src/Math-Core-Distribution/PMNormalDistribution.class.st @@ -47,7 +47,7 @@ PMNormalDistribution class >> random [ ifNil: [ [ v1 := Number random * 2 - 1. v2 := Number random * 2 - 1. w := v1 squared + v2 squared. - w > 1 ] whileTrue: [ ]. + w > 1 ] whileTrue. y := (w ln * 2 negated / w) sqrt. v1 := y * v1. NextRandom := y * v2 ] diff --git a/src/Math-Numerical/PMFisherTippettDistribution.class.st b/src/Math-Numerical/PMFisherTippettDistribution.class.st index a10cc84ad..39a78a546 100644 --- a/src/Math-Numerical/PMFisherTippettDistribution.class.st +++ b/src/Math-Numerical/PMFisherTippettDistribution.class.st @@ -70,8 +70,8 @@ PMFisherTippettDistribution >> distributionValue: aNumber [ PMFisherTippettDistribution >> initialize: aNumber1 scale: aNumber2 [ "Initialize the parameters of the receiver." - aNumber2 > 0 - ifFalse: [ self error: 'Illegal distribution parameters' ]. + aNumber2 <= 0 + ifTrue: [ self error: 'Illegal distribution parameters' ]. alpha := aNumber1. beta := aNumber2 ] @@ -104,11 +104,12 @@ PMFisherTippettDistribution >> parameters [ { #category : #information } PMFisherTippettDistribution >> random [ - "Answer a random number distributed according to the receiver." + "Answer a random number distributed according to the receiver." + | t | [ t := flatGenerator floatValue ln negated. - t > 0] whileFalse: []. - ^t ln negated * beta + alpha + t > 0 ] whileFalse. + ^ t ln negated * beta + alpha ] { #category : #information } From 2b89664f185c1736aee20a0d5946e25dd8664b0f Mon Sep 17 00:00:00 2001 From: Serge Stinckwich Date: Tue, 23 Feb 2021 17:24:07 +0800 Subject: [PATCH 3/5] Typos/fix comment --- .../PMNormalDistribution.class.st | 5 +++-- src/Math-Numerical/Number.extension.st | 13 +++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Math-Core-Distribution/PMNormalDistribution.class.st b/src/Math-Core-Distribution/PMNormalDistribution.class.st index 981416d2e..962e9e2f4 100644 --- a/src/Math-Core-Distribution/PMNormalDistribution.class.st +++ b/src/Math-Core-Distribution/PMNormalDistribution.class.st @@ -95,8 +95,9 @@ PMNormalDistribution >> parameters [ { #category : #information } PMNormalDistribution >> random [ - "Answer a random number distributed accroding to the receiver." - ^self class random * sigma + mu + "Answer a random number distributed according to the receiver." + + ^ self class random * sigma + mu ] { #category : #information } diff --git a/src/Math-Numerical/Number.extension.st b/src/Math-Numerical/Number.extension.st index 31ef61b6a..a16408381 100644 --- a/src/Math-Numerical/Number.extension.st +++ b/src/Math-Numerical/Number.extension.st @@ -70,15 +70,16 @@ Number >> productWithVector: aVector [ ] { #category : #'*Math-Numerical' } -Number >> random [ - "Answers a random number distributed between 0 and the receiver." - ^self class random * self +Number class >> random [ + "Answers a floating random number between 0 and 1 excluded" + + ^ PMMitchellMooreGenerator new floatValue ] { #category : #'*Math-Numerical' } -Number class >> random [ - "Answers a random number between 0 and the receiver." - ^ PMMitchellMooreGenerator new floatValue +Number >> random [ + "Answers a random number distributed between 0 and the receiver." + ^self class random * self ] { #category : #'*Math-Numerical' } From c83319df450cf869cd892c7d48a95a0e04e76982 Mon Sep 17 00:00:00 2001 From: Serge Stinckwich Date: Tue, 23 Feb 2021 20:44:06 +0800 Subject: [PATCH 4/5] Ad d a comment about Box-Muller transform --- src/Math-Core-Distribution/PMNormalDistribution.class.st | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Math-Core-Distribution/PMNormalDistribution.class.st b/src/Math-Core-Distribution/PMNormalDistribution.class.st index 962e9e2f4..9a418b6e3 100644 --- a/src/Math-Core-Distribution/PMNormalDistribution.class.st +++ b/src/Math-Core-Distribution/PMNormalDistribution.class.st @@ -44,7 +44,9 @@ PMNormalDistribution class >> random [ | v1 v2 w y | NextRandom - ifNil: [ [ v1 := Number random * 2 - 1. + ifNil: [ + "Use Box-Muller transform" + [ v1 := Number random * 2 - 1. v2 := Number random * 2 - 1. w := v1 squared + v2 squared. w > 1 ] whileTrue. From ea87d33b1fb1957ef03a01e283346dd66f0e4ee1 Mon Sep 17 00:00:00 2001 From: Serge Stinckwich Date: Tue, 23 Feb 2021 21:31:07 +0800 Subject: [PATCH 5/5] Extract boxMullerTransform to be more intuition revealing --- .../PMNormalDistribution.class.st | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Math-Core-Distribution/PMNormalDistribution.class.st b/src/Math-Core-Distribution/PMNormalDistribution.class.st index 9a418b6e3..bced833aa 100644 --- a/src/Math-Core-Distribution/PMNormalDistribution.class.st +++ b/src/Math-Core-Distribution/PMNormalDistribution.class.st @@ -11,6 +11,19 @@ Class { #category : #'Math-Core-Distribution' } +{ #category : #information } +PMNormalDistribution class >> boxMullerTransform [ +|v1 v2 w y| + [ v1 := Number random * 2 - 1. + v2 := Number random * 2 - 1. + w := v1 squared + v2 squared. + w > 1 ] whileTrue. + y := (w ln * 2 negated / w) sqrt. + v1 := y * v1. + NextRandom := y * v2. + ^v1. +] + { #category : #information } PMNormalDistribution class >> distributionName [ @@ -42,17 +55,11 @@ PMNormalDistribution class >> new: aNumber1 sigma: aNumber2 [ PMNormalDistribution class >> random [ "Answer a random number distributed according to a (0,1) normal distribution." - | v1 v2 w y | + | v1 | NextRandom ifNil: [ - "Use Box-Muller transform" - [ v1 := Number random * 2 - 1. - v2 := Number random * 2 - 1. - w := v1 squared + v2 squared. - w > 1 ] whileTrue. - y := (w ln * 2 negated / w) sqrt. - v1 := y * v1. - NextRandom := y * v2 ] + + v1 := self boxMullerTransform ] ifNotNil: [ v1 := NextRandom. NextRandom := nil ]. ^ v1