Skip to content

Commit 9dc5e56

Browse files
committed
Fix two random failing tests by using a random generator with a fixed seed
Fixes #298
1 parent 770f386 commit 9dc5e56

File tree

6 files changed

+105
-66
lines changed

6 files changed

+105
-66
lines changed

src/Math-Core-Process/PMIterativeProcess.class.st

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,7 @@ PMIterativeProcess >> initialize [
8282
super initialize.
8383

8484
desiredPrecision := self class defaultPrecision.
85-
maximumIterations := self class defaultMaximumIterations.
86-
^ self
85+
maximumIterations := self class defaultMaximumIterations
8786
]
8887

8988
{ #category : #operation }

src/Math-Numerical/PMFunctionOptimizer.class.st

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ PMFunctionOptimizer >> initialValue: aVector [
6060

6161
{ #category : #initialization }
6262
PMFunctionOptimizer >> initialize [
63-
"Private"
64-
bestPoints := SortedCollection sortBlock: [ :a :b | a betterThan: b].
65-
^super initialize
63+
"Private"
64+
65+
super initialize.
66+
bestPoints := SortedCollection sortBlock: [ :a :b | a betterThan: b ]
6667
]
6768

6869
{ #category : #initialization }
Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
Class {
22
#name : #PMOneVariableFunctionOptimizer,
33
#superclass : #PMFunctionOptimizer,
4+
#instVars : [
5+
'randomGenerator'
6+
],
47
#classVars : [
58
'GoldenSection'
69
],
@@ -24,69 +27,86 @@ PMOneVariableFunctionOptimizer class >> goldenSection [
2427
{ #category : #operation }
2528
PMOneVariableFunctionOptimizer >> computeInitialValues [
2629

27-
[ bestPoints size > 3] whileTrue: [ bestPoints removeLast].
28-
bestPoints size = 3
29-
ifTrue: [ self hasBracketingPoints
30-
ifFalse:[ bestPoints removeLast].
31-
].
32-
bestPoints size < 3
33-
ifTrue: [ ( PMOptimizingBracketFinder forOptimizer: self) evaluate]
30+
| finder |
31+
[ bestPoints size > 3 ] whileTrue: [ bestPoints removeLast ].
32+
33+
bestPoints size = 3 ifTrue: [ self hasBracketingPoints ifFalse: [ bestPoints removeLast ] ].
34+
35+
bestPoints size < 3 ifFalse: [ ^ self ].
36+
37+
finder := PMOptimizingBracketFinder forOptimizer: self.
38+
self randomGenerator ifNotNil: [ :generator | finder randomGenerator: generator ].
39+
finder evaluate
3440
]
3541

3642
{ #category : #information }
3743
PMOneVariableFunctionOptimizer >> computePrecision [
38-
^self precisionOf: ( ( bestPoints at: 2) position - ( bestPoints at: 3) position) abs
39-
relativeTo: ( bestPoints at: 1) position abs
44+
45+
^ self precisionOf: ((bestPoints at: 2) position - (bestPoints at: 3) position) abs relativeTo: (bestPoints at: 1) position abs
4046
]
4147

4248
{ #category : #operation }
4349
PMOneVariableFunctionOptimizer >> evaluateIteration [
50+
4451
self addPointAt: self nextXValue.
4552
bestPoints removeAt: self indexOfOuterPoint.
46-
^self computePrecision
53+
^ self computePrecision
4754
]
4855

4956
{ #category : #information }
5057
PMOneVariableFunctionOptimizer >> hasBracketingPoints [
51-
"Private"
58+
"Private"
59+
5260
| x1 |
53-
x1 := ( bestPoints at: 1) position.
54-
^( ( bestPoints at: 2) position - x1) * (( bestPoints at: 3) position - x1) < 0
61+
x1 := (bestPoints at: 1) position.
62+
^ (bestPoints at: 2) position - x1 * ((bestPoints at: 3) position - x1) < 0
5563
]
5664

5765
{ #category : #information }
5866
PMOneVariableFunctionOptimizer >> indexOfOuterPoint [
59-
"Private"
67+
"Private"
68+
6069
| inferior superior x |
6170
inferior := false.
6271
superior := false.
6372
x := bestPoints first position.
64-
2 to: 4 do:
65-
[ :n |
66-
( bestPoints at: n) position < x
67-
ifTrue: [ inferior
68-
ifTrue: [ ^n].
69-
inferior := true.
70-
]
71-
ifFalse:[ superior
72-
ifTrue: [ ^n].
73-
superior := true.
74-
].
75-
]
73+
2 to: 4 do: [ :n |
74+
(bestPoints at: n) position < x
75+
ifTrue: [
76+
inferior ifTrue: [ ^ n ].
77+
inferior := true ]
78+
ifFalse: [
79+
superior ifTrue: [ ^ n ].
80+
superior := true ] ]
7681
]
7782

7883
{ #category : #information }
7984
PMOneVariableFunctionOptimizer >> nextXValue [
8085
"Private"
86+
8187
| d3 d2 x1 |
82-
x1 := ( bestPoints at: 1) position.
83-
d2 := ( bestPoints at: 2) position - x1.
84-
d3 := ( bestPoints at: 3) position - x1.
85-
^( d3 abs > d2 abs ifTrue: [ d3]
86-
ifFalse:[ d2]) * self class goldenSection + x1
88+
x1 := (bestPoints at: 1) position.
89+
d2 := (bestPoints at: 2) position - x1.
90+
d3 := (bestPoints at: 3) position - x1.
91+
^ (d3 abs > d2 abs
92+
ifTrue: [ d3 ]
93+
ifFalse: [ d2 ]) * self class goldenSection + x1
94+
]
95+
96+
{ #category : #accessing }
97+
PMOneVariableFunctionOptimizer >> randomGenerator [
98+
99+
^ randomGenerator
100+
]
101+
102+
{ #category : #accessing }
103+
PMOneVariableFunctionOptimizer >> randomGenerator: anObject [
104+
105+
randomGenerator := anObject
87106
]
88107

89108
{ #category : #transformation }
90109
PMOneVariableFunctionOptimizer >> reset [
91-
[ bestPoints isEmpty] whileFalse: [ bestPoints removeLast]
110+
111+
bestPoints removeAll
92112
]

src/Math-Numerical/PMOptimizingBracketFinder.class.st

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,39 +12,45 @@ PMOptimizingBracketFinder class >> initialPoints: aSortedCollection function: aF
1212

1313
{ #category : #operation }
1414
PMOptimizingBracketFinder >> computeInitialValues [
15-
| random |
16-
random := Random new.
1715

18-
[ bestPoints size < 2 ] whileTrue: [
19-
self addPointAt: random next ]
16+
[ bestPoints size < 2 ] whileTrue: [ self addPointAt: self randomGenerator next ]
2017
]
2118

2219
{ #category : #operation }
2320
PMOptimizingBracketFinder >> evaluateIteration [
21+
2422
| x1 x2 |
25-
x1 := ( bestPoints at: 1) position.
26-
x2 := ( bestPoints at: 2) position.
27-
self addPointAt: ( x1 * 3 - ( x2 * 2)).
28-
precision := ( x2 - x1) * ( ( bestPoints at: 3) position - x1).
29-
self hasConverged
30-
ifFalse:[ bestPoints removeLast].
31-
^precision
23+
x1 := (bestPoints at: 1) position.
24+
x2 := (bestPoints at: 2) position.
25+
self addPointAt: x1 * 3 - (x2 * 2).
26+
precision := x2 - x1 * ((bestPoints at: 3) position - x1).
27+
self hasConverged ifFalse: [ bestPoints removeLast ].
28+
^ precision
3229
]
3330

3431
{ #category : #operation }
3532
PMOptimizingBracketFinder >> finalizeIterations [
3633
result := bestPoints
3734
]
3835

36+
{ #category : #initialization }
37+
PMOptimizingBracketFinder >> initialize [
38+
39+
super initialize.
40+
self randomGenerator: Random new
41+
]
42+
3943
{ #category : #initialization }
4044
PMOptimizingBracketFinder >> initializeForOptimizer: aFunctionOptimizer [
41-
"Private"
45+
"Private"
46+
4247
super initializeForOptimizer: aFunctionOptimizer.
4348
bestPoints := aFunctionOptimizer bestPoints
4449
]
4550

4651
{ #category : #initialization }
4752
PMOptimizingBracketFinder >> setInitialPoints: aSortedCollection [
48-
"Private"
53+
"Private"
54+
4955
bestPoints := aSortedCollection
5056
]

src/Math-Numerical/PMSimplexOptimizer.class.st

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ Class {
22
#name : #PMSimplexOptimizer,
33
#superclass : #PMFunctionOptimizer,
44
#instVars : [
5-
'worstVector'
5+
'worstVector',
6+
'randomGenerator'
67
],
78
#category : #'Math-Numerical-Math-FunctionIterator'
89
}
@@ -18,26 +19,24 @@ PMSimplexOptimizer >> buildInitialSimplex [
1819
"Private"
1920

2021
| projectedFunction finder partialResult |
21-
projectedFunction := PMProjectedOneVariableFunction
22-
function: functionBlock.
22+
projectedFunction := PMProjectedOneVariableFunction function: functionBlock.
2323
finder := PMOneVariableFunctionOptimizer forOptimizer: self.
24+
self randomGenerator ifNotNil: [ :generator | finder randomGenerator: generator ].
2425
finder setFunction: projectedFunction.
25-
[bestPoints size < (result size + 1)] whileTrue:
26-
[projectedFunction
27-
setArgument: result;
28-
bumpIndex.
29-
partialResult := finder
30-
reset;
31-
evaluate.
32-
bestPoints add: (optimizingPointClass
33-
vector: (projectedFunction argumentWith: partialResult)
34-
function: functionBlock)]
26+
[ bestPoints size < (result size + 1) ] whileTrue: [
27+
projectedFunction
28+
setArgument: result;
29+
bumpIndex.
30+
partialResult := finder
31+
reset;
32+
evaluate.
33+
bestPoints add: (optimizingPointClass vector: (projectedFunction argumentWith: partialResult) function: functionBlock) ]
3534
]
3635

3736
{ #category : #initialization }
3837
PMSimplexOptimizer >> computeInitialValues [
39-
bestPoints
40-
add: (optimizingPointClass vector: result function: functionBlock).
38+
39+
bestPoints add: (optimizingPointClass vector: result function: functionBlock).
4140
self buildInitialSimplex.
4241
worstVector := bestPoints removeLast position
4342
]
@@ -106,3 +105,15 @@ PMSimplexOptimizer >> printOn: aStream [
106105
aStream cr.
107106
worstVector printOn: aStream
108107
]
108+
109+
{ #category : #accessing }
110+
PMSimplexOptimizer >> randomGenerator [
111+
112+
^ randomGenerator
113+
]
114+
115+
{ #category : #accessing }
116+
PMSimplexOptimizer >> randomGenerator: anObject [
117+
118+
randomGenerator := anObject
119+
]

src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ PMNumericalMethodsTestCase >> testOptimizeOneDimension [
819819
| distr finder maximum |
820820
distr := PMGammaDistribution shape: 2 scale: 5.
821821
finder := PMOneVariableFunctionOptimizer maximizingFunction: distr.
822+
finder randomGenerator: (Random seed: 42).
822823
finder desiredPrecision: 1.0e-6.
823824
maximum := finder evaluate.
824825
self assert: (maximum - 5) abs < 1.0e-6.
@@ -848,8 +849,9 @@ PMNumericalMethodsTestCase >> testOptimizeSimplex [
848849

849850
| fBlock simplex educatedGuess result |
850851
fBlock := [ :x | (x * x) negated exp ].
851-
educatedGuess := #(0.5 1.0 0.5) asPMVector.
852+
educatedGuess := #( 0.5 1.0 0.5 ) asPMVector.
852853
simplex := PMSimplexOptimizer maximizingFunction: fBlock.
854+
simplex randomGenerator: (Random seed: 42).
853855
simplex initialValue: educatedGuess.
854856
simplex desiredPrecision: 1.0e-6.
855857
result := simplex evaluate.

0 commit comments

Comments
 (0)