From 820655f7566d8f532820fdb99e6ff57382ac7b29 Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Wed, 25 Mar 2026 16:20:21 +0100 Subject: [PATCH 1/5] fixed printOn: methods --- .../CleanBlockClosure.extension.st | 7 ++ src/Math-FunctionFit/Collection.extension.st | 4 +- .../PMAnotherChromosomeManager.class.st | 55 +++++++-------- .../PMAnotherGeneticOptimizer.class.st | 68 +++++++++--------- src/Math-FunctionFit/PMDataHolder.class.st | 11 +-- .../PMErrorAsParameterFunction.class.st | 21 +++--- .../PMErrorMinimizer.class.st | 13 ++-- .../PMErrorOfParameterFunction.class.st | 49 +++++++------ src/Math-FunctionFit/PMFunctionFit.class.st | 27 ++++---- src/Math-FunctionFit/PMGAAccuracy.class.st | 45 ++++++------ .../PMGeneralFunctionFit.class.st | 69 ++++++++++--------- .../PMSimpleParameterFunction.class.st | 33 ++++----- src/Math-FunctionFit/package.st | 2 +- 13 files changed, 214 insertions(+), 190 deletions(-) create mode 100644 src/Math-FunctionFit/CleanBlockClosure.extension.st diff --git a/src/Math-FunctionFit/CleanBlockClosure.extension.st b/src/Math-FunctionFit/CleanBlockClosure.extension.st new file mode 100644 index 000000000..d0fafe7c0 --- /dev/null +++ b/src/Math-FunctionFit/CleanBlockClosure.extension.st @@ -0,0 +1,7 @@ +Extension { #name : 'CleanBlockClosure' } + +{ #category : '*Math-FunctionFit' } +CleanBlockClosure >> functionString [ + + ^ self sourceNode value sourceCode asString +] diff --git a/src/Math-FunctionFit/Collection.extension.st b/src/Math-FunctionFit/Collection.extension.st index 79b3484ec..b67d8ac12 100644 --- a/src/Math-FunctionFit/Collection.extension.st +++ b/src/Math-FunctionFit/Collection.extension.st @@ -1,6 +1,6 @@ -Extension { #name : #Collection } +Extension { #name : 'Collection' } -{ #category : #'*Math-FunctionFit' } +{ #category : '*Math-FunctionFit' } Collection >> norm [ ^(self*self)sum sqrt ] diff --git a/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st b/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st index 8bda83a96..7219fd63d 100644 --- a/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st +++ b/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st @@ -3,8 +3,8 @@ AnotherChromosomeManager implements more specific operations for Floats. Is used by AnotherGeneticOptimizer " Class { - #name : #PMAnotherChromosomeManager, - #superclass : #PMVectorChromosomeManager, + #name : 'PMAnotherChromosomeManager', + #superclass : 'PMVectorChromosomeManager', #instVars : [ 'hammersley', 'rateOfLC', @@ -14,10 +14,11 @@ Class { #classVars : [ 'Primes' ], - #category : #'Math-FunctionFit' + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' } -{ #category : #utilities } +{ #category : 'utilities' } PMAnotherChromosomeManager class >> integerDigitsFor: anInteger base: aBase [ | n integer next result | "n:=(anInteger ln / aBase ln) floor ." "does not always work because of floating point errors. next 2 lines are better" @@ -33,7 +34,7 @@ PMAnotherChromosomeManager class >> integerDigitsFor: anInteger base: aBase [ ^result ] -{ #category : #utilities } +{ #category : 'utilities' } PMAnotherChromosomeManager class >> numberOfHamersleyPoints: n dimension: d randomGenerator: randomGenerator [ "a bit randomized " @@ -59,12 +60,12 @@ PMAnotherChromosomeManager class >> numberOfHamersleyPoints: n dimension: d rand ifNil: [ sum ] ] ] ] ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMAnotherChromosomeManager class >> origin: anArray range: anotherArray [ ^self new origin: anArray; range: anotherArray; yourself ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherChromosomeManager >> crossover: aChromosome1 and: aChromosome2 [ "the Discrete Recombination operator that does not prefer schemata of certain parameters based on their position" @@ -86,7 +87,7 @@ that does not prefer schemata of certain parameters based on their position" ^ Array with: new1 with: new2 ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherChromosomeManager >> eirCrossover: aChromosome1 and: aChromosome2 [ "the Extended Intermediate Recombination 0.5 operator, slightly changed to make it more similar to linecrossover (distribution is more centered around Chromosome1, which is better than C2)" | randomNumbers new1 new2 dif | @@ -108,7 +109,7 @@ PMAnotherChromosomeManager >> eirCrossover: aChromosome1 and: aChromosome2 [ ^ { new1 . new2 } ] -{ #category : #initialization } +{ #category : 'initialization' } PMAnotherChromosomeManager >> initialize [ super initialize. @@ -121,13 +122,13 @@ PMAnotherChromosomeManager >> initialize [ Primes ifNil: [ Primes := Integer primesUpTo: 500 ] "sufficient for up to 95 dimensions (parameters)" ] -{ #category : #information } +{ #category : 'information' } PMAnotherChromosomeManager >> isFullyPopulated [ population ifNil: [^false]. ^super isFullyPopulated ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherChromosomeManager >> lineCrossOver: aChromosome1 and: aChromosome2 [ "BGA Line Recombination; expects C1 to be better than C2, which is not correct at the moment, need to change that!!! mhm i think i did that." | new1 new2 line norm| @@ -140,7 +141,7 @@ PMAnotherChromosomeManager >> lineCrossOver: aChromosome1 and: aChromosome2 [ ^Array with: new1 with: new2 ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherChromosomeManager >> mutate: aVector [ "BGA mutation" | isMutated threshold new index | @@ -163,13 +164,13 @@ PMAnotherChromosomeManager >> mutate: aVector [ ^ new ] -{ #category : #accessing } +{ #category : 'accessing' } PMAnotherChromosomeManager >> populationSize [ "AnotherGeneticOptimizer needs these data" ^populationSize ] -{ #category : #printing } +{ #category : 'printing' } PMAnotherChromosomeManager >> printOn: aStream [ aStream nextPutAll: self class name; @@ -184,7 +185,7 @@ PMAnotherChromosomeManager >> printOn: aStream [ nextPut: $) ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherChromosomeManager >> process: aChromosome1 and: aChromosome2 [ | roll | roll := randomNumberGenerator next. @@ -208,24 +209,24 @@ PMAnotherChromosomeManager >> process: aChromosome1 and: aChromosome2 [ add: (self clone: aChromosome2)]]]] ] -{ #category : #accessing } +{ #category : 'accessing' } PMAnotherChromosomeManager >> randomGenerator [ ^ randomGenerator ] -{ #category : #accessing } +{ #category : 'accessing' } PMAnotherChromosomeManager >> randomGenerator: anObject [ randomGenerator := anObject ] -{ #category : #private } +{ #category : 'private' } PMAnotherChromosomeManager >> randomRangeAt: aPosition [ ^(range at: aPosition )*(self smallDistribution ) ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherChromosomeManager >> randomizePopulation [ hammersley ifFalse: [ ^ super randomizePopulation ]. @@ -233,53 +234,53 @@ PMAnotherChromosomeManager >> randomizePopulation [ population := population collect: [ :aChr | aChr * range + origin ] ] -{ #category : #accessing } +{ #category : 'accessing' } PMAnotherChromosomeManager >> range [ "AnotherGeneticOptimizer needs these data" ^range ] -{ #category : #initialization } +{ #category : 'initialization' } PMAnotherChromosomeManager >> rateOfCrossover: aNumber [ self testRate: aNumber oldRate: rateOfCrossover name: 'rateOfCrossover'. rateOfCrossover := aNumber ] -{ #category : #initialization } +{ #category : 'initialization' } PMAnotherChromosomeManager >> rateOfEir: aNumber [ self testRate: aNumber oldRate: rateOfEir name: 'rateOfEir'. rateOfEir := aNumber ] -{ #category : #initialization } +{ #category : 'initialization' } PMAnotherChromosomeManager >> rateOfLC: aNumber [ self testRate: aNumber oldRate: rateOfLC name: 'rateOfLC'. rateOfLC := aNumber ] -{ #category : #initialization } +{ #category : 'initialization' } PMAnotherChromosomeManager >> rateOfMutation: aNumber [ self testRate: aNumber oldRate: rateOfMutation name: 'rateOfMutation'. rateOfMutation := aNumber ] -{ #category : #private } +{ #category : 'private' } PMAnotherChromosomeManager >> smallDistribution [ "an exponential distribution as used by H. Mühlenbein" ^ 2 raisedTo: (16 * randomNumberGenerator next negated) ] -{ #category : #private } +{ #category : 'private' } PMAnotherChromosomeManager >> testRate:aFloat oldRate: asecondFloat name:aString [ (aFloat between: 0 and: 1) ifFalse: [(DomainError new)from:0;to:1;messageText: 'Value outside [0 , 1]';signalIn: thisContext sender]. (rateOfCrossover + rateOfMutation + rateOfLC + rateOfEir + aFloat - asecondFloat)>1.000000000000001 "for Float inaccuracies" ifTrue: [Warning signal:'All rates together are higher than 1, if ' , aString, ' is set to ',aFloat asString ] ] -{ #category : #initialization } +{ #category : 'initialization' } PMAnotherChromosomeManager >> useHammersley: aBoolean [ "default is true" hammersley :=aBoolean diff --git a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st index 11c9b2d7d..cd4159223 100644 --- a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st +++ b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st @@ -2,8 +2,8 @@ AnotherGeneticOptimizer is a more efficient GeneticOptimizer, that is necessary for the correct use of AnotherChromosomeManager. " Class { - #name : #PMAnotherGeneticOptimizer, - #superclass : #PMGeneticOptimizer, + #name : 'PMAnotherGeneticOptimizer', + #superclass : 'PMGeneticOptimizer', #instVars : [ 'rangeScale', 'steadyState', @@ -14,16 +14,17 @@ Class { 'whateverHistory', 'originalFunction' ], - #category : #'Math-FunctionFit' + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' } -{ #category : #information } +{ #category : 'information' } PMAnotherGeneticOptimizer class >> defaultPrecision [ ^ Float machineEpsilon ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMAnotherGeneticOptimizer class >> function: aBlock minimumValues: anArray maximumValues: anotherArray [ |o m| o:=self minimizingFunction:aBlock. @@ -38,12 +39,12 @@ m range: (anotherArray - anArray). ^o ] -{ #category : #transformation } +{ #category : 'transformation' } PMAnotherGeneticOptimizer >> add: aMinimizingPoint [ ^bestPoints add: aMinimizingPoint ] -{ #category : #transformation } +{ #category : 'transformation' } PMAnotherGeneticOptimizer >> addPointAt: aVector [ "makes room if necessary and adds point only, if there is already enough room or the bestPoints get better with the new point" @@ -57,23 +58,23 @@ if there is already enough room or the bestPoints get better with the new point ifFalse: [self add: p] ] -{ #category : #information } +{ #category : 'information' } PMAnotherGeneticOptimizer >> bestValueHistory [ ^bestValueHistory ] -{ #category : #accessing } +{ #category : 'accessing' } PMAnotherGeneticOptimizer >> calcStatistics:aBoolean [ "calc the best and the worst function return history. default is false." statistics :=aBoolean ] -{ #category : #accessing } +{ #category : 'accessing' } PMAnotherGeneticOptimizer >> chromosomeManager [ ^chromosomeManager ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherGeneticOptimizer >> collectPoints [ | size | size := steadyState @@ -85,7 +86,7 @@ PMAnotherGeneticOptimizer >> collectPoints [ result := bestPoints first position ] -{ #category : #information } +{ #category : 'information' } PMAnotherGeneticOptimizer >> computePrecision: whateverData [ "can be changed to check how the ga behaves" statistics ifTrue: [bestValueHistory add: bestPoints first value. @@ -94,20 +95,20 @@ PMAnotherGeneticOptimizer >> computePrecision: whateverData [ "can be changed t ^steadyState ifTrue: [bestPoints last value - bestPoints first value] ifFalse: [1] ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherGeneticOptimizer >> evaluate [ ^ Cursor wait showWhile: [ super evaluate ] ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherGeneticOptimizer >> evaluateIteration [ self nextGeneration. self mixupGeneration. ^ self computePrecision: bestPoints first position first ] -{ #category : #private } +{ #category : 'private' } PMAnotherGeneticOptimizer >> findNearestTo: anOptimizingPointClass [ |max dist| max:=Array with: bestPoints size with: Float infinity. @@ -120,7 +121,7 @@ PMAnotherGeneticOptimizer >> findNearestTo: anOptimizingPointClass [ ^max first ] -{ #category : #initialization } +{ #category : 'initialization' } PMAnotherGeneticOptimizer >> initialize [ super initialize . rangeScale :=true. @@ -129,7 +130,7 @@ removeLast:=false. statistics :=false ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherGeneticOptimizer >> initializeIterations [ bestPoints size >= chromosomeManager populationSize ifTrue: [ bestPoints := bestPoints copyFrom: 1 to: (bestPoints size // 2 max: 1) ]. @@ -139,7 +140,7 @@ PMAnotherGeneticOptimizer >> initializeIterations [ whateverHistory := OrderedCollection new ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherGeneticOptimizer >> mixupGeneration [ | doMixUp r r1 | r := bestPoints first value. @@ -155,7 +156,7 @@ PMAnotherGeneticOptimizer >> mixupGeneration [ self collectPoints ] ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherGeneticOptimizer >> nextGeneration [ | randomScale | randomScale := rangeScale @@ -167,15 +168,16 @@ PMAnotherGeneticOptimizer >> nextGeneration [ self collectPoints ] -{ #category : #printing } +{ #category : 'printing' } PMAnotherGeneticOptimizer >> printOn1: aStream [ + aStream nextPutAll: self class name; nextPutAll: '( function: '; - nextPutAll: originalFunction asString + nextPutAll: originalFunction functionString ] -{ #category : #printing } +{ #category : 'printing' } PMAnotherGeneticOptimizer >> printOn2: aStream [ aStream nextPutAll: ' manager: '; @@ -195,13 +197,13 @@ PMAnotherGeneticOptimizer >> printOn2: aStream [ nextPut: $) ] -{ #category : #printing } +{ #category : 'printing' } PMAnotherGeneticOptimizer >> printOn: aStream [ self printOn1: aStream. self printOn2: aStream ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherGeneticOptimizer >> processRandomParents: aNumberArray [ "puts the better chromosome at the first place (is eg necessary for lineCrossOver:and:)" | pos1 pos2 c | @@ -212,7 +214,7 @@ PMAnotherGeneticOptimizer >> processRandomParents: aNumberArray [ and: ( bestPoints at: pos2) position ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherGeneticOptimizer >> rangeScale [ "keeps constant selection pressure" | size best| @@ -221,31 +223,31 @@ best := 0.0 . ^(size to: 1 by: (-1)) collect: [:i | best := 2 * i / (size * (size + 1)) + best] ] -{ #category : #accessing } +{ #category : 'accessing' } PMAnotherGeneticOptimizer >> rangeScale: aBoolean [ "if rangeScale is false the old method of selecting an individual proportionally to its fitness is used, if it is true a constant selection pressure is used. default is true. " rangeScale :=aBoolean ] -{ #category : #accessing } +{ #category : 'accessing' } PMAnotherGeneticOptimizer >> removeLast: aBoolean [ "if steadyState is true, then either the worst individual (removeLast:true) is deleted, or the most similar to the new individual (removeLast:false) is deleted, to make room for the new one. default is false, since this keeps diversity high. But it is a bit slow" removeLast :=aBoolean ] -{ #category : #transformation } +{ #category : 'transformation' } PMAnotherGeneticOptimizer >> removeNearestTo: anOptimizingPointClass [ bestPoints removeAt: (self findNearestTo: anOptimizingPointClass) ] -{ #category : #operation } +{ #category : 'operation' } PMAnotherGeneticOptimizer >> resetBestPoints [ "for repeated evaluating with different starting populations" bestPoints := SortedCollection sortBlock: [ :a :b | a betterThan: b]. result :=nil ] -{ #category : #initialization } +{ #category : 'initialization' } PMAnotherGeneticOptimizer >> setFunction: aBlock [ ( aBlock respondsTo: #value:) ifFalse:[ self error: 'Function block must implement the method value:']. @@ -254,18 +256,18 @@ PMAnotherGeneticOptimizer >> setFunction: aBlock [ self resetBestPoints ] -{ #category : #accessing } +{ #category : 'accessing' } PMAnotherGeneticOptimizer >> steadyState: aBoolean [ "if steadyState is false, the old method of making room for new individuals after one iteration and just keeping the best so far is used. If it is true (the default), then everything is kept and only offspring that are better than the worst so far are put into the population." steadyState :=aBoolean ] -{ #category : #information } +{ #category : 'information' } PMAnotherGeneticOptimizer >> whateverHistory [ ^whateverHistory ] -{ #category : #information } +{ #category : 'information' } PMAnotherGeneticOptimizer >> worstValueHistory [ ^worstValueHistory ] diff --git a/src/Math-FunctionFit/PMDataHolder.class.st b/src/Math-FunctionFit/PMDataHolder.class.st index 2ad18edc7..4c7a7fa6c 100644 --- a/src/Math-FunctionFit/PMDataHolder.class.st +++ b/src/Math-FunctionFit/PMDataHolder.class.st @@ -2,13 +2,14 @@ DataHolder is an Array of Points and is used only internally by FunctionFit. " Class { - #name : #PMDataHolder, - #superclass : #Array, - #type : #variable, - #category : #'Math-FunctionFit' + #name : 'PMDataHolder', + #superclass : 'Array', + #type : 'variable', + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' } -{ #category : #iterators } +{ #category : 'iterators' } PMDataHolder >> pointsAndErrorsDo: aBlock [ "uses an unweighted approach; the weighted one does not make sense here and is dangerous, if done too naively, eg because of negative or infinite weights" self do: diff --git a/src/Math-FunctionFit/PMErrorAsParameterFunction.class.st b/src/Math-FunctionFit/PMErrorAsParameterFunction.class.st index 1b2087201..4731ade4b 100644 --- a/src/Math-FunctionFit/PMErrorAsParameterFunction.class.st +++ b/src/Math-FunctionFit/PMErrorAsParameterFunction.class.st @@ -2,17 +2,18 @@ ErrorAsParameterFunction is used internally by ErrorMinimizer. it is essentially a wrapper around an ErrorOfParameterFunction . " Class { - #name : #PMErrorAsParameterFunction, - #superclass : #PMSimpleParameterFunction, - #category : #'Math-FunctionFit' + #name : 'PMErrorAsParameterFunction', + #superclass : 'PMSimpleParameterFunction', + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' } -{ #category : #accessing } +{ #category : 'accessing' } PMErrorAsParameterFunction >> changeParametersBy: aVector [ varArray :=varArray + aVector ] -{ #category : #initialization } +{ #category : 'initialization' } PMErrorAsParameterFunction >> function: anErrorOfParameterFunction [ |d f size steps| d :=anErrorOfParameterFunction data. @@ -30,24 +31,24 @@ function := (0 to: steps)collect: [:i| f] ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorAsParameterFunction >> maxFunction [ "The number of data partitions used. The highest number that can be send to #value:" ^ function ifNil: [ 0 ] ifNotNil: [ :f | f size ] ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorAsParameterFunction >> parameters [ ^varArray ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorAsParameterFunction >> parameters: indexableCollection [ ^varArray :=indexableCollection copy ] -{ #category : #printing } +{ #category : 'printing' } PMErrorAsParameterFunction >> printOn: aStream [ aStream @@ -64,7 +65,7 @@ PMErrorAsParameterFunction >> printOn: aStream [ aStream nextPut: $) ] -{ #category : #evaluating } +{ #category : 'evaluating' } PMErrorAsParameterFunction >> value: aNumber [ "aNumber chooses the data partition. it can run from 1 to maxFunction." ^(function at: aNumber) value: varArray diff --git a/src/Math-FunctionFit/PMErrorMinimizer.class.st b/src/Math-FunctionFit/PMErrorMinimizer.class.st index 2c36806ff..4fddb65e2 100644 --- a/src/Math-FunctionFit/PMErrorMinimizer.class.st +++ b/src/Math-FunctionFit/PMErrorMinimizer.class.st @@ -9,12 +9,13 @@ fit evaluate . fit parameters. --> #(2.0 0.39999999999903596) " Class { - #name : #PMErrorMinimizer, - #superclass : #PMFunctionFit, - #category : #'Math-FunctionFit' + #name : 'PMErrorMinimizer', + #superclass : 'PMFunctionFit', + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' } -{ #category : #creation } +{ #category : 'creation' } PMErrorMinimizer class >> function: anErrorOfParameterFunction [ |f d| f := PMErrorAsParameterFunction function: anErrorOfParameterFunction. @@ -22,12 +23,12 @@ d :=( 1 to:( f maxFunction ))collect: [:i| i@0]. ^self new initialize: d data: f ] -{ #category : #creation } +{ #category : 'creation' } PMErrorMinimizer class >> function: aBlock data: aCollection [ ^self shouldNotImplement ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorMinimizer >> maxFunction [ "The number of data partitions used." diff --git a/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st b/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st index f318dcf20..80cb84818 100644 --- a/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st +++ b/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st @@ -3,8 +3,8 @@ ErrorOfParameterFunction wants a function with parameters as a block and a Colle ErrorOfParameterFunction>>value: anArrayOfParameters returns a sum of squared errors or similar error measures. it can be used in MultiVariableOptimizers to calculate parameters. " Class { - #name : #PMErrorOfParameterFunction, - #superclass : #Object, + #name : 'PMErrorOfParameterFunction', + #superclass : 'Object', #instVars : [ 'data', 'function', @@ -14,20 +14,21 @@ Class { 'qPosition', 'relative' ], - #category : #'Math-FunctionFit' + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMErrorOfParameterFunction class >> function: aBlock data: aCollectionOfPoints [ ^self new function: aBlock; data: aCollectionOfPoints; yourself ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> data [ ^data ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> data: aCollectionOfPoints [ "a collection of points x@f(x)" (aCollectionOfPoints isCollection and: [aCollectionOfPoints allSatisfy: [:aPoint| aPoint isPoint]]) ifFalse: @@ -38,7 +39,7 @@ quartile ifNotNil:[ self quartile: quartile] . ^data ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> errorCollection: parameters [ "returns a collection of squared errors or of abs errors" "this is used often and should and could be a bit optimized" @@ -63,12 +64,12 @@ PMErrorOfParameterFunction >> errorCollection: parameters [ ifFalse: [ err abs ] ]] ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> errorType [ ^errorType ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> errorType: aSymbol [ "valid errorTypes are: #squared, #abs, #insensitive, #quartile, #median. Default is #squared" (aSymbol isSymbol and:[#(#squared #abs #insensitive #quartile #median) includes: aSymbol]) ifFalse: @@ -78,18 +79,24 @@ aSymbol =#median ifTrue: [^errorType :=#quartile] . ^errorType :=aSymbol ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> function [ ^function ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> function: aBlock [ function :=aBlock . varArray :=Array new: aBlock numArgs ] -{ #category : #initialization } +{ #category : 'accessing' } +PMErrorOfParameterFunction >> functionString [ + + ^ self asString +] + +{ #category : 'initialization' } PMErrorOfParameterFunction >> initialize [ super initialize . relative :=false. @@ -97,21 +104,21 @@ errorType :=#squared. quartile:= 1/2 ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> parameterNames [ ^(function argumentNames collect:[:s| s asString ])allButFirst ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> parameterSize [ ^varArray size -1 ] -{ #category : #printing } +{ #category : 'printing' } PMErrorOfParameterFunction >> printOn: aStream [ super printOn: aStream. aStream - nextPutAll: '( function: '; print: function; + nextPutAll: '( function: '; print: function compiledBlock; nextPutAll: ' relativeError: '; print: relative; nextPutAll: ' errorType: '; print: errorType. (#(#quartile #insensitive) includes: errorType)ifTrue:[ @@ -119,12 +126,12 @@ PMErrorOfParameterFunction >> printOn: aStream [ aStream nextPut: $). ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> quartile [ ^quartile ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> quartile: aFloat [ "quartile: is used by errortypes #quartile and #insensitive." aFloat >1 | (aFloat <0) ifTrue:[^DomainError signal:'quartile must be between 0 and 1']. @@ -132,7 +139,7 @@ data ifNotNil: [qPosition :=(data size -1.00001 * aFloat )rounded+1]. "-1.00001 ^quartile := aFloat ] -{ #category : #evaluating } +{ #category : 'evaluating' } PMErrorOfParameterFunction >> realValue: parameters [ "returns the sqrt of the mean of the sum of squared errors, or the mean abs error, or the quartile error, or the insensitive error" |e| @@ -142,13 +149,13 @@ errorType = #squared ifTrue: [e := e sqrt] . "if relativeError=true this is not ^e ] -{ #category : #accessing } +{ #category : 'accessing' } PMErrorOfParameterFunction >> relativeError: aBoolean [ " default is false" ^relative :=aBoolean ] -{ #category : #evaluating } +{ #category : 'evaluating' } PMErrorOfParameterFunction >> value: parameters [ "returns the sum of squared errors, or the sum of abs errors, or the quartile error. insensitive is an experimental quartile error that centers a tube around its quartile and returns the (estimated) radius of the tube like quartile" diff --git a/src/Math-FunctionFit/PMFunctionFit.class.st b/src/Math-FunctionFit/PMFunctionFit.class.st index 9a76a2f72..e723fbb06 100644 --- a/src/Math-FunctionFit/PMFunctionFit.class.st +++ b/src/Math-FunctionFit/PMFunctionFit.class.st @@ -7,27 +7,28 @@ fit evaluate . fit result parameters . ---> #(1.9999999999999998 0.39999999999999863) " Class { - #name : #PMFunctionFit, - #superclass : #PMLeastSquareFit, - #category : #'Math-FunctionFit' + #name : 'PMFunctionFit', + #superclass : 'PMLeastSquareFit', + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' } -{ #category : #creation } +{ #category : 'creation' } PMFunctionFit class >> function: aBlock data: aDataHolder [ ^super points: aDataHolder function: (PMSimpleParameterFunction function: aBlock) ] -{ #category : #creation } +{ #category : 'creation' } PMFunctionFit class >> histogram: aHistogram distributionClass: aProbabilityDensityFunctionClass [ ^self shouldNotImplement ] -{ #category : #creation } +{ #category : 'creation' } PMFunctionFit class >> points: aDataHolder function: aBlock [ ^self shouldNotImplement ] -{ #category : #operation } +{ #category : 'operation' } PMFunctionFit >> accumulate: aWeightedPoint [ | f g | f := result valueAndGradient: aWeightedPoint xValue. @@ -41,7 +42,7 @@ PMFunctionFit >> accumulate: aWeightedPoint [ ] ] -{ #category : #operation } +{ #category : 'operation' } PMFunctionFit >> computeChanges [ ^ [ super computeChanges ] @@ -51,7 +52,7 @@ PMFunctionFit >> computeChanges [ signal pass ] ] -{ #category : #information } +{ #category : 'information' } PMFunctionFit >> computeChiSquare [ "does not make much sense to use in most cases, but then, the superclass has it and if its here, the calculation should be correct and the superclass's way does not work here eg because of the way DataHolder>>pointsAndErrorsDo: works" chiSquare := 0. @@ -65,7 +66,7 @@ PMFunctionFit >> computeChiSquare [ ] ] -{ #category : #initialization } +{ #category : 'initialization' } PMFunctionFit >> initialize: aDataHolder data: aParametricFunction [ (aDataHolder isCollection and: [aDataHolder allSatisfy: [:aPoint| aPoint isPoint]]) ifTrue: [dataHolder:= aDataHolder as: PMDataHolder ] @@ -76,12 +77,12 @@ PMFunctionFit >> initialize: aDataHolder data: aParametricFunction [ ^self ] -{ #category : #information } +{ #category : 'information' } PMFunctionFit >> parameters [ ^result parameters ] -{ #category : #initialization } +{ #category : 'initialization' } PMFunctionFit >> parameters: indexableCollection [ indexableCollection do: [ :e | @@ -91,7 +92,7 @@ PMFunctionFit >> parameters: indexableCollection [ self finalizeIterations ] -{ #category : #printing } +{ #category : 'printing' } PMFunctionFit >> printOn: aStream [ super printOn: aStream. aStream nextPutAll: ' for '. diff --git a/src/Math-FunctionFit/PMGAAccuracy.class.st b/src/Math-FunctionFit/PMGAAccuracy.class.st index d19eed1bb..d6c728278 100644 --- a/src/Math-FunctionFit/PMGAAccuracy.class.st +++ b/src/Math-FunctionFit/PMGAAccuracy.class.st @@ -2,15 +2,16 @@ GAAccuracy tests standard problems " Class { - #name : #PMGAAccuracy, - #superclass : #PMAccuracy, + #name : 'PMGAAccuracy', + #superclass : 'PMAccuracy', #instVars : [ 'fast' ], - #category : #'Math-FunctionFit' + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' } -{ #category : #tests } +{ #category : 'tests' } PMGAAccuracy >> checkDamavandi [ | g origin range optimizer | g := [:x| |x1 x2| @@ -25,7 +26,7 @@ PMGAAccuracy >> checkDamavandi [ ^g value: optimizer evaluate ] -{ #category : #tests } +{ #category : 'tests' } PMGAAccuracy >> checkDeVilliersGlasser2 [ | ti yi g origin range optimizer | ti := [ :x | (x - 1) / 10 ]. @@ -54,7 +55,7 @@ PMGAAccuracy >> checkDeVilliersGlasser2 [ ^ g value: optimizer evaluate ] -{ #category : #tests } +{ #category : 'tests' } PMGAAccuracy >> checkF1 [ | f origin optimizer | f := [ :x | @@ -71,7 +72,7 @@ PMGAAccuracy >> checkF1 [ ^ f value: optimizer evaluate ] -{ #category : #tests } +{ #category : 'tests' } PMGAAccuracy >> checkF2 [ | g origin optimizer r | g := [ :x | (x overlappingPairsCollect: [ :f :s | (s - f squared) squared * 100 + (1 - f) squared ]) sum ]. @@ -88,7 +89,7 @@ PMGAAccuracy >> checkF2 [ ^ r ] -{ #category : #tests } +{ #category : 'tests' } PMGAAccuracy >> checkF3 [ | g origin optimizer | g := [ :x | (x floor + 0.5) squared sum ]. @@ -105,7 +106,7 @@ PMGAAccuracy >> checkF3 [ ^ g value: optimizer evaluate ] -{ #category : #tests } +{ #category : 'tests' } PMGAAccuracy >> checkF5 [ | g origin optimizer | g := [ :x | @@ -127,7 +128,7 @@ PMGAAccuracy >> checkF5 [ ^ g value: optimizer evaluate ] -{ #category : #tests } +{ #category : 'tests' } PMGAAccuracy >> checkGriewank [ | g origin range optimizer | g := [ :x | x squared sum / 4000 - ((x withIndexCollect: [ :xi :i | (xi / i sqrt) cos ]) reduce: [ :a :b | a * b ]) + 1 ]. @@ -140,18 +141,18 @@ PMGAAccuracy >> checkGriewank [ ^ g value: optimizer evaluate ] -{ #category : #accessing } +{ #category : 'accessing' } PMGAAccuracy >> fast [ ^fast ] -{ #category : #accessing } +{ #category : 'accessing' } PMGAAccuracy >> fast: aBoolean [ "default is false" fast := aBoolean ] -{ #category : #initialization } +{ #category : 'initialization' } PMGAAccuracy >> initialize [ super initialize. fast :=false. @@ -159,51 +160,51 @@ PMGAAccuracy >> initialize [ self parameter: #(#(0.4 0.15 0.29 0.16) #(0.40 0.15 0.28 0.17)) ] -{ #category : #initialization } +{ #category : 'initialization' } PMGAAccuracy >> initializeDamavandi [ self result: 0 ] -{ #category : #initialization } +{ #category : 'initialization' } PMGAAccuracy >> initializeDeVilliersGlasser2 [ self result: 0 ] -{ #category : #initialization } +{ #category : 'initialization' } PMGAAccuracy >> initializeF1 [ self result: #((0) (0) (0)). self argument: #((4) (8) (12)) ] -{ #category : #initialization } +{ #category : 'initialization' } PMGAAccuracy >> initializeF2 [ self result: #(0 0 0) ] -{ #category : #initialization } +{ #category : 'initialization' } PMGAAccuracy >> initializeF3 [ self argument: #(#(16) #(20)). self result: #(#(4) #(5)) ] -{ #category : #initialization } +{ #category : 'initialization' } PMGAAccuracy >> initializeF5 [ self result: 0.99800383779444 ] -{ #category : #initialization } +{ #category : 'initialization' } PMGAAccuracy >> initializeGriewank [ self result: 0 ] -{ #category : #running } +{ #category : 'running' } PMGAAccuracy >> runFast [ "fast is an euphemism here, but at least its fast to type" fast := true. ^ self run: #('F1' 'F2' 'F3' 'F5' 'Griewank') ] -{ #category : #running } +{ #category : 'running' } PMGAAccuracy >> setManager:aManager with: rates [ "set everything to zero first, so that you dont get warnings" aManager diff --git a/src/Math-FunctionFit/PMGeneralFunctionFit.class.st b/src/Math-FunctionFit/PMGeneralFunctionFit.class.st index 3301ffdee..059e7b496 100644 --- a/src/Math-FunctionFit/PMGeneralFunctionFit.class.st +++ b/src/Math-FunctionFit/PMGeneralFunctionFit.class.st @@ -7,8 +7,8 @@ fit evaluate . fit result . --> #(2.0000000000000413 3.000000000000014) " Class { - #name : #PMGeneralFunctionFit, - #superclass : #Object, + #name : 'PMGeneralFunctionFit', + #superclass : 'Object', #instVars : [ 'manager', 'errorFunction', @@ -19,10 +19,11 @@ Class { 'dataTruncated', 'geneticOptimizer' ], - #category : #'Math-FunctionFit' + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' } -{ #category : #creation } +{ #category : 'creation' } PMGeneralFunctionFit class >> function: aBlock data: aCollectionOfPoints minimumValues: anArray maximumValues: anotherArray [ (aBlock isBlock and:[aBlock numArgs > 1]) ifFalse: [^self error: 'aBlock must be a Block with one independent variable and at least one parameter' ]. @@ -33,7 +34,7 @@ PMGeneralFunctionFit class >> function: aBlock data: aCollectionOfPoints minimum yourself ] -{ #category : #util } +{ #category : 'util' } PMGeneralFunctionFit class >> range: anArray size: anInteger type: string [ ^anArray isNumber ifTrue: [Array new: anInteger withAll: anArray ] @@ -44,7 +45,7 @@ PMGeneralFunctionFit class >> range: anArray size: anInteger type: string [ ifFalse: [self error: (string, ' values is no collection or number')]] ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> data: aCollectionOfPoints [ "the data, a collection of x@f(x), used to estimate the parameters" self resetResult . @@ -53,44 +54,44 @@ dataTruncated:=false. ^errorFunction data: aCollectionOfPoints ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> dataTruncated [ ^dataTruncated ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> error [ "returns the sqrt of the mean of the sum of squared errors, or the mean abs error, or the quartile error, or the insensitive error" result ifNil: [^nil]. ^self error: result ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> error: parameters [ "returns the error for any parameter array; for example if you want to compare the error of the result with the error of the 'real' parameters" ^errorFunction realValue: parameters ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> errorCollection [ ^ result ifNil: [ Error signal: 'run "self evaluate" first' ] ifNotNil: [ :r | self optimizer functionBlock errorCollection: r ] ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> errorType [ ^errorFunction errorType ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> errorType: aSymbol [ "defines what kind of fitting should be used. valid errorTypes are: #squared, #abs, #insensitive, #quartile, #median. Default is #squared" self resetResult. ^errorFunction errorType: aSymbol ] -{ #category : #operation } +{ #category : 'operation' } PMGeneralFunctionFit >> evaluate [ | ff | @@ -120,7 +121,7 @@ PMGeneralFunctionFit >> evaluate [ ^ result ] -{ #category : #operation } +{ #category : 'operation' } PMGeneralFunctionFit >> findQuartile [ | errorCol d2 max v n| (#(#quartile #insensitive) includes: self errorType ) ifFalse: @@ -153,7 +154,7 @@ verbose :=v. ^self evaluate ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> function [ "does usually not return the originally entered block, but a SimpleParameterFunction with the parameters set to the result" |f| @@ -161,14 +162,14 @@ f :=errorFunction function . ^result ifNil: [f] ifNotNil: [PMSimpleParameterFunction function: f parameters: result] ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> function: aBlock [ "sets the function to be fitted. the first value has to be the independent variable, further values are the parameters to be fitted. only one independent variable is allowed (if you have several independent vars or eg a function of a vector, that returns another vector, have a look at the 'spiral' example)." self resetResult. errorFunction function: aBlock ] -{ #category : #initialization } +{ #category : 'initialization' } PMGeneralFunctionFit >> initialize [ super initialize. @@ -185,20 +186,20 @@ PMGeneralFunctionFit >> initialize [ dataTruncated := false ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> manager [ "if you want to change parameters of AnotherChromosomeManager, that are not directly available in GeneralFunctionFit" ^manager ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> maximumIterations: anInteger [ "default is 170." geneticOptimizer maximumIterations: anInteger. ^anInteger ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> minValues: anArray maxValues: anotherArray [ "instead of an array one can also use a number, an array will then be filled with this number. eg one can use 0 instead of the tiresome #(0 0 0 0). minValues and maxValues need not be absolutely correct. also results outside of this range, but nearby, will often be found." |array1 array2 aSize| @@ -212,13 +213,13 @@ manager origin: array1. manager range: (array2 - array1) ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> optimizer [ "if you want to change parameters of AnotherGeneticOptimizer not directly available in GeneralFunctionFit" ^geneticOptimizer ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> populationSize: anInteger [ " if you have a lot of parameters (essentially beginning with 3 parameters), you may want to enlarge the populationsize. default is only 50. eg for 3 parameters, you might want set this to 300" self resetResult. @@ -226,13 +227,13 @@ manager populationSize: anInteger . ^anInteger ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> precision [ "not really useful to look at, you might better look at #error" ^geneticOptimizer precision ] -{ #category : #printing } +{ #category : 'printing' } PMGeneralFunctionFit >> printOn: aStream [ aStream nextPutAll: 'a '; @@ -246,57 +247,57 @@ PMGeneralFunctionFit >> printOn: aStream [ aStream nextPut: $) ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> quartile [ ^errorFunction quartile ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> quartile: aFloat [ "quartile: is used by errortypes #quartile and #insensitive. if you set quartile to 1, it does not make much sense to use #insensitive, since #insensitive is much slower than #quartile and calculating the tube radius is not quite correct for #insensitive in this special case (it will leave out one datapoint )." self resetResult. ^errorFunction quartile: aFloat ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> relativeError: aBoolean [ "by default false" self resetResult . ^errorFunction relativeError: aBoolean ] -{ #category : #operation } +{ #category : 'operation' } PMGeneralFunctionFit >> resetBestPoints [ "for repeated evaluating with different starting populations" self resetResult ] -{ #category : #operation } +{ #category : 'operation' } PMGeneralFunctionFit >> resetData [ self data: data ] -{ #category : #private } +{ #category : 'private' } PMGeneralFunctionFit >> resetResult [ result :=nil. firstResult :=nil. geneticOptimizer resetBestPoints ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> result [ "the fitted parameters" result ifNil: [self evaluate ]. ^result ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> secondaryResult [ "not really necessary" ^firstResult ] -{ #category : #operation } +{ #category : 'operation' } PMGeneralFunctionFit >> truncateData [ |ec ei | dataTruncated ifTrue: [^Error signal:'data is already truncated']. @@ -309,7 +310,7 @@ dataTruncated:=true. ^self optimizer functionBlock data: (ei collect: [:i|self optimizer functionBlock data at: i]) ] -{ #category : #accessing } +{ #category : 'accessing' } PMGeneralFunctionFit >> verbose: aBoolean [ " by default false. if set it to true, you will get some tiresome messages" verbose :=aBoolean diff --git a/src/Math-FunctionFit/PMSimpleParameterFunction.class.st b/src/Math-FunctionFit/PMSimpleParameterFunction.class.st index 297334a83..f05a09165 100644 --- a/src/Math-FunctionFit/PMSimpleParameterFunction.class.st +++ b/src/Math-FunctionFit/PMSimpleParameterFunction.class.st @@ -2,32 +2,33 @@ SimpleParameterFunction is used internally by FunctionFit . it is essentially a wrapper around a block, which is used as a function with parameters. the independent variable has to be declared first in the block, then the parameters. " Class { - #name : #PMSimpleParameterFunction, - #superclass : #Object, + #name : 'PMSimpleParameterFunction', + #superclass : 'Object', #instVars : [ 'usedVars', 'function', 'varArray' ], - #category : #'Math-FunctionFit' + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMSimpleParameterFunction class >> function: aBlock [ ^self new function: aBlock ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMSimpleParameterFunction class >> function: aBlock parameters: anArray [ ^self new function: aBlock; parameters: anArray; yourself ] -{ #category : #accessing } +{ #category : 'accessing' } PMSimpleParameterFunction >> changeParametersBy: aVector [ 2 to: (usedVars+1) do:[:n| varArray at: n put: ((varArray at: n)+ ( aVector at: n-1)).] ] -{ #category : #initialization } +{ #category : 'initialization' } PMSimpleParameterFunction >> function: aBlock [ "also initializes the parameters" function:=aBlock. @@ -36,49 +37,49 @@ self initializeVarArray: 2. usedVars :=usedVars -1 ] -{ #category : #initialization } +{ #category : 'initialization' } PMSimpleParameterFunction >> initializeVarArray: aStart [ varArray :=Array new: usedVars withAll: 0.937. (1 + aStart) to: (usedVars min: (aStart +4)) do:[:i| varArray at: i put: ( #(0.929 0.919 0.911 0.907) at: (i - aStart ) )] ] -{ #category : #accessing } +{ #category : 'accessing' } PMSimpleParameterFunction >> parameterNames [ ^(function argumentNames collect:[:s| s asString ])allButFirst ] -{ #category : #accessing } +{ #category : 'accessing' } PMSimpleParameterFunction >> parameterSize [ ^usedVars ] -{ #category : #accessing } +{ #category : 'accessing' } PMSimpleParameterFunction >> parameters [ ^varArray allButFirst ] -{ #category : #accessing } +{ #category : 'accessing' } PMSimpleParameterFunction >> parameters: indexableCollection [ 1 to: usedVars do:[:n| varArray at: n+1 put: ( indexableCollection at: n)]. ^indexableCollection ] -{ #category : #printing } +{ #category : 'printing' } PMSimpleParameterFunction >> printOn: aStream [ super printOn: aStream. - aStream nextPutAll: '( '; print: function . + aStream nextPutAll: '( '; print: function compiledBlock. varArray ifNotNil:[ self parameterNames with: self parameters do: [:n :p|aStream nextPutAll: ' '; nextPutAll: n; nextPutAll:': ';print: p. ]] . aStream nextPut: $). ] -{ #category : #evaluating } +{ #category : 'evaluating' } PMSimpleParameterFunction >> value: aNumber [ varArray at:1 put: aNumber . ^[function valueWithArguments: varArray ]on: Error do: [ Float nan ] ] -{ #category : #evaluating } +{ #category : 'evaluating' } PMSimpleParameterFunction >> valueAndGradient: aNumber [ "the original unchanged approximatedValueAndGradient: " | delta parameters dp gradient n | diff --git a/src/Math-FunctionFit/package.st b/src/Math-FunctionFit/package.st index 0aeb25b60..9de935265 100644 --- a/src/Math-FunctionFit/package.st +++ b/src/Math-FunctionFit/package.st @@ -1 +1 @@ -Package { #name : #'Math-FunctionFit' } +Package { #name : 'Math-FunctionFit' } From 8cbae10e1925d237bb80c1150ce5b9291c5537d1 Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Wed, 25 Mar 2026 16:21:27 +0100 Subject: [PATCH 2/5] changed random seed so that tests passes in all Pharo versions --- .../PMClusterFinderTest.class.st | 21 ++++++++++--------- src/Math-Tests-Clustering/package.st | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Math-Tests-Clustering/PMClusterFinderTest.class.st b/src/Math-Tests-Clustering/PMClusterFinderTest.class.st index 6928f1934..7e1edc23c 100644 --- a/src/Math-Tests-Clustering/PMClusterFinderTest.class.st +++ b/src/Math-Tests-Clustering/PMClusterFinderTest.class.st @@ -1,14 +1,15 @@ Class { - #name : #PMClusterFinderTest, - #superclass : #TestCase, + #name : 'PMClusterFinderTest', + #superclass : 'TestCase', #instVars : [ 'dataServer', 'randomNumberGenerator' ], - #category : #'Math-Tests-Clustering' + #category : 'Math-Tests-Clustering', + #package : 'Math-Tests-Clustering' } -{ #category : #utilities } +{ #category : 'utilities' } PMClusterFinderTest >> accumulateAround: aVector size: aNumber into: aCollection [ "Private - Generate a random point around the given center and insert it into the collection. aNumber is the sigma for the distance to the center" @@ -28,7 +29,7 @@ PMClusterFinderTest >> accumulateAround: aVector size: aNumber into: aCollection aCollection add: (localVector + aVector) ] -{ #category : #utilities } +{ #category : 'utilities' } PMClusterFinderTest >> generatedPoints: anInteger [ "Private - Generate random points into aCollection. 3 clusters are used" | centers results randomNumber | @@ -47,16 +48,16 @@ PMClusterFinderTest >> generatedPoints: anInteger [ ^ results ] -{ #category : #running } +{ #category : 'running' } PMClusterFinderTest >> setUp [ super setUp. - randomNumberGenerator := Random seed: 3. + randomNumberGenerator := Random seed: 29. dataServer := PMMemoryBasedDataServer new. dataServer data: (self generatedPoints: 1000) ] -{ #category : #tests } +{ #category : 'tests' } PMClusterFinderTest >> testClusterCovariance [ | clusters finder | @@ -66,7 +67,7 @@ PMClusterFinderTest >> testClusterCovariance [ self assert: clusters size equals: 3 ] -{ #category : #tests } +{ #category : 'tests' } PMClusterFinderTest >> testClusterEuclidean [ | clusters finder | @@ -76,7 +77,7 @@ PMClusterFinderTest >> testClusterEuclidean [ self assert: clusters size equals: 3 ] -{ #category : #tests } +{ #category : 'tests' } PMClusterFinderTest >> testMahalanobisCenter [ "Code example 12.5" diff --git a/src/Math-Tests-Clustering/package.st b/src/Math-Tests-Clustering/package.st index 8aa635545..833e82fee 100644 --- a/src/Math-Tests-Clustering/package.st +++ b/src/Math-Tests-Clustering/package.st @@ -1 +1 @@ -Package { #name : #'Math-Tests-Clustering' } +Package { #name : 'Math-Tests-Clustering' } From 07885b0a498a608fe1ba5aae4e106ae1eab4b27a Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Wed, 25 Mar 2026 16:38:19 +0100 Subject: [PATCH 3/5] moved method to superclass for backward compatibility --- ...eanBlockClosure.extension.st => BlockClosure.extension.st} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename src/Math-FunctionFit/{CleanBlockClosure.extension.st => BlockClosure.extension.st} (51%) diff --git a/src/Math-FunctionFit/CleanBlockClosure.extension.st b/src/Math-FunctionFit/BlockClosure.extension.st similarity index 51% rename from src/Math-FunctionFit/CleanBlockClosure.extension.st rename to src/Math-FunctionFit/BlockClosure.extension.st index d0fafe7c0..385654b4a 100644 --- a/src/Math-FunctionFit/CleanBlockClosure.extension.st +++ b/src/Math-FunctionFit/BlockClosure.extension.st @@ -1,7 +1,7 @@ -Extension { #name : 'CleanBlockClosure' } +Extension { #name : 'BlockClosure' } { #category : '*Math-FunctionFit' } -CleanBlockClosure >> functionString [ +BlockClosure >> functionString [ ^ self sourceNode value sourceCode asString ] From 18d3bf891a8d89528fc02c036640aee469285475 Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Thu, 26 Mar 2026 15:53:16 +0100 Subject: [PATCH 4/5] removed extension method, inlined printOn --- src/Math-FunctionFit/BlockClosure.extension.st | 7 ------- .../PMAnotherGeneticOptimizer.class.st | 17 +++-------------- .../PMErrorOfParameterFunction.class.st | 13 +++++++------ .../PMGeneralFunctionFit.class.st | 6 ++++-- 4 files changed, 14 insertions(+), 29 deletions(-) delete mode 100644 src/Math-FunctionFit/BlockClosure.extension.st diff --git a/src/Math-FunctionFit/BlockClosure.extension.st b/src/Math-FunctionFit/BlockClosure.extension.st deleted file mode 100644 index 385654b4a..000000000 --- a/src/Math-FunctionFit/BlockClosure.extension.st +++ /dev/null @@ -1,7 +0,0 @@ -Extension { #name : 'BlockClosure' } - -{ #category : '*Math-FunctionFit' } -BlockClosure >> functionString [ - - ^ self sourceNode value sourceCode asString -] diff --git a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st index cd4159223..9e5962646 100644 --- a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st +++ b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st @@ -169,17 +169,12 @@ PMAnotherGeneticOptimizer >> nextGeneration [ ] { #category : 'printing' } -PMAnotherGeneticOptimizer >> printOn1: aStream [ +PMAnotherGeneticOptimizer >> printOn: aStream [ aStream nextPutAll: self class name; nextPutAll: '( function: '; - nextPutAll: originalFunction functionString -] - -{ #category : 'printing' } -PMAnotherGeneticOptimizer >> printOn2: aStream [ - aStream + nextPutAll: originalFunction compiledBlock asString; nextPutAll: ' manager: '; print: chromosomeManager; nextPutAll: ' maxIterations: '; @@ -197,12 +192,6 @@ PMAnotherGeneticOptimizer >> printOn2: aStream [ nextPut: $) ] -{ #category : 'printing' } -PMAnotherGeneticOptimizer >> printOn: aStream [ - self printOn1: aStream. - self printOn2: aStream -] - { #category : 'operation' } PMAnotherGeneticOptimizer >> processRandomParents: aNumberArray [ "puts the better chromosome at the first place (is eg necessary for lineCrossOver:and:)" @@ -251,7 +240,7 @@ result :=nil PMAnotherGeneticOptimizer >> setFunction: aBlock [ ( aBlock respondsTo: #value:) ifFalse:[ self error: 'Function block must implement the method value:']. - originalFunction :=aBlock . "necessary for subclass; do not delete that nonsense!" + originalFunction := aBlock . "necessary for subclass; do not delete that nonsense!" functionBlock := aBlock. self resetBestPoints ] diff --git a/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st b/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st index 80cb84818..23b8f2393 100644 --- a/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st +++ b/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st @@ -23,6 +23,13 @@ PMErrorOfParameterFunction class >> function: aBlock data: aCollectionOfPoints [ ^self new function: aBlock; data: aCollectionOfPoints; yourself ] +{ #category : 'accessing' } +PMErrorOfParameterFunction >> compiledBlock [ + "This method only exists for polymorphic message send" + + ^ self asString +] + { #category : 'accessing' } PMErrorOfParameterFunction >> data [ ^data @@ -90,12 +97,6 @@ function :=aBlock . varArray :=Array new: aBlock numArgs ] -{ #category : 'accessing' } -PMErrorOfParameterFunction >> functionString [ - - ^ self asString -] - { #category : 'initialization' } PMErrorOfParameterFunction >> initialize [ super initialize . diff --git a/src/Math-FunctionFit/PMGeneralFunctionFit.class.st b/src/Math-FunctionFit/PMGeneralFunctionFit.class.st index 059e7b496..400937b18 100644 --- a/src/Math-FunctionFit/PMGeneralFunctionFit.class.st +++ b/src/Math-FunctionFit/PMGeneralFunctionFit.class.st @@ -165,8 +165,9 @@ f :=errorFunction function . { #category : 'accessing' } PMGeneralFunctionFit >> function: aBlock [ "sets the function to be fitted. the first value has to be the independent variable, further values are the parameters to be fitted. only one independent variable is allowed (if you have several independent vars or eg a function of a vector, that returns another vector, have a look at the 'spiral' example)." -self resetResult. -errorFunction function: aBlock + + self resetResult. + errorFunction function: aBlock ] { #category : 'initialization' } @@ -181,6 +182,7 @@ PMGeneralFunctionFit >> initialize [ chromosomeManager: manager; maximumIterations: 170; yourself. + self errorType: #squared. verbose := false. dataTruncated := false From e666a489911fb4c241ec63e62c057c97b65d6ebf Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Fri, 27 Mar 2026 15:28:54 +0100 Subject: [PATCH 5/5] fixed print tests --- .../PMAnotherGeneticOptimizer.class.st | 2 +- .../PMErrorOfParameterFunction.class.st | 8 ++-- .../PMFunctionPrinter.class.st | 12 +++++ .../PMGeneralFunctionFit.class.st | 17 +++++-- .../PMAnotherChromosomeManagerTest.class.st | 41 +++++++---------- .../PMAnotherGeneticOptimizerTest.class.st | 43 +++++++----------- .../PMDataHolderTest.class.st | 9 ++-- .../PMErrorAsParameterFunctionTest.class.st | 28 ++++-------- .../PMErrorMinimizerTest.class.st | 9 ++-- .../PMErrorOfParameterFunctionTest.class.st | 37 ++++++--------- .../PMFunctionFitTest.class.st | 22 +++------ .../PMGeneralFunctionFitTest.class.st | 45 ++++++------------- .../PMSimpleParameterFunctionTest.class.st | 28 ++++-------- src/Math-Tests-FunctionFit/package.st | 2 +- 14 files changed, 123 insertions(+), 180 deletions(-) create mode 100644 src/Math-FunctionFit/PMFunctionPrinter.class.st diff --git a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st index 9e5962646..35a45c32c 100644 --- a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st +++ b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st @@ -174,7 +174,7 @@ PMAnotherGeneticOptimizer >> printOn: aStream [ aStream nextPutAll: self class name; nextPutAll: '( function: '; - nextPutAll: originalFunction compiledBlock asString; + nextPutAll: (PMFunctionPrinter new printFunction: originalFunction); nextPutAll: ' manager: '; print: chromosomeManager; nextPutAll: ' maxIterations: '; diff --git a/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st b/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st index 23b8f2393..5862ecfbe 100644 --- a/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st +++ b/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st @@ -27,7 +27,7 @@ PMErrorOfParameterFunction class >> function: aBlock data: aCollectionOfPoints [ PMErrorOfParameterFunction >> compiledBlock [ "This method only exists for polymorphic message send" - ^ self asString + ^ function ] { #category : 'accessing' } @@ -117,9 +117,11 @@ PMErrorOfParameterFunction >> parameterSize [ { #category : 'printing' } PMErrorOfParameterFunction >> printOn: aStream [ - super printOn: aStream. aStream - nextPutAll: '( function: '; print: function compiledBlock; + nextPutAll: 'a '; + nextPutAll: self class name; + nextPutAll: '( function: '; + nextPutAll: (PMFunctionPrinter new printFunction: function); nextPutAll: ' relativeError: '; print: relative; nextPutAll: ' errorType: '; print: errorType. (#(#quartile #insensitive) includes: errorType)ifTrue:[ diff --git a/src/Math-FunctionFit/PMFunctionPrinter.class.st b/src/Math-FunctionFit/PMFunctionPrinter.class.st new file mode 100644 index 000000000..4619452b9 --- /dev/null +++ b/src/Math-FunctionFit/PMFunctionPrinter.class.st @@ -0,0 +1,12 @@ +Class { + #name : 'PMFunctionPrinter', + #superclass : 'Object', + #category : 'Math-FunctionFit', + #package : 'Math-FunctionFit' +} + +{ #category : 'printing' } +PMFunctionPrinter >> printFunction: aFunction [ + + ^ aFunction compiledBlock sourceNode sourceCode +] diff --git a/src/Math-FunctionFit/PMGeneralFunctionFit.class.st b/src/Math-FunctionFit/PMGeneralFunctionFit.class.st index 400937b18..593192375 100644 --- a/src/Math-FunctionFit/PMGeneralFunctionFit.class.st +++ b/src/Math-FunctionFit/PMGeneralFunctionFit.class.st @@ -45,6 +45,12 @@ PMGeneralFunctionFit class >> range: anArray size: anInteger type: string [ ifFalse: [self error: (string, ' values is no collection or number')]] ] +{ #category : 'accessing' } +PMGeneralFunctionFit >> compiledBlock [ + + ^ errorFunction function +] + { #category : 'accessing' } PMGeneralFunctionFit >> data: aCollectionOfPoints [ "the data, a collection of x@f(x), used to estimate the parameters" @@ -237,16 +243,19 @@ PMGeneralFunctionFit >> precision [ { #category : 'printing' } PMGeneralFunctionFit >> printOn: aStream [ + aStream nextPutAll: 'a '; nextPutAll: self class name; nextPut: $(; print: geneticOptimizer; nextPutAll: ' with data of size: '; - print: data size . - dataTruncated ifTrue: - [aStream nextPutAll: ' truncated to: '; print: self optimizer functionBlock data size] . - aStream nextPut: $) + print: data size. + dataTruncated ifTrue: [ + aStream + nextPutAll: ' truncated to: '; + print: self optimizer functionBlock data size ]. + aStream nextPut: $) ] { #category : 'accessing' } diff --git a/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st b/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st index 50152d1c4..2294a9fd4 100644 --- a/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st +++ b/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st @@ -1,13 +1,14 @@ Class { - #name : #PMAnotherChromosomeManagerTest, - #superclass : #TestCase, + #name : 'PMAnotherChromosomeManagerTest', + #superclass : 'TestCase', #instVars : [ 'chromosomeManager' ], - #category : #'Math-Tests-FunctionFit' + #category : 'Math-Tests-FunctionFit', + #package : 'Math-Tests-FunctionFit' } -{ #category : #running } +{ #category : 'running' } PMAnotherChromosomeManagerTest >> setHammersleyTest: aBoolean [ chromosomeManager useHammersley: aBoolean. chromosomeManager randomizePopulation. @@ -23,7 +24,7 @@ PMAnotherChromosomeManagerTest >> setHammersleyTest: aBoolean [ self assert: (i second between: 1 and: 4) ] ] -{ #category : #running } +{ #category : 'running' } PMAnotherChromosomeManagerTest >> setUp [ super setUp. @@ -31,14 +32,14 @@ PMAnotherChromosomeManagerTest >> setUp [ chromosomeManager randomGenerator: (Random seed: 42) ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherChromosomeManagerTest >> testAccessing [ self assert: chromosomeManager range equals: #(2 3). self assert: chromosomeManager populationSize equals: 100. self deny: chromosomeManager isFullyPopulated ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherChromosomeManagerTest >> testCrossOver [ | a | @@ -56,7 +57,7 @@ PMAnotherChromosomeManagerTest >> testCrossOver [ self assert: (a occurrencesOf: #( 1 2 3 )) < 20 ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherChromosomeManagerTest >> testEirCrossOver [ |a| a :=(1 to: 200)collect: [:i| a:=chromosomeManager eirCrossover: #(1.0 3.0) and: #(5.0 1.0). @@ -82,7 +83,7 @@ self shouldnt: [a:=chromosomeManager eirCrossover: #(1 -3) and: #(1 -3)] raise: ]. ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherChromosomeManagerTest >> testIntegerDigits [ self assert: (PMAnotherChromosomeManager integerDigitsFor: 0 base: 2) @@ -101,7 +102,7 @@ PMAnotherChromosomeManagerTest >> testIntegerDigits [ equals: #(1 4 4) ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherChromosomeManagerTest >> testLineCrossOver [ | a | 1 to: 10 do: [ :i | @@ -110,7 +111,7 @@ PMAnotherChromosomeManagerTest >> testLineCrossOver [ self assert: ((a at: 2) at: 2) equals: ((a at: 2) at: 1) negated ] ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherChromosomeManagerTest >> testMutateProbabilistic [ | a f s | @@ -134,7 +135,7 @@ PMAnotherChromosomeManagerTest >> testMutateProbabilistic [ self assert: (s size between: 3 and: 20) ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherChromosomeManagerTest >> testNumberOfHamersleyPoints [ | rand | @@ -197,17 +198,7 @@ PMAnotherChromosomeManagerTest >> testNumberOfHamersleyPoints [ rand do: [ :i | i do: [ :j | j < (1 / 3) ] ] ] -{ #category : #tests } -PMAnotherChromosomeManagerTest >> testPrint [ -|aStream s| -aStream :=ReadWriteStream with:''. -chromosomeManager printOn: aStream . -s :=aStream contents . -self assert: (s includesSubstring: '#(0 1)'). -self assert: (s includesSubstring: '#(2 3)') -] - -{ #category : #tests } +{ #category : 'tests' } PMAnotherChromosomeManagerTest >> testProcessand [ chromosomeManager reset. 1 to: 60 do: [ :i | chromosomeManager process: #(0 0) and: #(1 1) ]. @@ -218,7 +209,7 @@ PMAnotherChromosomeManagerTest >> testProcessand [ self assert: chromosomeManager population size equals: 120 ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherChromosomeManagerTest >> testRandomizePopulation [ | g | @@ -231,7 +222,7 @@ PMAnotherChromosomeManagerTest >> testRandomizePopulation [ self deny: chromosomeManager population first equals: g ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherChromosomeManagerTest >> testRateSetting [ self should: [chromosomeManager rateOfLC: 1.3] raise: DomainError . self should: [chromosomeManager rateOfEir: -0.3] raise: DomainError . diff --git a/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st b/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st index 5c1920046..2941475b8 100644 --- a/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st +++ b/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st @@ -1,13 +1,14 @@ Class { - #name : #PMAnotherGeneticOptimizerTest, - #superclass : #TestCase, + #name : 'PMAnotherGeneticOptimizerTest', + #superclass : 'TestCase', #instVars : [ 'geneticOptimizer' ], - #category : #'Math-Tests-FunctionFit' + #category : 'Math-Tests-FunctionFit', + #package : 'Math-Tests-FunctionFit' } -{ #category : #running } +{ #category : 'running' } PMAnotherGeneticOptimizerTest >> setUp [ | origin f | @@ -23,7 +24,7 @@ PMAnotherGeneticOptimizerTest >> setUp [ geneticOptimizer chromosomeManager randomGenerator: (Random seed: 42) ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testChromosomeManager [ self assert: geneticOptimizer chromosomeManager class @@ -31,7 +32,7 @@ PMAnotherGeneticOptimizerTest >> testChromosomeManager [ self assert: geneticOptimizer chromosomeManager populationSize equals: 20 ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testComputePrecision [ |r| geneticOptimizer maximumIterations: 2. @@ -42,7 +43,7 @@ geneticOptimizer evaluate . self assert: (r>geneticOptimizer computePrecision ) ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testEvaluate [ geneticOptimizer maximumIterations: 170. @@ -50,7 +51,7 @@ PMAnotherGeneticOptimizerTest >> testEvaluate [ self assert: geneticOptimizer evaluate closeTo: #( 0 0 0 ) ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testInitializeIterations [ self assertEmpty: geneticOptimizer bestPoints. @@ -63,19 +64,7 @@ PMAnotherGeneticOptimizerTest >> testInitializeIterations [ self assertEmpty: geneticOptimizer bestValueHistory ] -{ #category : #tests } -PMAnotherGeneticOptimizerTest >> testPrint [ - - | aStream s | - aStream := ReadWriteStream with: ''. - geneticOptimizer printOn: aStream. - s := aStream contents. - self assert: (s includesSubstring: 'v * v'). - self assert: (s includesSubstring: '50'). - self assert: (s includesSubstring: '20') -] - -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testRangeScale [ geneticOptimizer initializeIterations. @@ -86,7 +75,7 @@ PMAnotherGeneticOptimizerTest >> testRangeScale [ self assert: geneticOptimizer rangeScale second closeTo: 0.19473684210526315 ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testRangeScaleProbabilistic [ | r1 r2 correct | correct := 0. @@ -106,7 +95,7 @@ PMAnotherGeneticOptimizerTest >> testRangeScaleProbabilistic [ self assert: correct > 0 ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testRemoveLastProbabilistic [ | r1 r2 correct | correct := 0. @@ -126,7 +115,7 @@ PMAnotherGeneticOptimizerTest >> testRemoveLastProbabilistic [ self assert: correct > 0 ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testSteadyState [ |r1 r2| "probabilistic test. not always true" @@ -140,7 +129,7 @@ r2 :=geneticOptimizer evaluate norm. self assert: (r1>r2 ) ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testaddPointAt [ | b | geneticOptimizer chromosomeManager populationSize: 2. @@ -167,7 +156,7 @@ PMAnotherGeneticOptimizerTest >> testaddPointAt [ self assert: b second position equals: #(0 0.9 0) ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testcalcStatistics [ | s | @@ -183,7 +172,7 @@ PMAnotherGeneticOptimizerTest >> testcalcStatistics [ self assert: geneticOptimizer whateverHistory size equals: s ] -{ #category : #tests } +{ #category : 'tests' } PMAnotherGeneticOptimizerTest >> testresetBestPoints [ geneticOptimizer evaluate. diff --git a/src/Math-Tests-FunctionFit/PMDataHolderTest.class.st b/src/Math-Tests-FunctionFit/PMDataHolderTest.class.st index aa937fa2d..cf43ccb4b 100644 --- a/src/Math-Tests-FunctionFit/PMDataHolderTest.class.st +++ b/src/Math-Tests-FunctionFit/PMDataHolderTest.class.st @@ -1,10 +1,11 @@ Class { - #name : #PMDataHolderTest, - #superclass : #TestCase, - #category : #'Math-Tests-FunctionFit' + #name : 'PMDataHolderTest', + #superclass : 'TestCase', + #category : 'Math-Tests-FunctionFit', + #package : 'Math-Tests-FunctionFit' } -{ #category : #tests } +{ #category : 'tests' } PMDataHolderTest >> testpointsAndErrorsDo [ |g| g:=PMDataHolder new: 2 withAll: 2@3. diff --git a/src/Math-Tests-FunctionFit/PMErrorAsParameterFunctionTest.class.st b/src/Math-Tests-FunctionFit/PMErrorAsParameterFunctionTest.class.st index 8857a80d0..90bcac00e 100644 --- a/src/Math-Tests-FunctionFit/PMErrorAsParameterFunctionTest.class.st +++ b/src/Math-Tests-FunctionFit/PMErrorAsParameterFunctionTest.class.st @@ -1,13 +1,14 @@ Class { - #name : #PMErrorAsParameterFunctionTest, - #superclass : #TestCase, + #name : 'PMErrorAsParameterFunctionTest', + #superclass : 'TestCase', #instVars : [ 'f' ], - #category : #'Math-Tests-FunctionFit' + #category : 'Math-Tests-FunctionFit', + #package : 'Math-Tests-FunctionFit' } -{ #category : #running } +{ #category : 'running' } PMErrorAsParameterFunctionTest >> setUp [ | col | @@ -18,32 +19,19 @@ PMErrorAsParameterFunctionTest >> setUp [ f := PMErrorAsParameterFunction new function: f ] -{ #category : #tests } +{ #category : 'tests' } PMErrorAsParameterFunctionTest >> testMaxFunction [ self assert: (f parameters size < f maxFunction ) ] -{ #category : #tests } -PMErrorAsParameterFunctionTest >> testPrint [ - - | aStream s | - aStream := ReadWriteStream with: ''. - f printOn: aStream. - s := aStream contents. - self assert: (s includesSubstring: 'a * x / (b + x)'). - self assert: (s includesSubstring: '#squared'). - self assert: - (s includesSubstring: 'maxFunction: ' , f maxFunction asString) -] - -{ #category : #tests } +{ #category : 'tests' } PMErrorAsParameterFunctionTest >> testparameters [ f parameters: #(1 1). f changeParametersBy: #(1 1). self assert: f parameters equals: #(2 2) ] -{ #category : #tests } +{ #category : 'tests' } PMErrorAsParameterFunctionTest >> testvalue [ f parameters: #(2 2). self assert: (f value: 2) equals: 1 / 9 diff --git a/src/Math-Tests-FunctionFit/PMErrorMinimizerTest.class.st b/src/Math-Tests-FunctionFit/PMErrorMinimizerTest.class.st index bcb8fafee..4b3fb506b 100644 --- a/src/Math-Tests-FunctionFit/PMErrorMinimizerTest.class.st +++ b/src/Math-Tests-FunctionFit/PMErrorMinimizerTest.class.st @@ -2,12 +2,13 @@ ErrorMinimizerTest tests indirectly also ErrorAsParameterFunction. " Class { - #name : #PMErrorMinimizerTest, - #superclass : #TestCase, - #category : #'Math-Tests-FunctionFit' + #name : 'PMErrorMinimizerTest', + #superclass : 'TestCase', + #category : 'Math-Tests-FunctionFit', + #package : 'Math-Tests-FunctionFit' } -{ #category : #tests } +{ #category : 'tests' } PMErrorMinimizerTest >> testErrorMinimizer [ | f col er fit | diff --git a/src/Math-Tests-FunctionFit/PMErrorOfParameterFunctionTest.class.st b/src/Math-Tests-FunctionFit/PMErrorOfParameterFunctionTest.class.st index 6cd7c5c52..4a0ec46aa 100644 --- a/src/Math-Tests-FunctionFit/PMErrorOfParameterFunctionTest.class.st +++ b/src/Math-Tests-FunctionFit/PMErrorOfParameterFunctionTest.class.st @@ -1,14 +1,15 @@ Class { - #name : #PMErrorOfParameterFunctionTest, - #superclass : #TestCase, + #name : 'PMErrorOfParameterFunctionTest', + #superclass : 'TestCase', #instVars : [ 'f', 'col' ], - #category : #'Math-Tests-FunctionFit' + #category : 'Math-Tests-FunctionFit', + #package : 'Math-Tests-FunctionFit' } -{ #category : #running } +{ #category : 'running' } PMErrorOfParameterFunctionTest >> setUp [ super setUp. @@ -17,12 +18,12 @@ PMErrorOfParameterFunctionTest >> setUp [ col := (1 to: 3) collect: [ :i | i @ (f function cull: i cull: 1 cull: 1) ] ] -{ #category : #tests } +{ #category : 'tests' } PMErrorOfParameterFunctionTest >> testArgumentsString [ self assert: f parameterNames asOrderedCollection equals: #('a' 'b') asOrderedCollection ] -{ #category : #tests } +{ #category : 'tests' } PMErrorOfParameterFunctionTest >> testErrorCollection [ f data: col. f errorType: #squared. @@ -37,7 +38,7 @@ PMErrorOfParameterFunctionTest >> testErrorCollection [ self assert: (f errorCollection: #(1 1)) equals: #(0 0 0) ] -{ #category : #tests } +{ #category : 'tests' } PMErrorOfParameterFunctionTest >> testErrorType [ self assert: f errorType equals: #squared. f errorType: #abs. @@ -50,25 +51,13 @@ PMErrorOfParameterFunctionTest >> testErrorType [ self assert: f quartile equals: 1 / 2 ] -{ #category : #tests } +{ #category : 'tests' } PMErrorOfParameterFunctionTest >> testFunction [ self assert: (f function cull: 1 cull: 2 cull: 3) equals: 1 / 2. self assert: f parameterSize equals: 2 ] -{ #category : #tests } -PMErrorOfParameterFunctionTest >> testPrint [ -|aStream s| -aStream :=ReadWriteStream with:''. -f data:(Array with: (1@(1/2)) with: (2@(2/3)) with: (3@(3/4))). -f printOn: aStream . -s :=aStream contents . -self assert: (s includesSubstring: 'a * x / (b + x)'). -self assert: (s includesSubstring: 'squared'). -self assert: (s includesSubstring: 'false') -] - -{ #category : #tests } +{ #category : 'tests' } PMErrorOfParameterFunctionTest >> testQuartile [ self assert: f quartile equals: 1 / 2. f quartile: 1. @@ -77,7 +66,7 @@ PMErrorOfParameterFunctionTest >> testQuartile [ self should: [ f quartile: -0.1 ] raise: DomainError ] -{ #category : #tests } +{ #category : 'tests' } PMErrorOfParameterFunctionTest >> testRealValue [ f := PMErrorOfParameterFunction function: [ :i :a | i + a ] @@ -97,14 +86,14 @@ PMErrorOfParameterFunctionTest >> testRealValue [ self assert: (f realValue: #(-2)) equals: 1 ] -{ #category : #tests } +{ #category : 'tests' } PMErrorOfParameterFunctionTest >> testdata [ self assert: f data isNil. f data: col. self assert: f data equals: col ] -{ #category : #tests } +{ #category : 'tests' } PMErrorOfParameterFunctionTest >> testvalue [ f data: col. f errorType: #squared. diff --git a/src/Math-Tests-FunctionFit/PMFunctionFitTest.class.st b/src/Math-Tests-FunctionFit/PMFunctionFitTest.class.st index edae74c9f..0758b2839 100644 --- a/src/Math-Tests-FunctionFit/PMFunctionFitTest.class.st +++ b/src/Math-Tests-FunctionFit/PMFunctionFitTest.class.st @@ -1,14 +1,15 @@ Class { - #name : #PMFunctionFitTest, - #superclass : #TestCase, + #name : 'PMFunctionFitTest', + #superclass : 'TestCase', #instVars : [ 'f', 'd' ], - #category : #'Math-Tests-FunctionFit' + #category : 'Math-Tests-FunctionFit', + #package : 'Math-Tests-FunctionFit' } -{ #category : #running } +{ #category : 'running' } PMFunctionFitTest >> setUp [ super setUp. @@ -17,7 +18,7 @@ PMFunctionFitTest >> setUp [ d := (1 to: 20) collect: [ :i | i @ (f cull: i cull: 2 cull: 0.4) ] ] -{ #category : #tests } +{ #category : 'tests' } PMFunctionFitTest >> testFunctionFit [ | ff ar p | @@ -34,14 +35,3 @@ PMFunctionFitTest >> testFunctionFit [ ff evaluate. self assert: ff parameters closeTo: #( 2 0.4 ) ] - -{ #category : #tests } -PMFunctionFitTest >> testPrint [ -|aStream ff s| -aStream :=ReadWriteStream with:''. -ff:= PMFunctionFit function: f data: d . -ff printOn: aStream . -s :=aStream contents . -self assert: (s includesSubstring: 'a * x / (b + x)'). -self assert: (s includesSubstring: '20') -] diff --git a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st index d4a86dbd6..a795f9e9f 100644 --- a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st +++ b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st @@ -1,15 +1,16 @@ Class { - #name : #PMGeneralFunctionFitTest, - #superclass : #TestCase, + #name : 'PMGeneralFunctionFitTest', + #superclass : 'TestCase', #instVars : [ 'f', 'col', 'fit' ], - #category : #'Math-Tests-FunctionFit' + #category : 'Math-Tests-FunctionFit', + #package : 'Math-Tests-FunctionFit' } -{ #category : #running } +{ #category : 'running' } PMGeneralFunctionFitTest >> setUp [ "Reset the seed of the random numbers (to get consistent results)" @@ -27,7 +28,7 @@ PMGeneralFunctionFitTest >> setUp [ fit manager randomGenerator: (Random seed: 42) ] -{ #category : #tests } +{ #category : 'tests' } PMGeneralFunctionFitTest >> testBasic [ | d | @@ -38,7 +39,7 @@ PMGeneralFunctionFitTest >> testBasic [ self assert: fit error < d ] -{ #category : #tests } +{ #category : 'tests' } PMGeneralFunctionFitTest >> testFunction [ | y | @@ -47,14 +48,14 @@ PMGeneralFunctionFitTest >> testFunction [ self assert: (fit function value: 3) closeTo: y ] -{ #category : #tests } +{ #category : 'tests' } PMGeneralFunctionFitTest >> testManager [ self assert: fit manager class equals: PMAnotherChromosomeManager. self assert: fit manager range equals: #( 5 5 ) ] -{ #category : #tests } +{ #category : 'tests' } PMGeneralFunctionFitTest >> testMaximumIterationsProbabilistic [ | r correct | @@ -73,7 +74,7 @@ PMGeneralFunctionFitTest >> testMaximumIterationsProbabilistic [ self assert: correct > 0 ] -{ #category : #tests } +{ #category : 'tests' } PMGeneralFunctionFitTest >> testPopulationSize [ self assert: fit manager populationSize equals: 50. @@ -81,7 +82,7 @@ PMGeneralFunctionFitTest >> testPopulationSize [ self assert: fit manager populationSize equals: 100 ] -{ #category : #tests } +{ #category : 'tests' } PMGeneralFunctionFitTest >> testPrecision [ self assert: fit precision isNil. @@ -89,25 +90,7 @@ PMGeneralFunctionFitTest >> testPrecision [ self assert: fit precision < 1e-6 ] -{ #category : #tests } -PMGeneralFunctionFitTest >> testPrint [ - - | aStream s | - 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 } +{ #category : 'tests' } PMGeneralFunctionFitTest >> testRelativeError [ | r | @@ -133,7 +116,7 @@ PMGeneralFunctionFitTest >> testRelativeError [ self assert: r < 4 ] -{ #category : #tests } +{ #category : 'tests' } PMGeneralFunctionFitTest >> testResetBestPoints [ fit evaluate. @@ -141,7 +124,7 @@ PMGeneralFunctionFitTest >> testResetBestPoints [ self assertEmpty: fit optimizer bestPoints ] -{ #category : #tests } +{ #category : 'tests' } PMGeneralFunctionFitTest >> testTruncate [ col at: 1 put: -4 @ -0.2. diff --git a/src/Math-Tests-FunctionFit/PMSimpleParameterFunctionTest.class.st b/src/Math-Tests-FunctionFit/PMSimpleParameterFunctionTest.class.st index 32297b92d..f36188d47 100644 --- a/src/Math-Tests-FunctionFit/PMSimpleParameterFunctionTest.class.st +++ b/src/Math-Tests-FunctionFit/PMSimpleParameterFunctionTest.class.st @@ -1,18 +1,19 @@ Class { - #name : #PMSimpleParameterFunctionTest, - #superclass : #TestCase, + #name : 'PMSimpleParameterFunctionTest', + #superclass : 'TestCase', #instVars : [ 'f' ], - #category : #'Math-Tests-FunctionFit' + #category : 'Math-Tests-FunctionFit', + #package : 'Math-Tests-FunctionFit' } -{ #category : #running } +{ #category : 'running' } PMSimpleParameterFunctionTest >> setUp [ f:=[:a :x :cc :b|x] ] -{ #category : #tests } +{ #category : 'tests' } PMSimpleParameterFunctionTest >> testChangeParametersBy [ | s | s := PMSimpleParameterFunction function: f parameters: #(1 1 2). @@ -20,27 +21,14 @@ PMSimpleParameterFunctionTest >> testChangeParametersBy [ self assert: s parameters equals: #(4 3 3) ] -{ #category : #tests } +{ #category : 'tests' } PMSimpleParameterFunctionTest >> testParameterNames [ | s | s := PMSimpleParameterFunction function: f. self assert: s parameterNames asArray equals: #('x' 'cc' 'b') ] -{ #category : #tests } -PMSimpleParameterFunctionTest >> testPrint [ -|aStream s| -aStream :=ReadWriteStream with:''. -s:=PMSimpleParameterFunction function:f parameters: #(1 2 3). -s printOn: aStream . -s :=aStream contents . -self assert: ((s beginsWith: 'a PMSimpleParameterFunction')). -self assert: (s includesSubstring: '1'). -self assert: (s includesSubstring: ' 2'). -self assert: (s includesSubstring: ' 3') -] - -{ #category : #tests } +{ #category : 'tests' } PMSimpleParameterFunctionTest >> testRest [ | s vg | diff --git a/src/Math-Tests-FunctionFit/package.st b/src/Math-Tests-FunctionFit/package.st index 336d0f416..af98dd5c8 100644 --- a/src/Math-Tests-FunctionFit/package.st +++ b/src/Math-Tests-FunctionFit/package.st @@ -1 +1 @@ -Package { #name : #'Math-Tests-FunctionFit' } +Package { #name : 'Math-Tests-FunctionFit' }