From 9dc5e564ed00586598981ed961adf9739d199f16 Mon Sep 17 00:00:00 2001 From: CyrilFerlicot Date: Mon, 13 Mar 2023 15:50:24 +0100 Subject: [PATCH 1/4] Fix two random failing tests by using a random generator with a fixed seed Fixes #298 --- .../PMIterativeProcess.class.st | 3 +- .../PMFunctionOptimizer.class.st | 7 +- .../PMOneVariableFunctionOptimizer.class.st | 84 ++++++++++++------- .../PMOptimizingBracketFinder.class.st | 32 ++++--- .../PMSimplexOptimizer.class.st | 41 +++++---- .../PMNumericalMethodsTestCase.class.st | 4 +- 6 files changed, 105 insertions(+), 66 deletions(-) diff --git a/src/Math-Core-Process/PMIterativeProcess.class.st b/src/Math-Core-Process/PMIterativeProcess.class.st index 827d374d9..0df1697e8 100644 --- a/src/Math-Core-Process/PMIterativeProcess.class.st +++ b/src/Math-Core-Process/PMIterativeProcess.class.st @@ -82,8 +82,7 @@ PMIterativeProcess >> initialize [ super initialize. desiredPrecision := self class defaultPrecision. - maximumIterations := self class defaultMaximumIterations. - ^ self + maximumIterations := self class defaultMaximumIterations ] { #category : #operation } diff --git a/src/Math-Numerical/PMFunctionOptimizer.class.st b/src/Math-Numerical/PMFunctionOptimizer.class.st index d27bfaf34..bd1067f96 100644 --- a/src/Math-Numerical/PMFunctionOptimizer.class.st +++ b/src/Math-Numerical/PMFunctionOptimizer.class.st @@ -60,9 +60,10 @@ PMFunctionOptimizer >> initialValue: aVector [ { #category : #initialization } PMFunctionOptimizer >> initialize [ - "Private" - bestPoints := SortedCollection sortBlock: [ :a :b | a betterThan: b]. - ^super initialize + "Private" + + super initialize. + bestPoints := SortedCollection sortBlock: [ :a :b | a betterThan: b ] ] { #category : #initialization } diff --git a/src/Math-Numerical/PMOneVariableFunctionOptimizer.class.st b/src/Math-Numerical/PMOneVariableFunctionOptimizer.class.st index c4a4644a1..b97dee913 100644 --- a/src/Math-Numerical/PMOneVariableFunctionOptimizer.class.st +++ b/src/Math-Numerical/PMOneVariableFunctionOptimizer.class.st @@ -1,6 +1,9 @@ Class { #name : #PMOneVariableFunctionOptimizer, #superclass : #PMFunctionOptimizer, + #instVars : [ + 'randomGenerator' + ], #classVars : [ 'GoldenSection' ], @@ -24,69 +27,86 @@ PMOneVariableFunctionOptimizer class >> goldenSection [ { #category : #operation } PMOneVariableFunctionOptimizer >> computeInitialValues [ - [ bestPoints size > 3] whileTrue: [ bestPoints removeLast]. - bestPoints size = 3 - ifTrue: [ self hasBracketingPoints - ifFalse:[ bestPoints removeLast]. - ]. - bestPoints size < 3 - ifTrue: [ ( PMOptimizingBracketFinder forOptimizer: self) evaluate] + | finder | + [ bestPoints size > 3 ] whileTrue: [ bestPoints removeLast ]. + + bestPoints size = 3 ifTrue: [ self hasBracketingPoints ifFalse: [ bestPoints removeLast ] ]. + + bestPoints size < 3 ifFalse: [ ^ self ]. + + finder := PMOptimizingBracketFinder forOptimizer: self. + self randomGenerator ifNotNil: [ :generator | finder randomGenerator: generator ]. + finder evaluate ] { #category : #information } PMOneVariableFunctionOptimizer >> computePrecision [ - ^self precisionOf: ( ( bestPoints at: 2) position - ( bestPoints at: 3) position) abs - relativeTo: ( bestPoints at: 1) position abs + + ^ self precisionOf: ((bestPoints at: 2) position - (bestPoints at: 3) position) abs relativeTo: (bestPoints at: 1) position abs ] { #category : #operation } PMOneVariableFunctionOptimizer >> evaluateIteration [ + self addPointAt: self nextXValue. bestPoints removeAt: self indexOfOuterPoint. - ^self computePrecision + ^ self computePrecision ] { #category : #information } PMOneVariableFunctionOptimizer >> hasBracketingPoints [ - "Private" + "Private" + | x1 | - x1 := ( bestPoints at: 1) position. - ^( ( bestPoints at: 2) position - x1) * (( bestPoints at: 3) position - x1) < 0 + x1 := (bestPoints at: 1) position. + ^ (bestPoints at: 2) position - x1 * ((bestPoints at: 3) position - x1) < 0 ] { #category : #information } PMOneVariableFunctionOptimizer >> indexOfOuterPoint [ - "Private" + "Private" + | inferior superior x | inferior := false. superior := false. x := bestPoints first position. - 2 to: 4 do: - [ :n | - ( bestPoints at: n) position < x - ifTrue: [ inferior - ifTrue: [ ^n]. - inferior := true. - ] - ifFalse:[ superior - ifTrue: [ ^n]. - superior := true. - ]. - ] + 2 to: 4 do: [ :n | + (bestPoints at: n) position < x + ifTrue: [ + inferior ifTrue: [ ^ n ]. + inferior := true ] + ifFalse: [ + superior ifTrue: [ ^ n ]. + superior := true ] ] ] { #category : #information } PMOneVariableFunctionOptimizer >> nextXValue [ "Private" + | d3 d2 x1 | - x1 := ( bestPoints at: 1) position. - d2 := ( bestPoints at: 2) position - x1. - d3 := ( bestPoints at: 3) position - x1. - ^( d3 abs > d2 abs ifTrue: [ d3] - ifFalse:[ d2]) * self class goldenSection + x1 + x1 := (bestPoints at: 1) position. + d2 := (bestPoints at: 2) position - x1. + d3 := (bestPoints at: 3) position - x1. + ^ (d3 abs > d2 abs + ifTrue: [ d3 ] + ifFalse: [ d2 ]) * self class goldenSection + x1 +] + +{ #category : #accessing } +PMOneVariableFunctionOptimizer >> randomGenerator [ + + ^ randomGenerator +] + +{ #category : #accessing } +PMOneVariableFunctionOptimizer >> randomGenerator: anObject [ + + randomGenerator := anObject ] { #category : #transformation } PMOneVariableFunctionOptimizer >> reset [ - [ bestPoints isEmpty] whileFalse: [ bestPoints removeLast] + + bestPoints removeAll ] diff --git a/src/Math-Numerical/PMOptimizingBracketFinder.class.st b/src/Math-Numerical/PMOptimizingBracketFinder.class.st index 6ceb5fe4a..a7cc95e04 100644 --- a/src/Math-Numerical/PMOptimizingBracketFinder.class.st +++ b/src/Math-Numerical/PMOptimizingBracketFinder.class.st @@ -12,23 +12,20 @@ PMOptimizingBracketFinder class >> initialPoints: aSortedCollection function: aF { #category : #operation } PMOptimizingBracketFinder >> computeInitialValues [ - | random | - random := Random new. - [ bestPoints size < 2 ] whileTrue: [ - self addPointAt: random next ] + [ bestPoints size < 2 ] whileTrue: [ self addPointAt: self randomGenerator next ] ] { #category : #operation } PMOptimizingBracketFinder >> evaluateIteration [ + | x1 x2 | - x1 := ( bestPoints at: 1) position. - x2 := ( bestPoints at: 2) position. - self addPointAt: ( x1 * 3 - ( x2 * 2)). - precision := ( x2 - x1) * ( ( bestPoints at: 3) position - x1). - self hasConverged - ifFalse:[ bestPoints removeLast]. - ^precision + x1 := (bestPoints at: 1) position. + x2 := (bestPoints at: 2) position. + self addPointAt: x1 * 3 - (x2 * 2). + precision := x2 - x1 * ((bestPoints at: 3) position - x1). + self hasConverged ifFalse: [ bestPoints removeLast ]. + ^ precision ] { #category : #operation } @@ -36,15 +33,24 @@ PMOptimizingBracketFinder >> finalizeIterations [ result := bestPoints ] +{ #category : #initialization } +PMOptimizingBracketFinder >> initialize [ + + super initialize. + self randomGenerator: Random new +] + { #category : #initialization } PMOptimizingBracketFinder >> initializeForOptimizer: aFunctionOptimizer [ - "Private" + "Private" + super initializeForOptimizer: aFunctionOptimizer. bestPoints := aFunctionOptimizer bestPoints ] { #category : #initialization } PMOptimizingBracketFinder >> setInitialPoints: aSortedCollection [ - "Private" + "Private" + bestPoints := aSortedCollection ] diff --git a/src/Math-Numerical/PMSimplexOptimizer.class.st b/src/Math-Numerical/PMSimplexOptimizer.class.st index 5e62cd7ac..63c9ad7fc 100644 --- a/src/Math-Numerical/PMSimplexOptimizer.class.st +++ b/src/Math-Numerical/PMSimplexOptimizer.class.st @@ -2,7 +2,8 @@ Class { #name : #PMSimplexOptimizer, #superclass : #PMFunctionOptimizer, #instVars : [ - 'worstVector' + 'worstVector', + 'randomGenerator' ], #category : #'Math-Numerical-Math-FunctionIterator' } @@ -18,26 +19,24 @@ PMSimplexOptimizer >> buildInitialSimplex [ "Private" | projectedFunction finder partialResult | - projectedFunction := PMProjectedOneVariableFunction - function: functionBlock. + projectedFunction := PMProjectedOneVariableFunction function: functionBlock. finder := PMOneVariableFunctionOptimizer forOptimizer: self. + self randomGenerator ifNotNil: [ :generator | finder randomGenerator: generator ]. finder setFunction: projectedFunction. - [bestPoints size < (result size + 1)] whileTrue: - [projectedFunction - setArgument: result; - bumpIndex. - partialResult := finder - reset; - evaluate. - bestPoints add: (optimizingPointClass - vector: (projectedFunction argumentWith: partialResult) - function: functionBlock)] + [ bestPoints size < (result size + 1) ] whileTrue: [ + projectedFunction + setArgument: result; + bumpIndex. + partialResult := finder + reset; + evaluate. + bestPoints add: (optimizingPointClass vector: (projectedFunction argumentWith: partialResult) function: functionBlock) ] ] { #category : #initialization } PMSimplexOptimizer >> computeInitialValues [ - bestPoints - add: (optimizingPointClass vector: result function: functionBlock). + + bestPoints add: (optimizingPointClass vector: result function: functionBlock). self buildInitialSimplex. worstVector := bestPoints removeLast position ] @@ -106,3 +105,15 @@ PMSimplexOptimizer >> printOn: aStream [ aStream cr. worstVector printOn: aStream ] + +{ #category : #accessing } +PMSimplexOptimizer >> randomGenerator [ + + ^ randomGenerator +] + +{ #category : #accessing } +PMSimplexOptimizer >> randomGenerator: anObject [ + + randomGenerator := anObject +] diff --git a/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st b/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st index c2ae5b139..e76c622da 100644 --- a/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st +++ b/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st @@ -819,6 +819,7 @@ PMNumericalMethodsTestCase >> testOptimizeOneDimension [ | distr finder maximum | distr := PMGammaDistribution shape: 2 scale: 5. finder := PMOneVariableFunctionOptimizer maximizingFunction: distr. + finder randomGenerator: (Random seed: 42). finder desiredPrecision: 1.0e-6. maximum := finder evaluate. self assert: (maximum - 5) abs < 1.0e-6. @@ -848,8 +849,9 @@ PMNumericalMethodsTestCase >> testOptimizeSimplex [ | fBlock simplex educatedGuess result | fBlock := [ :x | (x * x) negated exp ]. - educatedGuess := #(0.5 1.0 0.5) asPMVector. + educatedGuess := #( 0.5 1.0 0.5 ) asPMVector. simplex := PMSimplexOptimizer maximizingFunction: fBlock. + simplex randomGenerator: (Random seed: 42). simplex initialValue: educatedGuess. simplex desiredPrecision: 1.0e-6. result := simplex evaluate. From a2e4237a41c920cbdbf569f55e499c4909eba934 Mon Sep 17 00:00:00 2001 From: CyrilFerlicot Date: Mon, 13 Mar 2023 16:18:40 +0100 Subject: [PATCH 2/4] Fix a bunch of new random failing tests FIxes #300 Fixes #306 --- .../PMAnotherChromosomeManager.class.st | 80 +++--- .../PMAnotherGeneticOptimizer.class.st | 13 +- .../PMErrorMinimizer.class.st | 5 +- src/Math-FunctionFit/PMFunctionFit.class.st | 7 +- .../PMGeneralFunctionFit.class.st | 83 +++--- .../PMAnotherChromosomeManagerTest.class.st | 248 ++++++++++-------- .../PMAnotherGeneticOptimizerTest.class.st | 153 +++++------ .../PMGeneralFunctionFitTest.class.st | 96 ++++--- 8 files changed, 377 insertions(+), 308 deletions(-) diff --git a/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st b/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st index 43dc664b6..8bda83a96 100644 --- a/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st +++ b/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st @@ -8,7 +8,8 @@ Class { #instVars : [ 'hammersley', 'rateOfLC', - 'rateOfEir' + 'rateOfEir', + 'randomGenerator' ], #classVars : [ 'Primes' @@ -33,28 +34,29 @@ PMAnotherChromosomeManager class >> integerDigitsFor: anInteger base: aBase [ ] { #category : #utilities } -PMAnotherChromosomeManager class >> numberOfHamersleyPoints: n dimension: d randomized: aBoolean [ +PMAnotherChromosomeManager class >> numberOfHamersleyPoints: n dimension: d randomGenerator: randomGenerator [ "a bit randomized " - | dist randomNumberGenerator | + + | dist | dist := 1.0 / n. - randomNumberGenerator := Random new. - - ^(1 to: n) collect: [ :number | - (1 to: d) collect: [ :dim | - (dim=1) - ifTrue: [ aBoolean - ifTrue: [ (number/n) - (randomNumberGenerator nextBetween: 0 and: dist) ] - ifFalse: [ number/n ] ] - ifFalse: [ |sum prime| - sum := 0. - prime := Primes at: dim - 1. - - (self integerDigitsFor: number base: prime) reverse withIndexDo: [ :i :index | - sum := i / (prime raisedToInteger: index) + sum ]. - - aBoolean - ifTrue: [ sum + (randomNumberGenerator nextBetween: 0 and: dist) ] - ifFalse: [ sum ] ] ]]. + + ^ (1 to: n) collect: [ :number | + (1 to: d) collect: [ :dim | + dim = 1 + ifTrue: [ + randomGenerator + ifNotNil: [ number / n - (randomGenerator nextBetween: 0 and: dist) ] + ifNil: [ number / n ] ] + ifFalse: [ + | sum prime | + sum := 0. + prime := Primes at: dim - 1. + + (self integerDigitsFor: number base: prime) reverse withIndexDo: [ :i :index | sum := i / (prime raisedToInteger: index) + sum ]. + + randomGenerator + ifNotNil: [ sum + (randomGenerator nextBetween: 0 and: dist) ] + ifNil: [ sum ] ] ] ] ] { #category : #'instance creation' } @@ -108,14 +110,15 @@ PMAnotherChromosomeManager >> eirCrossover: aChromosome1 and: aChromosome2 [ { #category : #initialization } PMAnotherChromosomeManager >> initialize [ -super initialize . -populationSize :=100. -hammersley :=true. -rateOfEir :=0.16. -rateOfLC:=0.29. -rateOfMutation :=0.4. -rateOfCrossover :=0.15. -Primes ifNil:[Primes :=Integer primesUpTo: 500]. "sufficient for up to 95 dimensions (parameters)" + + super initialize. + populationSize := 100. + hammersley := true. + rateOfEir := 0.16. + rateOfLC := 0.29. + rateOfMutation := 0.4. + rateOfCrossover := 0.15. + Primes ifNil: [ Primes := Integer primesUpTo: 500 ] "sufficient for up to 95 dimensions (parameters)" ] { #category : #information } @@ -205,6 +208,18 @@ PMAnotherChromosomeManager >> process: aChromosome1 and: aChromosome2 [ add: (self clone: aChromosome2)]]]] ] +{ #category : #accessing } +PMAnotherChromosomeManager >> randomGenerator [ + + ^ randomGenerator +] + +{ #category : #accessing } +PMAnotherChromosomeManager >> randomGenerator: anObject [ + + randomGenerator := anObject +] + { #category : #private } PMAnotherChromosomeManager >> randomRangeAt: aPosition [ ^(range at: aPosition )*(self smallDistribution ) @@ -212,9 +227,10 @@ PMAnotherChromosomeManager >> randomRangeAt: aPosition [ { #category : #operation } PMAnotherChromosomeManager >> randomizePopulation [ -hammersley ifFalse: [^super randomizePopulation ]. -population :=self class numberOfHamersleyPoints: populationSize dimension: origin size randomized: true. -population := population collect: [:aChr| aChr *range +origin ] + + hammersley ifFalse: [ ^ super randomizePopulation ]. + population := self class numberOfHamersleyPoints: populationSize dimension: origin size randomGenerator: (self randomGenerator ifNil: [ Random new ]). + population := population collect: [ :aChr | aChr * range + origin ] ] { #category : #accessing } diff --git a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st index 2e28abb6f..74cbe1198 100644 --- a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st +++ b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st @@ -95,7 +95,8 @@ PMAnotherGeneticOptimizer >> computePrecision: whateverData [ "can be changed t { #category : #operation } PMAnotherGeneticOptimizer >> evaluate [ -^Cursor wait showWhile: [super evaluate] + + ^ Cursor wait showWhile: [ super evaluate ] ] { #category : #operation } @@ -129,12 +130,12 @@ statistics :=false { #category : #operation } PMAnotherGeneticOptimizer >> initializeIterations [ - bestPoints size>=chromosomeManager populationSize - ifTrue: [bestPoints := bestPoints copyFrom: 1 to: (bestPoints size // 2 max: 1)]. + + bestPoints size >= chromosomeManager populationSize ifTrue: [ bestPoints := bestPoints copyFrom: 1 to: (bestPoints size // 2 max: 1) ]. super initializeIterations. - bestValueHistory:=OrderedCollection new. - worstValueHistory:=OrderedCollection new. - whateverHistory:=OrderedCollection new + bestValueHistory := OrderedCollection new. + worstValueHistory := OrderedCollection new. + whateverHistory := OrderedCollection new ] { #category : #operation } diff --git a/src/Math-FunctionFit/PMErrorMinimizer.class.st b/src/Math-FunctionFit/PMErrorMinimizer.class.st index 9b60de6af..2c36806ff 100644 --- a/src/Math-FunctionFit/PMErrorMinimizer.class.st +++ b/src/Math-FunctionFit/PMErrorMinimizer.class.st @@ -29,6 +29,7 @@ PMErrorMinimizer class >> function: aBlock data: aCollection [ { #category : #accessing } PMErrorMinimizer >> maxFunction [ -"The number of data partitions used." -^dataHolder size + "The number of data partitions used." + + ^ dataHolder size ] diff --git a/src/Math-FunctionFit/PMFunctionFit.class.st b/src/Math-FunctionFit/PMFunctionFit.class.st index a271ef4ac..9a76a2f72 100644 --- a/src/Math-FunctionFit/PMFunctionFit.class.st +++ b/src/Math-FunctionFit/PMFunctionFit.class.st @@ -43,7 +43,12 @@ PMFunctionFit >> accumulate: aWeightedPoint [ { #category : #operation } PMFunctionFit >> computeChanges [ - ^[super computeChanges]on: PMSingularMatrixError do:[:signal|signal messageText: 'singular error matrix, set better parameters'.signal pass] + + ^ [ super computeChanges ] + on: PMSingularMatrixError + do: [ :signal | + signal messageText: 'singular error matrix, set better parameters'. + signal pass ] ] { #category : #information } diff --git a/src/Math-FunctionFit/PMGeneralFunctionFit.class.st b/src/Math-FunctionFit/PMGeneralFunctionFit.class.st index 586011d56..4187f79f0 100644 --- a/src/Math-FunctionFit/PMGeneralFunctionFit.class.st +++ b/src/Math-FunctionFit/PMGeneralFunctionFit.class.st @@ -10,14 +10,14 @@ Class { #name : #PMGeneralFunctionFit, #superclass : #Object, #instVars : [ - 'go', 'manager', 'errorFunction', 'result', 'firstResult', 'verbose', 'data', - 'dataTruncated' + 'dataTruncated', + 'geneticOptimizer' ], #category : #'Math-FunctionFit' } @@ -92,27 +92,31 @@ self resetResult. { #category : #operation } PMGeneralFunctionFit >> evaluate [ -|ff| -ff :=PMErrorMinimizer function: errorFunction. -firstResult :=[ff evaluate .ff parameters] - onErrorDo: [ verbose ifTrue: [self inform: 'ErrorMinimizer was not successful']. nil]. -firstResult ifNotNil: [go addPointAt: firstResult] . -firstResult := go evaluate . -self errorType =#squared - ifTrue: [ff :=PMFunctionFit function: errorFunction function data: errorFunction data ]. -ff parameters: firstResult. -ff desiredPrecision: PMFloatingPointMachine new machinePrecision. -ff maximumIterations: 1000 . -result:=[ff evaluate .ff parameters] - onErrorDo: [ - verbose ifTrue: [self inform: 'last FunctionFit was not successful']. - ff result parameters]. -((errorFunction value: result) > (errorFunction value: firstResult)) ifTrue:[ - ff:=result. - result :=firstResult. - firstResult :=ff. - verbose ifTrue: [self inform: 'first result was better than final result' ] ]. -^result + + | ff | + ff := PMErrorMinimizer function: errorFunction. + firstResult := [ + ff evaluate. + ff parameters ] onErrorDo: [ + verbose ifTrue: [ self inform: 'ErrorMinimizer was not successful' ]. + nil ]. + firstResult ifNotNil: [ geneticOptimizer addPointAt: firstResult ]. + firstResult := geneticOptimizer evaluate. + self errorType = #squared ifTrue: [ ff := PMFunctionFit function: errorFunction function data: errorFunction data ]. + ff parameters: firstResult. + ff desiredPrecision: PMFloatingPointMachine new machinePrecision. + ff maximumIterations: 1000. + result := [ + ff evaluate. + ff parameters ] onErrorDo: [ + verbose ifTrue: [ self inform: 'last FunctionFit was not successful' ]. + ff result parameters ]. + (errorFunction value: result) > (errorFunction value: firstResult) ifTrue: [ + ff := result. + result := firstResult. + firstResult := ff. + verbose ifTrue: [ self inform: 'first result was better than final result' ] ]. + ^ result ] { #category : #operation } @@ -165,16 +169,19 @@ errorFunction function: aBlock { #category : #initialization } PMGeneralFunctionFit >> initialize [ -super initialize . -errorFunction :=PMErrorOfParameterFunction new. -manager :=PMAnotherChromosomeManager new. -manager populationSize: 50. -go :=PMAnotherGeneticOptimizer minimizingFunction: errorFunction . -go chromosomeManager: manager. -go maximumIterations: 170. -self errorType: #squared. -verbose:=false. -dataTruncated :=false + + super initialize. + errorFunction := PMErrorOfParameterFunction new. + manager := PMAnotherChromosomeManager new + populationSize: 50; + yourself. + geneticOptimizer := (PMAnotherGeneticOptimizer minimizingFunction: errorFunction) + chromosomeManager: manager; + maximumIterations: 170; + yourself. + self errorType: #squared. + verbose := false. + dataTruncated := false ] { #category : #accessing } @@ -186,7 +193,7 @@ PMGeneralFunctionFit >> manager [ { #category : #accessing } PMGeneralFunctionFit >> maximumIterations: anInteger [ "default is 170." -go maximumIterations: anInteger. +geneticOptimizer maximumIterations: anInteger. ^anInteger ] @@ -207,7 +214,7 @@ manager range: (array2 - array1) { #category : #accessing } PMGeneralFunctionFit >> optimizer [ "if you want to change parameters of AnotherGeneticOptimizer not directly available in GeneralFunctionFit" -^go +^geneticOptimizer ] { #category : #accessing } @@ -221,7 +228,7 @@ manager populationSize: anInteger . { #category : #accessing } PMGeneralFunctionFit >> precision [ "not really useful to look at, you might better look at #error" -^go precision +^geneticOptimizer precision ] { #category : #printing } @@ -230,7 +237,7 @@ PMGeneralFunctionFit >> printOn: aStream [ nextPutAll: 'a '; nextPutAll: self class name; nextPut: $(; - print: go; + print: geneticOptimizer; nextPutAll: ' with data of size: '; print: data size . dataTruncated ifTrue: @@ -272,7 +279,7 @@ self data: data PMGeneralFunctionFit >> resetResult [ result :=nil. firstResult :=nil. -go resetBestPoints +geneticOptimizer resetBestPoints ] { #category : #accessing } diff --git a/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st b/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st index 9918eac11..50152d1c4 100644 --- a/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st +++ b/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st @@ -2,21 +2,21 @@ Class { #name : #PMAnotherChromosomeManagerTest, #superclass : #TestCase, #instVars : [ - 'cm' + 'chromosomeManager' ], #category : #'Math-Tests-FunctionFit' } { #category : #running } PMAnotherChromosomeManagerTest >> setHammersleyTest: aBoolean [ - cm useHammersley: aBoolean. - cm randomizePopulation. - self assert: cm isFullyPopulated. - self assert: (cm population anySatisfy: [ :g | g first > 1 ]). - self assert: (cm population anySatisfy: [ :g | g first < 1 ]). - self assert: (cm population anySatisfy: [ :g | g second < 2 ]). - self assert: (cm population anySatisfy: [ :g | g second > 3 ]). - cm population + chromosomeManager useHammersley: aBoolean. + chromosomeManager randomizePopulation. + self assert: chromosomeManager isFullyPopulated. + self assert: (chromosomeManager population anySatisfy: [ :g | g first > 1 ]). + self assert: (chromosomeManager population anySatisfy: [ :g | g first < 1 ]). + self assert: (chromosomeManager population anySatisfy: [ :g | g second < 2 ]). + self assert: (chromosomeManager population anySatisfy: [ :g | g second > 3 ]). + chromosomeManager population do: [ :i | self assert: i size equals: 2. self assert: (i first between: 0 and: 2). @@ -27,14 +27,15 @@ PMAnotherChromosomeManagerTest >> setHammersleyTest: aBoolean [ PMAnotherChromosomeManagerTest >> setUp [ super setUp. - cm := PMAnotherChromosomeManager origin: #( 0 1 ) range: #( 2 3 ) + chromosomeManager := PMAnotherChromosomeManager origin: #( 0 1 ) range: #( 2 3 ). + chromosomeManager randomGenerator: (Random seed: 42) ] { #category : #tests } PMAnotherChromosomeManagerTest >> testAccessing [ - self assert: cm range equals: #(2 3). - self assert: cm populationSize equals: 100. - self deny: cm isFullyPopulated + self assert: chromosomeManager range equals: #(2 3). + self assert: chromosomeManager populationSize equals: 100. + self deny: chromosomeManager isFullyPopulated ] { #category : #tests } @@ -42,7 +43,7 @@ PMAnotherChromosomeManagerTest >> testCrossOver [ | a | 1 to: 20 do: [ :i | - a := cm crossover: #( 1 2 3 ) and: #( 4 5 6 ). + a := chromosomeManager crossover: #( 1 2 3 ) and: #( 4 5 6 ). 1 to: 2 do: [ :index | self assert: (#( 1 4 ) includes: (a at: index) first). self assert: (#( 2 5 ) includes: ((a at: index) at: 2)). @@ -58,7 +59,7 @@ PMAnotherChromosomeManagerTest >> testCrossOver [ { #category : #tests } PMAnotherChromosomeManagerTest >> testEirCrossOver [ |a| -a :=(1 to: 200)collect: [:i| a:=cm eirCrossover: #(1.0 3.0) and: #(5.0 1.0). +a :=(1 to: 200)collect: [:i| a:=chromosomeManager eirCrossover: #(1.0 3.0) and: #(5.0 1.0). self assert: (((a at: 1)at:1) between: -1 and: 7). self assert: (((a at: 1)at:2) between: 0 and: 4). self assert: (((a at: 2)at:1) between: -1 and: 3). @@ -72,8 +73,8 @@ self assert: (a anySatisfy: [:g|((g at: 2)at:1)<0]). self assert: (a anySatisfy: [:g|((g at: 2)at:1)>2]). self assert: (a anySatisfy: [:g|((g at: 2)at:2)<3]). self assert: (a anySatisfy: [:g|((g at: 2)at:2)>3]). -self shouldnt: [a:=cm eirCrossover: #(1 -3) and: #(1 -3)] raise: Error. -(1 to: 20)do: [:i| a:=cm eirCrossover: #(-1.0 -1) and: #(1 1.0). +self shouldnt: [a:=chromosomeManager eirCrossover: #(1 -3) and: #(1 -3)] raise: Error. +(1 to: 20)do: [:i| a:=chromosomeManager eirCrossover: #(-1.0 -1) and: #(1 1.0). self assert: (((a at: 1)at:1) between: -2 and: 2). self assert: (((a at: 1)at:2) between: -2 and: 2). self assert: (((a at: 2)at:1) between: -2 and: 0). @@ -100,34 +101,107 @@ PMAnotherChromosomeManagerTest >> testIntegerDigits [ equals: #(1 4 4) ] +{ #category : #tests } +PMAnotherChromosomeManagerTest >> testLineCrossOver [ + | a | + 1 to: 10 do: [ :i | + a := chromosomeManager lineCrossOver: #(-2 2) and: #(-4 4). + self assert: ((a at: 1) at: 2) equals: ((a at: 1) at: 1) negated. + self assert: ((a at: 2) at: 2) equals: ((a at: 2) at: 1) negated ] +] + { #category : #tests } PMAnotherChromosomeManagerTest >> testMutateProbabilistic [ -|a f s| -a:=(1 to: 100)collect: [:i| cm mutate: #(-4 4)]. -f:=a collect: [:i|i first]. -s :=f select:[:i|i>(-4)]. -self assert: (s size between: 15 and: 60). -s :=f select:[:i|i=(-4)]. -self assert: (s size >20). -s :=f select:[:i|i>(-3.8)or:[i<(-4.2)]]. -self assert: (s size between: 3 and: 20). -s :=f select:[:i|i>(-3.9)or:[i<(-4.1)]]. -self assert: (s size between: 6 and: 50). - -f:=a collect: [:i|i second ]. -s :=f select:[:i|i>(4)]. -self assert: (s size between: 15 and: 60). -s :=f select:[:i|i=(4)]. -self assert: (s size >20). -s :=f select:[:i|i<(3.8)or:[i>(4.2)]]. -self assert: (s size between: 3 and: 20) + + | a f s | + a := (1 to: 100) collect: [ :i | chromosomeManager mutate: #( -4 4 ) ]. + f := a collect: [ :i | i first ]. + s := f select: [ :i | i > -4 ]. + self assert: (s size between: 15 and: 60). + s := f select: [ :i | i = -4 ]. + self assert: s size > 20. + s := f select: [ :i | i > -3.8 or: [ i < -4.2 ] ]. + self assert: (s size between: 3 and: 20). + s := f select: [ :i | i > -3.9 or: [ i < -4.1 ] ]. + self assert: (s size between: 6 and: 50). + + f := a collect: [ :i | i second ]. + s := f select: [ :i | i > 4 ]. + self assert: (s size between: 15 and: 60). + s := f select: [ :i | i = 4 ]. + self assert: s size > 20. + s := f select: [ :i | i < 3.8 or: [ i > 4.2 ] ]. + self assert: (s size between: 3 and: 20) +] + +{ #category : #tests } +PMAnotherChromosomeManagerTest >> testNumberOfHamersleyPoints [ + + | rand | + self + assert: (PMAnotherChromosomeManager numberOfHamersleyPoints: 9 dimension: 1 randomGenerator: nil) + equals: ((1 to: 9) collect: [ :i | Array with: i * (1 / 9) ]). + self assert: (PMAnotherChromosomeManager numberOfHamersleyPoints: 9 dimension: 4 randomGenerator: nil) equals: (OrderedCollection new + add: (Array + with: 1 / 9 + with: 1 / 2 + with: 1 / 3 + with: 1 / 5); + add: (Array + with: 2 / 9 + with: 1 / 4 + with: 2 / 3 + with: 2 / 5); + add: (Array + with: 1 / 3 + with: 3 / 4 + with: 1 / 9 + with: 3 / 5); + add: (Array + with: 4 / 9 + with: 1 / 8 + with: 4 / 9 + with: 4 / 5); + add: (Array + with: 5 / 9 + with: 5 / 8 + with: 7 / 9 + with: 1 / 25); + add: (Array + with: 2 / 3 + with: 3 / 8 + with: 2 / 9 + with: 6 / 25); + add: (Array + with: 7 / 9 + with: 7 / 8 + with: 5 / 9 + with: 11 / 25); + add: (Array + with: 8 / 9 + with: 1 / 16 + with: 8 / 9 + with: 16 / 25); + add: (Array + with: 1 + with: 9 / 16 + with: 1 / 27 + with: 21 / 25); + asArray). + rand := (PMAnotherChromosomeManager numberOfHamersleyPoints: 3 dimension: 4 randomGenerator: nil) + - (PMAnotherChromosomeManager numberOfHamersleyPoints: 3 dimension: 4 randomGenerator: (Random seed: 42)). + rand do: [ :i | + self assert: i first >= 0. + self assert: (i at: 2) < 0. + self assert: (i at: 3) < 0 ]. + rand do: [ :i | i do: [ :j | j < (1 / 3) ] ] ] { #category : #tests } PMAnotherChromosomeManagerTest >> testPrint [ |aStream s| aStream :=ReadWriteStream with:''. -cm printOn: aStream . +chromosomeManager printOn: aStream . s :=aStream contents . self assert: (s includesSubstring: '#(0 1)'). self assert: (s includesSubstring: '#(2 3)') @@ -135,13 +209,13 @@ self assert: (s includesSubstring: '#(2 3)') { #category : #tests } PMAnotherChromosomeManagerTest >> testProcessand [ - cm reset. - 1 to: 60 do: [ :i | cm process: #(0 0) and: #(1 1) ]. - self assert: (cm population select: [ :i | i = #(0 0) ]) size < 15. - self assert: (cm population select: [ :i | i = #(1 1) ]) size < 15. - self assert: (cm population select: [ :i | i = #(0 1) ]) size > 0. - self assert: (cm population select: [ :i | i = #(1 0) ]) size > 0. - self assert: cm population size equals: 120 + chromosomeManager reset. + 1 to: 60 do: [ :i | chromosomeManager process: #(0 0) and: #(1 1) ]. + self assert: (chromosomeManager population select: [ :i | i = #(0 0) ]) size < 15. + self assert: (chromosomeManager population select: [ :i | i = #(1 1) ]) size < 15. + self assert: (chromosomeManager population select: [ :i | i = #(0 1) ]) size > 0. + self assert: (chromosomeManager population select: [ :i | i = #(1 0) ]) size > 0. + self assert: chromosomeManager population size equals: 120 ] { #category : #tests } @@ -149,81 +223,27 @@ PMAnotherChromosomeManagerTest >> testRandomizePopulation [ | g | self setHammersleyTest: true. - g := cm population first. + g := chromosomeManager population first. self setHammersleyTest: false. - self deny: cm population first equals: g. - g := cm population first. + self deny: chromosomeManager population first equals: g. + g := chromosomeManager population first. self setHammersleyTest: false. - self deny: cm population first equals: g + self deny: chromosomeManager population first equals: g ] { #category : #tests } PMAnotherChromosomeManagerTest >> testRateSetting [ -self should: [cm rateOfLC: 1.3] raise: DomainError . -self should: [cm rateOfEir: -0.3] raise: DomainError . -self should: [cm rateOfMutation: 1.0000003] raise: DomainError . -self should: [cm rateOfCrossover: -0.0000003] raise: DomainError . -self shouldnt: [cm rateOfLC: 0] raise: Error . -self should: [cm rateOfLC: 0.33] raise: Warning . -cm rateOfLC: 0.2. -self shouldnt: [cm rateOfEir: 0.25] raise: Error . -self should: [cm rateOfEir: 0.26] raise: Warning . -self should: [cm rateOfMutation: 1] raise: Warning . +self should: [chromosomeManager rateOfLC: 1.3] raise: DomainError . +self should: [chromosomeManager rateOfEir: -0.3] raise: DomainError . +self should: [chromosomeManager rateOfMutation: 1.0000003] raise: DomainError . +self should: [chromosomeManager rateOfCrossover: -0.0000003] raise: DomainError . +self shouldnt: [chromosomeManager rateOfLC: 0] raise: Error . +self should: [chromosomeManager rateOfLC: 0.33] raise: Warning . +chromosomeManager rateOfLC: 0.2. +self shouldnt: [chromosomeManager rateOfEir: 0.25] raise: Error . +self should: [chromosomeManager rateOfEir: 0.26] raise: Warning . +self should: [chromosomeManager rateOfMutation: 1] raise: Warning . "usual floating point inaccuracies should be accepted:" -self shouldnt: [cm rateOfCrossover: 0.15000000000000001 ] raise: Warning . -self should: [cm rateOfCrossover: 0.1500001] raise: Warning -] - -{ #category : #tests } -PMAnotherChromosomeManagerTest >> testlineCrossOver [ - | a | - 1 to: 10 do: [ :i | - a := cm lineCrossOver: #(-2 2) and: #(-4 4). - self assert: ((a at: 1) at: 2) equals: ((a at: 1) at: 1) negated. - self assert: ((a at: 2) at: 2) equals: ((a at: 2) at: 1) negated ] -] - -{ #category : #tests } -PMAnotherChromosomeManagerTest >> testnumberOfHamersleyPoints [ - | rand | - self - assert: - (PMAnotherChromosomeManager - numberOfHamersleyPoints: 9 - dimension: 1 - randomized: false) - equals: ((1 to: 9) collect: [ :i | Array with: i * (1 / 9) ]). - self - assert: - (PMAnotherChromosomeManager - numberOfHamersleyPoints: 9 - dimension: 4 - randomized: false) - equals: - (OrderedCollection new - add: (Array with: (1 / 9) with: (1 / 2) with: (1 / 3) with: (1 / 5)); - add: (Array with: (2 / 9) with: (1 / 4) with: (2 / 3) with: (2 / 5)); - add: (Array with: (1 / 3) with: (3 / 4) with: (1 / 9) with: (3 / 5)); - add: (Array with: (4 / 9) with: (1 / 8) with: (4 / 9) with: (4 / 5)); - add: (Array with: (5 / 9) with: (5 / 8) with: (7 / 9) with: (1 / 25)); - add: (Array with: (2 / 3) with: (3 / 8) with: (2 / 9) with: (6 / 25)); - add: (Array with: (7 / 9) with: (7 / 8) with: (5 / 9) with: (11 / 25)); - add: (Array with: (8 / 9) with: (1 / 16) with: (8 / 9) with: (16 / 25)); - add: (Array with: 1 with: (9 / 16) with: (1 / 27) with: (21 / 25)); - asArray). - rand := (PMAnotherChromosomeManager - numberOfHamersleyPoints: 3 - dimension: 4 - randomized: false) - - - (PMAnotherChromosomeManager - numberOfHamersleyPoints: 3 - dimension: 4 - randomized: true). - rand - do: [ :i | - self assert: i first >= 0. - self assert: (i at: 2) < 0. - self assert: (i at: 3) < 0 ]. - rand do: [ :i | i do: [ :j | j < (1 / 3) ] ] +self shouldnt: [chromosomeManager rateOfCrossover: 0.15000000000000001 ] raise: Warning . +self should: [chromosomeManager rateOfCrossover: 0.1500001] raise: Warning ] diff --git a/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st b/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st index 94635e186..766a39760 100644 --- a/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st +++ b/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st @@ -2,7 +2,7 @@ Class { #name : #PMAnotherGeneticOptimizerTest, #superclass : #TestCase, #instVars : [ - 'go' + 'geneticOptimizer' ], #category : #'Math-Tests-FunctionFit' } @@ -17,49 +17,50 @@ PMAnotherGeneticOptimizerTest >> setUp [ v := x asPMVector. v * v ]. origin := #( -5 -5 -5 ). - go := PMAnotherGeneticOptimizer function: f minimumValues: origin maximumValues: origin negated. - go maximumIterations: 50. - go chromosomeManager populationSize: 20 + geneticOptimizer := PMAnotherGeneticOptimizer function: f minimumValues: origin maximumValues: origin negated. + geneticOptimizer maximumIterations: 50. + geneticOptimizer chromosomeManager populationSize: 20. + geneticOptimizer chromosomeManager randomGenerator: (Random seed: 42) ] { #category : #tests } PMAnotherGeneticOptimizerTest >> testChromosomeManager [ self - assert: go chromosomeManager class + assert: geneticOptimizer chromosomeManager class equals: PMAnotherChromosomeManager. - self assert: go chromosomeManager populationSize equals: 20 + self assert: geneticOptimizer chromosomeManager populationSize equals: 20 ] { #category : #tests } PMAnotherGeneticOptimizerTest >> testComputePrecision [ |r| -go maximumIterations: 2. -go evaluate . -r:=go computePrecision:0. -go maximumIterations: 50 . -go evaluate . -self assert: (r>go computePrecision ) +geneticOptimizer maximumIterations: 2. +geneticOptimizer evaluate . +r:=geneticOptimizer computePrecision:0. +geneticOptimizer maximumIterations: 50 . +geneticOptimizer evaluate . +self assert: (r>geneticOptimizer computePrecision ) ] { #category : #tests } PMAnotherGeneticOptimizerTest >> testEvaluate [ - go maximumIterations: 170. - go chromosomeManager populationSize: 50. - self assert: (go evaluate closeTo: #( 0 0 0 )) + geneticOptimizer maximumIterations: 170. + geneticOptimizer chromosomeManager populationSize: 50. + self assert: (geneticOptimizer evaluate closeTo: #( 0 0 0 )) ] { #category : #tests } PMAnotherGeneticOptimizerTest >> testInitializeIterations [ - self assertEmpty: go bestPoints. - go initializeIterations. - self denyEmpty: go bestPoints. - go calcStatistics: true. - go evaluate. - self denyEmpty: go bestValueHistory. - go initializeIterations. - self assertEmpty: go bestValueHistory + self assertEmpty: geneticOptimizer bestPoints. + geneticOptimizer initializeIterations. + self denyEmpty: geneticOptimizer bestPoints. + geneticOptimizer calcStatistics: true. + geneticOptimizer evaluate. + self denyEmpty: geneticOptimizer bestValueHistory. + geneticOptimizer initializeIterations. + self assertEmpty: geneticOptimizer bestValueHistory ] { #category : #tests } @@ -67,7 +68,7 @@ PMAnotherGeneticOptimizerTest >> testPrint [ | aStream s | aStream := ReadWriteStream with: ''. - go printOn: aStream. + geneticOptimizer printOn: aStream. s := aStream contents. self assert: (s includesSubstring: 'v * v'). self assert: (s includesSubstring: '50'). @@ -77,12 +78,12 @@ PMAnotherGeneticOptimizerTest >> testPrint [ { #category : #tests } PMAnotherGeneticOptimizerTest >> testRangeScale [ - go initializeIterations. - self assert: (go rangeScale first closeTo: 0.1). - self assert: (go rangeScale second closeTo: 0.19473684210526315). - go initializeIterations. - self assert: (go rangeScale first closeTo: 0.1). - self assert: (go rangeScale second closeTo: 0.19473684210526315) + geneticOptimizer initializeIterations. + self assert: (geneticOptimizer rangeScale first closeTo: 0.1). + self assert: (geneticOptimizer rangeScale second closeTo: 0.19473684210526315). + geneticOptimizer initializeIterations. + self assert: (geneticOptimizer rangeScale first closeTo: 0.1). + self assert: (geneticOptimizer rangeScale second closeTo: 0.19473684210526315) ] { #category : #tests } @@ -92,13 +93,13 @@ PMAnotherGeneticOptimizerTest >> testRangeScaleProbabilistic [ 9 timesRepeat: [ self setUp. - go maximumIterations: 500. - go rangeScale: true. - r1 := go evaluate norm. + geneticOptimizer maximumIterations: 500. + geneticOptimizer rangeScale: true. + r1 := geneticOptimizer evaluate norm. self setUp. - go maximumIterations: 500. - go rangeScale: false. - r2 := go evaluate norm. + geneticOptimizer maximumIterations: 500. + geneticOptimizer rangeScale: false. + r2 := geneticOptimizer evaluate norm. correct := r1 < r2 ifTrue: [ correct + 1 ] ifFalse: [ correct - 1 ] ]. @@ -112,13 +113,13 @@ PMAnotherGeneticOptimizerTest >> testRemoveLastProbabilistic [ 3 timesRepeat: [ self setUp. - go maximumIterations: 1000. - go removeLast: true. - r1 := go evaluate norm. + geneticOptimizer maximumIterations: 1000. + geneticOptimizer removeLast: true. + r1 := geneticOptimizer evaluate norm. self setUp. - go maximumIterations: 1000. - go removeLast: false. - r2 := go evaluate norm. + geneticOptimizer maximumIterations: 1000. + geneticOptimizer removeLast: false. + r2 := geneticOptimizer evaluate norm. correct := r1 > r2 ifTrue: [ correct + 1 ] ifFalse: [ correct - 1 ] ]. @@ -129,39 +130,39 @@ PMAnotherGeneticOptimizerTest >> testRemoveLastProbabilistic [ PMAnotherGeneticOptimizerTest >> testSteadyState [ |r1 r2| "probabilistic test. not always true" -go steadyState: false. -go maximumIterations: 1000. -r1 :=go evaluate norm. +geneticOptimizer steadyState: false. +geneticOptimizer maximumIterations: 1000. +r1 :=geneticOptimizer evaluate norm. self setUp . -go steadyState: true. -go maximumIterations: 1000. -r2 :=go evaluate norm. +geneticOptimizer steadyState: true. +geneticOptimizer maximumIterations: 1000. +r2 :=geneticOptimizer evaluate norm. self assert: (r1>r2 ) ] { #category : #tests } PMAnotherGeneticOptimizerTest >> testaddPointAt [ | b | - go chromosomeManager populationSize: 2. - go resetBestPoints. - go addPointAt: #(0 1 0). - b := go bestPoints. + geneticOptimizer chromosomeManager populationSize: 2. + geneticOptimizer resetBestPoints. + geneticOptimizer addPointAt: #(0 1 0). + b := geneticOptimizer bestPoints. self assert: b first position equals: #(0 1 0). self assert: b first value equals: 1. - go addPointAt: (Array with: 0 with: Float nan with: 0). - self assert: go bestPoints equals: b. - go addPointAt: (Array with: (0 - Float infinity) with: 0 with: 0). - self assert: go bestPoints equals: b. - go addPointAt: #(1 1 0). - b := go bestPoints. + geneticOptimizer addPointAt: (Array with: 0 with: Float nan with: 0). + self assert: geneticOptimizer bestPoints equals: b. + geneticOptimizer addPointAt: (Array with: (0 - Float infinity) with: 0 with: 0). + self assert: geneticOptimizer bestPoints equals: b. + geneticOptimizer addPointAt: #(1 1 0). + b := geneticOptimizer bestPoints. self assert: b size equals: 2. - go addPointAt: #(2 1 0). - self assert: go bestPoints equals: b. - go addPointAt: #(0 0.9 0). + geneticOptimizer addPointAt: #(2 1 0). + self assert: geneticOptimizer bestPoints equals: b. + geneticOptimizer addPointAt: #(0 0.9 0). self assert: b first position equals: #(0 0.9 0). self assert: b second position equals: #(0 1 0). "never throw away old first position" - go removeLast: true. - go addPointAt: #(0 0.89 0). + geneticOptimizer removeLast: true. + geneticOptimizer addPointAt: #(0 0.89 0). self assert: b first position equals: #(0 0.89 0). self assert: b second position equals: #(0 0.9 0) ] @@ -170,22 +171,22 @@ PMAnotherGeneticOptimizerTest >> testaddPointAt [ PMAnotherGeneticOptimizerTest >> testcalcStatistics [ | s | - go evaluate. - self assertEmpty: go bestValueHistory. - self assertEmpty: go worstValueHistory. - self assertEmpty: go whateverHistory. - go calcStatistics: true. - go evaluate. - s := go iterations. - self assert: go bestValueHistory size equals: s. - self assert: go worstValueHistory size equals: s. - self assert: go whateverHistory size equals: s + geneticOptimizer evaluate. + self assertEmpty: geneticOptimizer bestValueHistory. + self assertEmpty: geneticOptimizer worstValueHistory. + self assertEmpty: geneticOptimizer whateverHistory. + geneticOptimizer calcStatistics: true. + geneticOptimizer evaluate. + s := geneticOptimizer iterations. + self assert: geneticOptimizer bestValueHistory size equals: s. + self assert: geneticOptimizer worstValueHistory size equals: s. + self assert: geneticOptimizer whateverHistory size equals: s ] { #category : #tests } PMAnotherGeneticOptimizerTest >> testresetBestPoints [ - go evaluate. - go resetBestPoints. - self assertEmpty: go bestPoints + geneticOptimizer evaluate. + geneticOptimizer resetBestPoints. + self assertEmpty: geneticOptimizer bestPoints ] diff --git a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st index d058e1c39..69ce3c41d 100644 --- a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st +++ b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st @@ -31,10 +31,9 @@ PMGeneralFunctionFitTest >> testBasic [ data: col minimumValues: 0 maximumValues: 5. + fit manager randomGenerator: (Random seed: 42). self assert: (fit evaluate closeTo: #( 0.1 0.4 )). - (fit result - #( 0.1 0.4 )) abs - with: (fit secondaryResult - #( 0.1 0.4 )) abs - do: [ :e :s | self assert: s - e > 0 ]. + (fit result - #( 0.1 0.4 )) abs with: (fit secondaryResult - #( 0.1 0.4 )) abs do: [ :e :s | self assert: s - e > 0 ]. d := fit error: fit secondaryResult. self assert: d < 1e-5. self assert: fit error < d @@ -49,6 +48,7 @@ PMGeneralFunctionFitTest >> testFunction [ data: col minimumValues: 0 maximumValues: 5. + fit manager randomGenerator: (Random seed: 42). y := fit function value: 3 value: 0.1 value: 0.4. fit evaluate. self assert: ((fit function value: 3) closeTo: y) @@ -67,25 +67,26 @@ PMGeneralFunctionFitTest >> testManager [ { #category : #tests } PMGeneralFunctionFitTest >> testMaximumIterationsProbabilistic [ + | r correct | fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. + function: f + data: col + minimumValues: 0 + maximumValues: 5. correct := 0. fit populationSize: 20. - 7 - timesRepeat: [ - fit resetBestPoints. - fit maximumIterations: 200. - r := (fit evaluate - #(0.1 0.4)) abs. - fit resetBestPoints. - fit maximumIterations: 2. - r := (fit evaluate - #(0.1 0.4)) abs - r. - correct := ((r at: 1) > 0 or: [ (r at: 2) > 0 ]) - ifTrue: [ correct + 1 ] - ifFalse: [ correct - 1 ] ]. + fit manager randomGenerator: (Random seed: 42). + 7 timesRepeat: [ + fit resetBestPoints. + fit maximumIterations: 200. + r := (fit evaluate - #( 0.1 0.4 )) abs. + fit resetBestPoints. + fit maximumIterations: 2. + r := (fit evaluate - #( 0.1 0.4 )) abs - r. + correct := ((r at: 1) > 0 or: [ (r at: 2) > 0 ]) + ifTrue: [ correct + 1 ] + ifFalse: [ correct - 1 ] ]. self assert: correct > 0 ] @@ -103,28 +104,41 @@ PMGeneralFunctionFitTest >> testPopulationSize [ { #category : #tests } PMGeneralFunctionFitTest >> testPrecision [ -fit:=PMGeneralFunctionFit function: f data: col minimumValues: 0 maximumValues: 5 . -self assert:fit precision isNil. -fit evaluate . -self assert: (fit precision < 1e-6 ) + + fit := PMGeneralFunctionFit + function: f + data: col + minimumValues: 0 + maximumValues: 5. + fit manager randomGenerator: (Random seed: 42). + self assert: fit precision isNil. + fit evaluate. + self assert: fit precision < 1e-6 ] { #category : #tests } PMGeneralFunctionFitTest >> testPrint [ -|aStream s| -fit:=PMGeneralFunctionFit function: f data: col minimumValues: 0 maximumValues: 5 . -aStream :=ReadWriteStream with:''. -fit printOn: aStream . -s :=aStream contents . -self assert: (s includesSubstring: '(a * x) sin / (b + x squared)'). -self assert: (s includesSubstring: '#squared'). -self assert: (s includesSubstring: '81'). -self deny: (s includesSubstring: '#(0.'). -fit evaluate . -aStream :=ReadWriteStream with:''. -fit printOn: aStream . -s :=aStream contents . -self assert: (s includesSubstring: '#(0.') + + | aStream s | + fit := PMGeneralFunctionFit + function: f + data: col + minimumValues: 0 + maximumValues: 5. + + fit manager randomGenerator: (Random seed: 42). + aStream := ReadWriteStream with: ''. + fit printOn: aStream. + s := aStream contents. + self assert: (s includesSubstring: '(a * x) sin / (b + x squared)'). + self assert: (s includesSubstring: '#squared'). + self assert: (s includesSubstring: '81'). + self deny: (s includesSubstring: '#(0.'). + fit evaluate. + aStream := ReadWriteStream with: ''. + fit printOn: aStream. + s := aStream contents. + self assert: (s includesSubstring: '#(0.') ] { #category : #tests } @@ -138,6 +152,8 @@ PMGeneralFunctionFitTest >> testRelativeError [ data: col minimumValues: -6 maximumValues: 6. + + fit manager randomGenerator: (Random seed: 42). fit populationSize: 10. r := fit evaluate first. self assert: (r closeTo: 4). @@ -159,6 +175,8 @@ PMGeneralFunctionFitTest >> testResetBestPoints [ data: col minimumValues: 0 maximumValues: 5. + + fit manager randomGenerator: (Random seed: 42). fit evaluate. fit resetBestPoints. self assertEmpty: fit optimizer bestPoints @@ -175,6 +193,8 @@ PMGeneralFunctionFitTest >> testTruncate [ data: col minimumValues: 0 maximumValues: 5. + + fit manager randomGenerator: (Random seed: 42). fit errorType: #quartile. self assert: (fit findQuartile closeTo: #( 0.1 0.4 )). self assert: fit quartile < (79 / 81). @@ -182,9 +202,7 @@ PMGeneralFunctionFitTest >> testTruncate [ self deny: fit dataTruncated. fit truncateData. self assert: fit dataTruncated. - self - assert: fit optimizer functionBlock data size - equals: fit quartile * col size. + self assert: fit optimizer functionBlock data size equals: fit quartile * col size. fit errorType: #abs. self assert: fit errorType equals: #abs. self assert: (fit evaluate closeTo: #( 0.1 0.4 )). From 8f7faf6c0d97a8cf31d1ee77597ee8be6f06bd33 Mon Sep 17 00:00:00 2001 From: CyrilFerlicot Date: Mon, 13 Mar 2023 16:21:38 +0100 Subject: [PATCH 3/4] Factorize code --- .../PMGeneralFunctionFitTest.class.st | 65 ++++--------------- 1 file changed, 13 insertions(+), 52 deletions(-) diff --git a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st index 69ce3c41d..889dea20a 100644 --- a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st +++ b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st @@ -19,19 +19,20 @@ PMGeneralFunctionFitTest >> setUp [ "Reset the FloatingPointMachine to make coverage consistent" PMFloatingPointMachine reset. f := [ :x :a :b | (a * x) sin / (b + x squared) ]. - col := (-4 to: 4 by: 0.1) collect: [ :i | i @ (f cull: i cull: 0.1 cull: 0.4) ] + col := (-4 to: 4 by: 0.1) collect: [ :i | i @ (f cull: i cull: 0.1 cull: 0.4) ]. + fit := PMGeneralFunctionFit + function: f + data: col + minimumValues: 0 + maximumValues: 5. + + fit manager randomGenerator: (Random seed: 42) ] { #category : #tests } PMGeneralFunctionFitTest >> testBasic [ | d | - fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. - fit manager randomGenerator: (Random seed: 42). self assert: (fit evaluate closeTo: #( 0.1 0.4 )). (fit result - #( 0.1 0.4 )) abs with: (fit secondaryResult - #( 0.1 0.4 )) abs do: [ :e :s | self assert: s - e > 0 ]. d := fit error: fit secondaryResult. @@ -43,12 +44,6 @@ PMGeneralFunctionFitTest >> testBasic [ PMGeneralFunctionFitTest >> testFunction [ | y | - fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. - fit manager randomGenerator: (Random seed: 42). y := fit function value: 3 value: 0.1 value: 0.4. fit evaluate. self assert: ((fit function value: 3) closeTo: y) @@ -56,27 +51,17 @@ PMGeneralFunctionFitTest >> testFunction [ { #category : #tests } PMGeneralFunctionFitTest >> testManager [ - fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. + self assert: fit manager class equals: PMAnotherChromosomeManager. - self assert: fit manager range equals: #(5 5) + self assert: fit manager range equals: #( 5 5 ) ] { #category : #tests } PMGeneralFunctionFitTest >> testMaximumIterationsProbabilistic [ | r correct | - fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. correct := 0. fit populationSize: 20. - fit manager randomGenerator: (Random seed: 42). 7 timesRepeat: [ fit resetBestPoints. fit maximumIterations: 200. @@ -92,11 +77,7 @@ PMGeneralFunctionFitTest >> testMaximumIterationsProbabilistic [ { #category : #tests } PMGeneralFunctionFitTest >> testPopulationSize [ - fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. + self assert: fit manager populationSize equals: 50. fit populationSize: 100. self assert: fit manager populationSize equals: 100 @@ -105,12 +86,6 @@ PMGeneralFunctionFitTest >> testPopulationSize [ { #category : #tests } PMGeneralFunctionFitTest >> testPrecision [ - fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. - fit manager randomGenerator: (Random seed: 42). self assert: fit precision isNil. fit evaluate. self assert: fit precision < 1e-6 @@ -120,13 +95,6 @@ PMGeneralFunctionFitTest >> testPrecision [ PMGeneralFunctionFitTest >> testPrint [ | aStream s | - fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. - - fit manager randomGenerator: (Random seed: 42). aStream := ReadWriteStream with: ''. fit printOn: aStream. s := aStream contents. @@ -150,8 +118,8 @@ PMGeneralFunctionFitTest >> testRelativeError [ fit := PMGeneralFunctionFit function: f data: col - minimumValues: -6 - maximumValues: 6. + minimumValues: 0 + maximumValues: 5. fit manager randomGenerator: (Random seed: 42). fit populationSize: 10. @@ -170,13 +138,6 @@ PMGeneralFunctionFitTest >> testRelativeError [ { #category : #tests } PMGeneralFunctionFitTest >> testResetBestPoints [ - fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. - - fit manager randomGenerator: (Random seed: 42). fit evaluate. fit resetBestPoints. self assertEmpty: fit optimizer bestPoints From a697e1473de3ad6d2042adb1b66c0b11126b1154 Mon Sep 17 00:00:00 2001 From: CyrilFerlicot Date: Mon, 13 Mar 2023 16:27:27 +0100 Subject: [PATCH 4/4] Revert a change that was not suppose to happen --- src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st index 889dea20a..b87af1fea 100644 --- a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st +++ b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st @@ -118,8 +118,8 @@ PMGeneralFunctionFitTest >> testRelativeError [ fit := PMGeneralFunctionFit function: f data: col - minimumValues: 0 - maximumValues: 5. + minimumValues: -6 + maximumValues: 6. fit manager randomGenerator: (Random seed: 42). fit populationSize: 10.