diff --git a/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st b/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st index c7246fe7..8f323990 100644 --- a/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st +++ b/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st @@ -39,12 +39,12 @@ BaselineOfPolyMath >> baseline: spec [ package: 'Math-Complex' with: [ spec requires: #( 'Math-Numerical' 'Math-Polynomials' ) ]; package: 'Math-Helpers'; package: 'Math-Distributions' with: [ spec requires: #( 'MathVectorMatrix' 'Math-Quantile' 'Math-Core-Process' ) ]; - package: 'Math-Core-Process' with: [ spec requires: #( 'Math-Helpers' ) ]; + package: 'Math-Core-Process'; package: 'Math-Numerical' - with: [ spec requires: #( 'MathVectorMatrix' 'Math-Helpers' 'Math-Core-Process' 'Math-Distributions' 'Math-StatisticalMoments' + with: [ spec requires: #( 'MathVectorMatrix' 'Math-Core-Process' 'Math-Distributions' 'Math-StatisticalMoments' 'Math-Series' ) ]; package: 'Math-Polynomials' - with: [ spec requires: #( 'MathVectorMatrix' 'Math-Helpers' 'Math-Core-Process' 'Math-Distributions' 'Math-StatisticalMoments' + with: [ spec requires: #( 'MathVectorMatrix' 'Math-Core-Process' 'Math-Distributions' 'Math-StatisticalMoments' 'Math-Series' ) ]; package: 'Math-FastFourierTransform' with: [ spec requires: #( 'Math-Complex' ) ]; package: 'Math-FunctionFit' diff --git a/src/Math-CompatibilityUpToPharo11/Float.extension.st b/src/Math-CompatibilityUpToPharo11/Float.extension.st index a5eed5a5..51d56ba0 100644 --- a/src/Math-CompatibilityUpToPharo11/Float.extension.st +++ b/src/Math-CompatibilityUpToPharo11/Float.extension.st @@ -1,5 +1,11 @@ Extension { #name : #Float } +{ #category : #'*Math-CompatibilityUpToPharo11' } +Float class >> defaultComparisonPrecision [ + + ^ self machineEpsilon sqrt +] + { #category : #'*Math-CompatibilityUpToPharo11' } Float class >> machineEpsilon [ "Answer the machine epsilon or macheps, defined by wikipedia asCalypsoItemContext diff --git a/src/Math-Core-Process/PMIterativeProcess.class.st b/src/Math-Core-Process/PMIterativeProcess.class.st index 827d374d..f82a9452 100644 --- a/src/Math-Core-Process/PMIterativeProcess.class.st +++ b/src/Math-Core-Process/PMIterativeProcess.class.st @@ -33,7 +33,9 @@ PMIterativeProcess class >> defaultMaximumIterations [ { #category : #default } PMIterativeProcess class >> defaultPrecision [ "Private - Answers the default precision for newly created instances." - ^PMFloatingPointMachine new defaultNumericalPrecision + + self flag: #todo. "In Pharo 12 the default comparision precision of Float will be improved. When Pharo 12 will be the minimal version of Polymath we can use `Float defaultComparisonPrecision" + ^ Float machineEpsilon sqrt ] { #category : #initialization } @@ -82,8 +84,7 @@ PMIterativeProcess >> initialize [ super initialize. desiredPrecision := self class defaultPrecision. - maximumIterations := self class defaultMaximumIterations. - ^ self + maximumIterations := self class defaultMaximumIterations ] { #category : #operation } @@ -99,10 +100,13 @@ PMIterativeProcess >> iterations [ { #category : #private } PMIterativeProcess >> limitedSmallValue: aNumber [ - "Private - prevent aNumber from being smaller in absolute value than a small number." - ^aNumber abs < PMFloatingPointMachine new smallNumber - ifTrue: [ PMFloatingPointMachine new smallNumber] - ifFalse:[ aNumber] + "Private - prevent aNumber from being smaller in absolute value than a small." + + | smallestAccepted | + smallestAccepted := Float fmin sqrt. + ^ aNumber abs < smallestAccepted + ifTrue: [ smallestAccepted ] + ifFalse: [ aNumber ] ] { #category : #initialization } @@ -122,9 +126,9 @@ PMIterativeProcess >> precision [ { #category : #information } PMIterativeProcess >> precisionOf: aNumber1 relativeTo: aNumber2 [ - ^aNumber2 > PMFloatingPointMachine new defaultNumericalPrecision - ifTrue: [ aNumber1 / aNumber2] - ifFalse:[ aNumber1] + ^ aNumber2 > Float defaultComparisonPrecision + ifTrue: [ aNumber1 / aNumber2 ] + ifFalse: [ aNumber1 ] ] { #category : #information } diff --git a/src/Math-Distributions/PMFisherTippettDistribution.class.st b/src/Math-Distributions/PMFisherTippettDistribution.class.st index 5c035a35..413accc6 100644 --- a/src/Math-Distributions/PMFisherTippettDistribution.class.st +++ b/src/Math-Distributions/PMFisherTippettDistribution.class.st @@ -60,7 +60,7 @@ PMFisherTippettDistribution >> distributionValue: aNumber [ the receiver with a value lower than or equal to aNumber." | arg | arg := ( aNumber - alpha) / beta. - arg := arg < PMFloatingPointMachine new largestExponentArgument negated + arg := arg < Float fmax ln negated ifTrue: [ ^0] ifFalse:[arg negated exp]. ^arg negated exp @@ -126,14 +126,17 @@ PMFisherTippettDistribution >> standardDeviation [ { #category : #information } PMFisherTippettDistribution >> value: aNumber [ - "Answers the probability that a random variable distributed according to the receiver + "Answers the probability that a random variable distributed according to the receiver gives a value between aNumber and aNumber + espilon (infinitesimal interval)." + | arg | - arg := ( aNumber - alpha) / beta. - arg := arg > PMFloatingPointMachine new largestExponentArgument ifTrue: [ ^0] - ifFalse:[arg negated exp + arg]. - ^arg > PMFloatingPointMachine new largestExponentArgument ifTrue: [ 0] - ifFalse:[ arg negated exp / beta] + arg := aNumber - alpha / beta. + arg := arg > Float fmax ln + ifTrue: [ ^ 0 ] + ifFalse: [ arg negated exp + arg ]. + ^ arg > Float fmax ln + ifTrue: [ 0 ] + ifFalse: [ arg negated exp / beta ] ] { #category : #information } diff --git a/src/Math-Distributions/PMIncompleteBetaFunction.class.st b/src/Math-Distributions/PMIncompleteBetaFunction.class.st index d2f18bda..faa477c6 100644 --- a/src/Math-Distributions/PMIncompleteBetaFunction.class.st +++ b/src/Math-Distributions/PMIncompleteBetaFunction.class.st @@ -26,7 +26,7 @@ PMIncompleteBetaFunction >> evaluateFraction: aNumber [ fraction setParameter: alpha1 second: alpha2 ]. fraction setArgument: aNumber. ^ (PMContinuedFraction server: fraction) - desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; + desiredPrecision: Float defaultComparisonPrecision; evaluate ] @@ -38,7 +38,7 @@ PMIncompleteBetaFunction >> evaluateInverseFraction: aNumber [ inverseFraction setParameter: alpha2 second: alpha1 ]. inverseFraction setArgument: 1 - aNumber. ^ (PMContinuedFraction server: inverseFraction) - desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; + desiredPrecision: Float defaultComparisonPrecision; evaluate ] diff --git a/src/Math-Distributions/PMIncompleteGammaFunction.class.st b/src/Math-Distributions/PMIncompleteGammaFunction.class.st index 47e207f6..3590952a 100644 --- a/src/Math-Distributions/PMIncompleteGammaFunction.class.st +++ b/src/Math-Distributions/PMIncompleteGammaFunction.class.st @@ -24,7 +24,7 @@ PMIncompleteGammaFunction >> evaluateFraction: aNumber [ fraction setParameter: alpha ]. fraction setArgument: aNumber. ^ (PMContinuedFraction server: fraction) - desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; + desiredPrecision: Float defaultComparisonPrecision; evaluate ] @@ -36,7 +36,7 @@ PMIncompleteGammaFunction >> evaluateSeries: aNumber [ series setParameter: alpha ]. series setArgument: aNumber. ^ (PMInfiniteSeries server: series) - desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; + desiredPrecision: Float defaultComparisonPrecision; evaluate ] diff --git a/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st b/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st index 43dc664b..8bda83a9 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 2e28abb6..11c9b2d7 100644 --- a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st +++ b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st @@ -19,7 +19,8 @@ Class { { #category : #information } PMAnotherGeneticOptimizer class >> defaultPrecision [ - ^PMFloatingPointMachine new machinePrecision + + ^ Float machineEpsilon ] { #category : #'instance creation' } @@ -95,7 +96,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 +131,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 9b60de6a..2c36806f 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 a271ef4a..9a76a2f7 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 586011d5..3301ffde 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,32 @@ 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: Float machineEpsilon. + 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 +170,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 +194,7 @@ PMGeneralFunctionFit >> manager [ { #category : #accessing } PMGeneralFunctionFit >> maximumIterations: anInteger [ "default is 170." -go maximumIterations: anInteger. +geneticOptimizer maximumIterations: anInteger. ^anInteger ] @@ -207,7 +215,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 +229,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 +238,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 +280,7 @@ self data: data PMGeneralFunctionFit >> resetResult [ result :=nil. firstResult :=nil. -go resetBestPoints +geneticOptimizer resetBestPoints ] { #category : #accessing } diff --git a/src/Math-Helpers/PMFloatingPointMachine.class.st b/src/Math-Helpers/PMFloatingPointMachine.class.st deleted file mode 100644 index e1bd2453..00000000 --- a/src/Math-Helpers/PMFloatingPointMachine.class.st +++ /dev/null @@ -1,198 +0,0 @@ -" -A `PMFloatingPointMachine` represents the numerical precision of this system. - -##Instance Variables - -- `defaultNumericalPrecision` The relative numerical precision that can be expected for a general numerical computation. One should consider to numbers a and b equal if the relative difference between them is less than the default machine precision, -- `largestExponentArgument` Natural logarithm of largest number, -- `largestNumber` The largest positive number that can be represented in the machine, -- `machinePrecision` $r^{-(n+1)}$, with the largest n such that $(1 + r^{-n}) - 1$ != 0, -- `negativeMachinePrecision` $r^{-(n+1)}$, with the largest n such that $(1 - r^{-n}) - 1$ != 0, -- `radix` The radix of the floating point representation. This is often 2, -- `smallNumber` A number that can be added to some value without noticeably changing the result of the computation, -- `smallestNumber` The smallest positive number different from 0. - -This class is detailed in Object Oriented Implementation of Numerical Methods, Section 1.4.1 and 1.4.2. - -" -Class { - #name : #PMFloatingPointMachine, - #superclass : #Object, - #instVars : [ - 'defaultNumericalPrecision', - 'radix', - 'machinePrecision', - 'negativeMachinePrecision', - 'smallestNumber', - 'largestNumber', - 'smallNumber', - 'largestExponentArgument' - ], - #classVars : [ - 'UniqueInstance' - ], - #category : #'Math-Helpers' -} - -{ #category : #'instance creation' } -PMFloatingPointMachine class >> new [ - UniqueInstance ifNil: [ UniqueInstance := super new ]. - ^ UniqueInstance -] - -{ #category : #accessing } -PMFloatingPointMachine class >> reset [ - UniqueInstance := nil -] - -{ #category : #information } -PMFloatingPointMachine >> computeLargestNumber [ - - | one floatingRadix fullMantissaNumber | - one := 1.0. - floatingRadix := self radix asFloat. - fullMantissaNumber := one - ( floatingRadix * self negativeMachinePrecision). - largestNumber := fullMantissaNumber. - [ [ fullMantissaNumber := fullMantissaNumber * floatingRadix. - fullMantissaNumber isInfinite ifTrue: [^nil]. - largestNumber := fullMantissaNumber. - true] whileTrue: [ ]. - ] on: Error do: [ :signal | signal return: nil] -] - -{ #category : #information } -PMFloatingPointMachine >> computeMachinePrecision [ - - | one zero inverseRadix tmp | - one := 1.0. - zero := 0.0. - inverseRadix := one / self radix asFloat. - machinePrecision := one. - [ tmp := one + machinePrecision. - tmp - one = zero] - whileFalse:[ machinePrecision := machinePrecision * inverseRadix] -] - -{ #category : #information } -PMFloatingPointMachine >> computeNegativeMachinePrecision [ - - | one zero floatingRadix inverseRadix tmp | - one := 1.0. - zero := 0.0. - floatingRadix := self radix asFloat. - inverseRadix := one / floatingRadix. - negativeMachinePrecision := one. - [ tmp := one - negativeMachinePrecision. - tmp - one = zero] - whileFalse:[ negativeMachinePrecision := negativeMachinePrecision * inverseRadix] -] - -{ #category : #information } -PMFloatingPointMachine >> computeRadix [ - - | one zero a b tmp1 tmp2| - one := 1.0. - zero := 0.0. - a := one. - [ a := a + a. - tmp1 := a + one. - tmp2 := tmp1 - a. - tmp2 - one = zero] whileTrue:[]. - b := one. - [ b := b + b. - tmp1 := a + b. - radix := ( tmp1 - a) truncated. - radix = 0 ] whileTrue: [] -] - -{ #category : #information } -PMFloatingPointMachine >> computeSmallestNumber [ - - | one floatingRadix inverseRadix fullMantissaNumber | - one := 1 asFloat. - floatingRadix := self radix asFloat. - inverseRadix := one / floatingRadix. - fullMantissaNumber := one - (floatingRadix * self negativeMachinePrecision). - smallestNumber := fullMantissaNumber. - [[fullMantissaNumber := fullMantissaNumber * inverseRadix. - fullMantissaNumber = 0.0 ifTrue: [Error signal ]. - smallestNumber := fullMantissaNumber. - true] - whileTrue: []] - on: Error do: [:signal | signal return: nil] -] - -{ #category : #information } -PMFloatingPointMachine >> defaultNumericalPrecision [ - - defaultNumericalPrecision ifNil: [ defaultNumericalPrecision := self machinePrecision sqrt ]. - ^ defaultNumericalPrecision -] - -{ #category : #information } -PMFloatingPointMachine >> largestExponentArgument [ - - largestExponentArgument ifNil: [ largestExponentArgument := self largestNumber ln ]. - ^ largestExponentArgument -] - -{ #category : #information } -PMFloatingPointMachine >> largestNumber [ - - largestNumber ifNil: [ self computeLargestNumber ]. - ^ largestNumber -] - -{ #category : #information } -PMFloatingPointMachine >> machinePrecision [ - - machinePrecision ifNil: [ self computeMachinePrecision ]. - ^ machinePrecision -] - -{ #category : #information } -PMFloatingPointMachine >> negativeMachinePrecision [ - - negativeMachinePrecision ifNil: [ self computeNegativeMachinePrecision ]. - ^ negativeMachinePrecision -] - -{ #category : #information } -PMFloatingPointMachine >> radix [ - - radix ifNil: [ self computeRadix ]. - ^ radix -] - -{ #category : #display } -PMFloatingPointMachine >> showParameters [ - - Transcript cr; cr; - nextPutAll: 'Floating-point machine parameters'; cr; - nextPutAll: '---------------------------------';cr; - nextPutAll: 'Radix: '. - self radix printOn: Transcript. - Transcript cr; nextPutAll: 'Machine precision: '. - self machinePrecision printOn: Transcript. - Transcript cr; nextPutAll: 'Negative machine precision: '. - self negativeMachinePrecision printOn: Transcript. - Transcript cr; nextPutAll: 'Smallest number: '. - self smallestNumber printOn: Transcript. - Transcript cr; nextPutAll: 'Largest number: '. - self largestNumber printOn: Transcript. - Transcript flush -] - -{ #category : #information } -PMFloatingPointMachine >> smallNumber [ - - smallNumber ifNil: [ smallNumber := self smallestNumber sqrt ]. - ^ smallNumber -] - -{ #category : #information } -PMFloatingPointMachine >> smallestNumber [ - - smallestNumber ifNil: [ self computeSmallestNumber ]. - ^ smallestNumber -] diff --git a/src/Math-Numerical/Number.extension.st b/src/Math-Numerical/Number.extension.st index f981417c..21d7a0b1 100644 --- a/src/Math-Numerical/Number.extension.st +++ b/src/Math-Numerical/Number.extension.st @@ -62,16 +62,6 @@ Number >> logGamma [ ] ] -{ #category : #'*Math-Numerical' } -Number >> relativelyEqualsTo: aNumber upTo: aSmallNumber [ - "compare to Float>>closeTo: - generally called from Number>>equalsTo:" - | norm | - norm := self abs max: aNumber abs. - ^norm <= PMFloatingPointMachine new defaultNumericalPrecision - or: [ (self - aNumber) abs < ( aSmallNumber * norm)] -] - { #category : #'*Math-Numerical' } Number >> subtractToPolynomial: aPolynomial [ ^aPolynomial addNumber: self negated diff --git a/src/Math-Numerical/PMFunctionOptimizer.class.st b/src/Math-Numerical/PMFunctionOptimizer.class.st index d27bfaf3..bd1067f9 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 c4a4644a..f1ba8856 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' ], @@ -9,8 +12,9 @@ Class { { #category : #information } PMOneVariableFunctionOptimizer class >> defaultPrecision [ - "Private" - ^PMFloatingPointMachine new defaultNumericalPrecision * 10 + "Private" + + ^ Float defaultComparisonPrecision * 10 ] { #category : #information } @@ -24,69 +28,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 6ceb5fe4..a7cc95e0 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 5e62cd7a..13f4ee62 100644 --- a/src/Math-Numerical/PMSimplexOptimizer.class.st +++ b/src/Math-Numerical/PMSimplexOptimizer.class.st @@ -2,15 +2,18 @@ Class { #name : #PMSimplexOptimizer, #superclass : #PMFunctionOptimizer, #instVars : [ - 'worstVector' + 'worstVector', + 'randomGenerator' ], #category : #'Math-Numerical-Math-FunctionIterator' } { #category : #information } PMSimplexOptimizer class >> defaultPrecision [ - "Private" - ^PMFloatingPointMachine new defaultNumericalPrecision * 1000 + "Private" + + self flag: #todo. "In Pharo 12 the default comparision precision of Float will be improved. When Pharo 12 will be the minimal version of Polymath we can use `Float defaultComparisonPrecision" + ^ Float machineEpsilon sqrt * 1000 ] { #category : #operation } @@ -18,26 +21,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 +107,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-Polynomials/PMPolynomial.class.st b/src/Math-Polynomials/PMPolynomial.class.st index 3ba7997d..d77820df 100644 --- a/src/Math-Polynomials/PMPolynomial.class.st +++ b/src/Math-Polynomials/PMPolynomial.class.st @@ -234,7 +234,7 @@ PMPolynomial >> reciprocal [ { #category : #information } PMPolynomial >> roots [ - ^self roots: PMFloatingPointMachine new defaultNumericalPrecision + ^ self roots: Float defaultComparisonPrecision ] { #category : #information } diff --git a/src/Math-Tests-Distributions/PMStatisticsBugs.class.st b/src/Math-Tests-Distributions/PMStatisticsBugs.class.st index 2186c7d3..821a151a 100644 --- a/src/Math-Tests-Distributions/PMStatisticsBugs.class.st +++ b/src/Math-Tests-Distributions/PMStatisticsBugs.class.st @@ -4,25 +4,130 @@ Class { #category : #'Math-Tests-Distributions' } +{ #category : #tests } +PMStatisticsBugs >> testAsymptoticChiSquareDistribution [ + + | a | + a := PMAsymptoticChiSquareDistribution degreeOfFreedom: 18. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.8)) closeTo: 0.8) + "Supplied derivative is not correct" +] + { #category : #tests } PMStatisticsBugs >> testBetaDistribution [ - | d | + + | d a | d := PMBetaDistribution shape: 0.9 shape: 0.9. self assert: (d distributionValue: 1.0 successor) equals: 1. self assert: (d distributionValue: 4) equals: 1. self assert: (d distributionValue: 0.0 predecessor) equals: 0. - self assert: (d distributionValue: -2) equals: 0 + self assert: (d distributionValue: -2) equals: 0. + + a := PMBetaDistribution shape: 2 shape: 3.1. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: 0.9). + "'Function''s derivative seems to be zero everywhere'" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: 0.5). + "zerodivide" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + "ok" + self assert: ((a distributionValue: (a inverseDistributionValue: 1)) closeTo: 1). + "zerod" + a := PMBetaDistribution shape: 0.9 shape: 0.9. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: 0.9). + "'Function''s derivative seems to be zero everywhere'" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: 0.5). + "'Function''s derivative seems to be zero everywhere'" + self assert: ((a inverseDistributionValue: 0) closeTo: 0). + "zerod" + self assert: ((a inverseDistributionValue: 1) closeTo: 1). + "zerod" + a := PMBetaDistribution shape: 9 shape: 0.29. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: 0.9). + "'Function''s derivative seems to be zero everywhere'" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: 0.5). + "'Function''s derivative seems to be zero everywhere'" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + "ok" + self assert: ((a inverseDistributionValue: 1.0) closeTo: 1) + "zerod" ] { #category : #tests } PMStatisticsBugs >> testCauchyDistribution [ + | a | a := PMCauchyDistribution shape: -40.2 scale: 2.1. "this line produced an error:" - self - assert: (a inverseDistributionValue: 0) - equals: Float infinity negated. - self assert: (a inverseDistributionValue: 1) equals: Float infinity + self assert: (a inverseDistributionValue: 0) equals: Float infinity negated. + self assert: (a inverseDistributionValue: 1) equals: Float infinity. + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: 0.9). + "ok" + self assert: (a inverseDistributionValue: 0.5) equals: -40.2. + "ok" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + "zerod, which in this case is ok" + self assert: ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1) + "ok" +] + +{ #category : #tests } +PMStatisticsBugs >> testChiSquareDistribution [ + + | a | + a := PMChiSquareDistribution degreeOfFreedom: 3. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.7)) closeTo: 0.7). + "zerodivide" + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.004)) closeTo: 0.004). + "zerodivide" + + a := PMChiSquareDistribution degreeOfFreedom: 300. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.7)) closeTo: 0.7). + "'Function''s derivative seems to be zero everywhere'" + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.004)) closeTo: 0.004). + "ok" + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + "ok" + + self assert: ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1) + "zerodivide" +] + +{ #category : #tests } +PMStatisticsBugs >> testExponentialDistribution [ + + | a | + a := PMExponentialDistribution new. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.99)) closeTo: 0.99). + "ok " + self assert: ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: 0.5). + "ok" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + "ok" + self assert: ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1) + "ok" +] + +{ #category : #tests } +PMStatisticsBugs >> testFisherSnedecorDistribution [ + + | a | + a := PMFisherSnedecorDistribution degreeOfFreedom: 100 degreeOfFreedom: 200. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.8)) closeTo: 0.8). + "'Function''s derivative seems to be zero everywhere'" + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.6)) closeTo: 0.6). + "zerodivide" + + a := PMFisherSnedecorDistribution degreeOfFreedom: 5 degreeOfFreedom: 6. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.8)) closeTo: 0.8). + "'Function''s derivative seems to be zero everywhere'" + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.6)) closeTo: 0.6) + "zerodivide" ] { #category : #tests } @@ -45,317 +150,200 @@ PMStatisticsBugs >> testFisherTippet2 [ self assert: (d distributionValue: -3) equals: -1 exp ] +{ #category : #tests } +PMStatisticsBugs >> testFisherTippetDistribution [ + + | a | + a := PMFisherTippettDistribution new. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: 0.9). + "zerodivide" + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.001)) closeTo: 0.001). + "ok" + + a := PMFisherTippettDistribution shape: -3 scale: 0.7. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: 0.9). + "zerodivide" + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.4)) closeTo: 0.4). + "zerodivide" + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + "ok" + + self assert: ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1) + "zerodivide" +] + { #category : #tests } PMStatisticsBugs >> testGammaDistribution [ - | dist | + + | dist a | dist := PMGammaDistribution shape: 3.4 scale: 1.7. - self assert: (dist average - (3.4 * 1.7)) abs < 0.000000001. - self - assert: (dist standardDeviation - (3.4 sqrt * 1.7)) abs < 0.000000001. - self assert: ((dist value: 4.5) - 0.1446067652) abs < 0.000000001. - self - assert: ((dist distributionValue: 4.5) - 0.3982869736) abs < 0.000000001 + self assert: dist average - (3.4 * 1.7) closeTo: 0. + self assert: dist standardDeviation - (3.4 sqrt * 1.7) closeTo: 0. + self assert: (dist value: 4.5) - 0.1446067652 closeTo: 0. + self assert: (dist distributionValue: 4.5) - 0.3982869736 closeTo: 0. + + + a := PMGammaDistribution shape: 2 scale: 1. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.99)) closeTo: 0.99). + "'Function''s derivative seems to be zero everywhere'" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: 0.5). + "zerod" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + "zerod" + self assert: ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1) + "zerod" ] { #category : #tests } -PMStatisticsBugs >> testProbabilityDensity [ +PMStatisticsBugs >> testHistogramDistribution [ - "tests PMProbabilityDensity>>inverseDistributionValue:." + | a random b | + a := PMHistogram new. + random := Random new. - "testing this method usually produces (not always and not always the same) three different errors: 'zerodivide', ' 'Function''s derivative seems to be zero everywhere' and 'Supplied derivative is not correct', the latter happens in other cases than the documented one too, i just dont remember which ones they are and i was too lazy to construct them, one example is enough" + 20 timesRepeat: [ a accumulate: (random nextBetween: 0 and: 7) ]. - | a b random | - a := PMNormalDistribution new: -20 sigma: 0.7. - self assert: (a inverseDistributionValue: 0.5) equals: -20. - "ocassionally 'Supplied derivative is not correct'" - a := PMNormalDistribution new: 2 sigma: 0.7. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.8)) closeTo: - 0.8). - "'Function''s derivative seems to be zero everywhere'" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.6)) closeTo: - 0.6). - "zerodivide" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). - self assert: - ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1). - "zerodivide" - a := PMAsymptoticChiSquareDistribution degreeOfFreedom: 18. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.8)) closeTo: - 0.8). - "Supplied derivative is not correct" - a := PMFisherSnedecorDistribution - degreeOfFreedom: 100 - degreeOfFreedom: 200. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.8)) closeTo: - 0.8). - "'Function''s derivative seems to be zero everywhere'" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.6)) closeTo: - 0.6). - "zerodivide" - a := PMFisherSnedecorDistribution - degreeOfFreedom: 5 - degreeOfFreedom: 6. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.8)) closeTo: - 0.8). - "'Function''s derivative seems to be zero everywhere'" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.6)) closeTo: - 0.6). - "zerodivide" - a := PMFisherTippettDistribution new. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: - 0.9). - "zerodivide" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.001)) - closeTo: 0.001). + b := PMHistogrammedDistribution histogram: a. + self assert: ((b distributionValue: (b inverseDistributionValue: 0.99)) closeTo: 0.99). "ok" - a := PMFisherTippettDistribution shape: -3 scale: 0.7. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: - 0.9). - "zerodivide" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.4)) closeTo: - 0.4). - "zerodivide" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + self assert: ((b distributionValue: (b inverseDistributionValue: 0.0)) closeTo: 0). "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1). - "zerodivide" - a := PMChiSquareDistribution degreeOfFreedom: 3. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.7)) closeTo: - 0.7). - "zerodivide" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.004)) - closeTo: 0.004). - "zerodivide" - a := PMChiSquareDistribution degreeOfFreedom: 300. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.7)) closeTo: - 0.7). + self assert: ((b distributionValue: (b inverseDistributionValue: 1.0) asFloat) closeTo: 1) + "ok" +] + +{ #category : #tests } +PMStatisticsBugs >> testKernelSmoothingDensity [ + + | a | + a := PMKernelSmoothedDensity fromData: #( 1 2 3 1 2.3 2.4 ). + a epanechnikov. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: 0.9). "'Function''s derivative seems to be zero everywhere'" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.004)) - closeTo: 0.004). + self assert: ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: 0.5). + "zerod" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + " -0.13122605895944042" "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + self assert: ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1) + "zerod" +] + +{ #category : #tests } +PMStatisticsBugs >> testLeplaceDistribution [ + + | a | + a := PMLaplaceDistribution new. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.99)) closeTo: 0.99). "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1). - "zerodivide" + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + "ok" + self assert: ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1) + "zerod" +] + +{ #category : #tests } +PMStatisticsBugs >> testLogNormalDistribution [ + + | a | a := PMLogNormalDistribution new. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.7)) closeTo: - 0.7). + self assert: ((a distributionValue: (a inverseDistributionValue: 0.7)) closeTo: 0.7). "zerodivide" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.004)) - closeTo: 0.004). + self assert: ((a distributionValue: (a inverseDistributionValue: 0.004)) closeTo: 0.004). "zerodivide" a := PMLogNormalDistribution new: 3 sigma: 1.4. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.7)) closeTo: - 0.7). + self assert: ((a distributionValue: (a inverseDistributionValue: 0.7)) closeTo: 0.7). "zerodivide" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). "zerodivide" - self assert: - ((a distributionValue: (a inverseDistributionValue: 1.0)) - 1) abs - < 3e-7. + self assert: ((a distributionValue: (a inverseDistributionValue: 1.0)) - 1) abs < 3e-7. "equalsTo: is a too strong condition in this case" a := PMLogNormalDistribution new: 3 sigma: 3. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.7)) closeTo: - 0.7). + self assert: ((a distributionValue: (a inverseDistributionValue: 0.7)) closeTo: 0.7) "zerodivide" +] + +{ #category : #tests } +PMStatisticsBugs >> testNormalDistribution [ + + | a | + a := PMNormalDistribution new: -20 sigma: 0.7. + self assert: (a inverseDistributionValue: 0.5) equals: -20. + "ocassionally 'Supplied derivative is not correct'" + + a := PMNormalDistribution new: 2 sigma: 0.7. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.8)) closeTo: 0.8). + "'Function''s derivative seems to be zero everywhere'" + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.6)) closeTo: 0.6). + "zerodivide" + + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). + self assert: ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1) + "zerodivide" +] + +{ #category : #tests } +PMStatisticsBugs >> testProbabilityDensityWithUnknownDistribution [ + | d | + d := PMLogNormalDistribution new. + self assert: ((d distributionValue: 1) closeTo: 0.5). + self assert: ((d distributionValue: 3.602) closeTo: 0.9). + self assert: ((d acceptanceBetween: 1 and: 3.602) closeTo: 0.4) +] + +{ #category : #tests } +PMStatisticsBugs >> testStudentDistribution [ + + | a | a := PMStudentDistribution degreeOfFreedom: 5. - self assert: - ((a distributionValue: (a inverseDistributionValue: 1)) closeTo: 1). + self assert: ((a distributionValue: (a inverseDistributionValue: 1)) closeTo: 1). "zerodivide" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0)) closeTo: 0). + self assert: ((a distributionValue: (a inverseDistributionValue: 0)) closeTo: 0) "well, ok" +] + +{ #category : #tests } +PMStatisticsBugs >> testTriangularDistribution [ + "tests PMProbabilityDensity>>inverseDistributionValue:." + + "testing this method usually produces (not always and not always the same) three different errors: 'zerodivide', ' 'Function''s derivative seems to be zero everywhere' and 'Supplied derivative is not correct', the latter happens in other cases than the documented one too, i just dont remember which ones they are and i was too lazy to construct them, one example is enough" + + | a | a := PMTriangularDistribution new: 0.6 from: -1 to: 3. - self assert: - ((a distributionValue: (a inverseDistributionValue: 1)) closeTo: 1). + self assert: ((a distributionValue: (a inverseDistributionValue: 1)) closeTo: 1). "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0)) closeTo: 0). + self assert: ((a distributionValue: (a inverseDistributionValue: 0)) closeTo: 0) "ok" +] + +{ #category : #tests } +PMStatisticsBugs >> testUniformDistribution [ + + | a | a := PMUniformDistribution from: 0 to: 3. - self assert: - ((a distributionValue: (a inverseDistributionValue: 1)) closeTo: 1). + self assert: ((a distributionValue: (a inverseDistributionValue: 1)) closeTo: 1). "ok " - self assert: - ((a distributionValue: (a inverseDistributionValue: 0)) closeTo: 0). + self assert: ((a distributionValue: (a inverseDistributionValue: 0)) closeTo: 0). "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.333333)) - closeTo: 0.333333). + self assert: ((a distributionValue: (a inverseDistributionValue: 0.333333)) closeTo: 0.333333) "ok" - a := PMWeibullDistribution shape: 0.5 scale: 1. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.99)) closeTo: - 0.99). - "ok " - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: - 0.5). - "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). - "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1). - "ok" - a := PMExponentialDistribution new. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.99)) closeTo: - 0.99). - "ok " - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: - 0.5). - "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). - "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1). - "ok" - a := PMGammaDistribution shape: 2 scale: 1. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.99)) closeTo: - 0.99). - "'Function''s derivative seems to be zero everywhere'" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: - 0.5). - "zerod" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). - "zerod" - self assert: - ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1). - "zerod" - a := PMLaplaceDistribution new. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.99)) closeTo: - 0.99). - "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). - "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1). - "zerod" - a := PMBetaDistribution shape: 2 shape: 3.1. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: - 0.9). - "'Function''s derivative seems to be zero everywhere'" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: - 0.5). - "zerodivide" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). - "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 1)) closeTo: 1). - "zerod" - a := PMBetaDistribution shape: 0.9 shape: 0.9. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: - 0.9). - "'Function''s derivative seems to be zero everywhere'" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: - 0.5). - "'Function''s derivative seems to be zero everywhere'" - self assert: ((a inverseDistributionValue: 0) closeTo: 0). - "zerod" - self assert: ((a inverseDistributionValue: 1) closeTo: 1). - "zerod" - a := PMBetaDistribution shape: 9 shape: 0.29. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: - 0.9). - "'Function''s derivative seems to be zero everywhere'" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: - 0.5). - "'Function''s derivative seems to be zero everywhere'" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). - "ok" - self assert: ((a inverseDistributionValue: 1.0) closeTo: 1). - "zerod" - a := PMCauchyDistribution shape: -40.2 scale: 2.1. - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.9)) closeTo: - 0.9). - "ok" - self assert: (a inverseDistributionValue: 0.5) equals: -40.2. - "ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). - "zerod, which in this case is ok" - self assert: - ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1). - "ok" - - "a:=KernelSmoothedDensity fromData: #(1 2 3 1 2.3 2.4). -a epanechnikov. -self assert: ((a distributionValue: (a inverseDistributionValue: 0.9))equalsTo: 0.9)." - "'Function''s derivative seems to be zero everywhere'" - "self assert: ((a distributionValue: (a inverseDistributionValue: 0.5))equalsTo: 0.5)." - "zerod" - "self assert: ((a distributionValue: (a inverseDistributionValue: 0.0))equalsTo: 0)." - " -0.13122605895944042" - "ok" - "self assert: ((a distributionValue: (a inverseDistributionValue: 1.0))equalsTo: 1)." - "zerod" - a := PMHistogram new. - random := Random new. +] - 20 timesRepeat: [ - a accumulate: (random nextBetween: 0 and: 7) ]. +{ #category : #tests } +PMStatisticsBugs >> testWeibullDistribution [ - b := PMHistogrammedDistribution histogram: a. - self assert: - ((b distributionValue: (b inverseDistributionValue: 0.99)) closeTo: - 0.99). + | a | + a := PMWeibullDistribution shape: 0.5 scale: 1. + self assert: ((a distributionValue: (a inverseDistributionValue: 0.99)) closeTo: 0.99). + "ok " + self assert: ((a distributionValue: (a inverseDistributionValue: 0.5)) closeTo: 0.5). "ok" - self assert: - ((b distributionValue: (b inverseDistributionValue: 0.0)) closeTo: 0). + self assert: ((a distributionValue: (a inverseDistributionValue: 0.0)) closeTo: 0). "ok" - self assert: - ((b distributionValue: (b inverseDistributionValue: 1.0) asFloat) - closeTo: 1) + self assert: ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1) "ok" ] - -{ #category : #tests } -PMStatisticsBugs >> testProbabilityDensityWithUnknownDistribution [ - | d | - d := PMLogNormalDistribution new. - self assert: ((d distributionValue: 1) closeTo: 0.5). - self assert: ((d distributionValue: 3.602) closeTo: 0.9). - self assert: ((d acceptanceBetween: 1 and: 3.602) closeTo: 0.4) -] diff --git a/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st b/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st index 9918eac1..50152d1c 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 94635e18..766a3976 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 d058e1c3..39fc4cb5 100644 --- a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st +++ b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st @@ -16,25 +16,23 @@ PMGeneralFunctionFitTest >> setUp [ super setUp. PMMitchellMooreGenerator reset: 0. - "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. 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 @@ -44,11 +42,6 @@ PMGeneralFunctionFitTest >> testBasic [ PMGeneralFunctionFitTest >> testFunction [ | y | - fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. y := fit function value: 3 value: 0.1 value: 0.4. fit evaluate. self assert: ((fit function value: 3) closeTo: y) @@ -56,46 +49,33 @@ 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. - 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 ] ]. + 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 ] { #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 @@ -103,28 +83,28 @@ 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 ) + + 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 | + 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 +118,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). @@ -154,11 +136,6 @@ PMGeneralFunctionFitTest >> testRelativeError [ { #category : #tests } PMGeneralFunctionFitTest >> testResetBestPoints [ - fit := PMGeneralFunctionFit - function: f - data: col - minimumValues: 0 - maximumValues: 5. fit evaluate. fit resetBestPoints. self assertEmpty: fit optimizer bestPoints @@ -175,6 +152,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 +161,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 )). diff --git a/src/Math-Tests-Numerical/PMFloatingPointMachineTestCase.class.st b/src/Math-Tests-Numerical/PMFloatingPointMachineTestCase.class.st deleted file mode 100644 index c4e3d5b1..00000000 --- a/src/Math-Tests-Numerical/PMFloatingPointMachineTestCase.class.st +++ /dev/null @@ -1,88 +0,0 @@ -Class { - #name : #PMFloatingPointMachineTestCase, - #superclass : #TestCase, - #category : #'Math-Tests-Numerical' -} - -{ #category : #precision } -PMFloatingPointMachineTestCase >> testMachinePrecision [ - | mach | - mach := PMFloatingPointMachine new. - self assert: mach machinePrecision > 0. - self assert: mach machinePrecision < 1. - self assert: mach negativeMachinePrecision > 0. - self assert: mach negativeMachinePrecision < 1. - self - assert: (mach radix raisedTo: mach negativeMachinePrecision) - equals: 1.0. - self assert: (mach radix raisedTo: mach machinePrecision) equals: 1.0 -] - -{ #category : #precision } -PMFloatingPointMachineTestCase >> testMachinePrecisionIsFloatPrecision [ - "sanity check. Take logs to find the exponent, then compare to Float's method" - - | prec | - prec := (PMFloatingPointMachine new machinePrecision ln - / PMFloatingPointMachine new radix ln) negated. - self assert: prec equals: Float precision -] - -{ #category : #precision } -PMFloatingPointMachineTestCase >> testMachinePrecisionLargestNumberGreaterThanAnyFractionOfItself [ - | mach | - mach := PMFloatingPointMachine new. - self - assert: - mach largestNumber * (1 - mach defaultNumericalPrecision) - < mach largestNumber -] - -{ #category : #precision } -PMFloatingPointMachineTestCase >> testMachinePrecisionLargestNumberIsLargest [ - | mach | - mach := PMFloatingPointMachine new. - self - assert: mach largestNumber * (1 + mach defaultNumericalPrecision) - equals: Float infinity -] - -{ #category : #precision } -PMFloatingPointMachineTestCase >> testMachinePrecisionLargestNumberNotInfinity [ - | mach | - mach := PMFloatingPointMachine new. - self assert: mach largestNumber < Float infinity -] - -{ #category : #precision } -PMFloatingPointMachineTestCase >> testMachinePrecisionSmallNumberLargerThanSmallestNumber [ - | mach | - mach := PMFloatingPointMachine new. - self assert: mach smallestNumber < mach smallNumber -] - -{ #category : #precision } -PMFloatingPointMachineTestCase >> testMachinePrecisionSmallNumberNotZero [ - | mach | - mach := PMFloatingPointMachine new. - self assert: mach smallNumber > 0.0 -] - -{ #category : #precision } -PMFloatingPointMachineTestCase >> testMachinePrecisionSmallestNumberNotZero [ - | mach | - mach := PMFloatingPointMachine new. - self assert: mach smallestNumber > 0.0 -] - -{ #category : #precision } -PMFloatingPointMachineTestCase >> testUniqueInstance [ - - | mach1 mach2 mach3 | - mach1 := PMFloatingPointMachine new. - mach2 := PMFloatingPointMachine new. - self assert: mach1 identicalTo: mach2. - PMFloatingPointMachine reset. - mach3 := PMFloatingPointMachine new. - self shouldnt: [ mach3 == mach2 ] -] diff --git a/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st b/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st index c2ae5b13..d8975269 100644 --- a/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st +++ b/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st @@ -9,9 +9,7 @@ PMNumericalMethodsTestCase >> setUp [ "Reset the seed of the random numbers (to get consistent results)" super setUp. - PMMitchellMooreGenerator reset: 0. - "Reset the FloatingPointMachine to make coverage consistent" - PMFloatingPointMachine reset + PMMitchellMooreGenerator reset: 0 ] { #category : #'linear algebra' } @@ -32,14 +30,13 @@ PMNumericalMethodsTestCase >> testBissection [ "Code Example 5.1" | zeroFinder result | - zeroFinder := PMBisectionZeroFinder - function: [ :x | x errorFunction - 0.9 ]. + zeroFinder := PMBisectionZeroFinder function: [ :x | x errorFunction - 0.9 ]. zeroFinder setPositiveX: 10.0; setNegativeX: 0.0. result := zeroFinder evaluate. self assert: zeroFinder hasConverged. - self assert: (result - 1.28155193291605) abs < 1.0e-14 + self assert: result closeTo: 1.28155193291605 ] { #category : #'linear algebra' } @@ -95,34 +92,26 @@ PMNumericalMethodsTestCase >> testErrorFunction [ "simple cases to expect" self assert: 0 errorFunction equals: 1 / 2. - self - assert: - PMFloatingPointMachine new largestNumber errorFunction - > (1 - PMFloatingPointMachine new machinePrecision). + self assert: Float fmax errorFunction > (1 - Float machineEpsilon). "add some code to require initialize to run" PMErfApproximation reset. - self - assert: - PMFloatingPointMachine new largestNumber negated errorFunction - < PMFloatingPointMachine new smallestNumber + self assert: Float fmax negated errorFunction < Float fmin ] { #category : #estimation } PMNumericalMethodsTestCase >> testFTest [ + | accC accMM confidenceLevel | accC := PMStatisticalMoments new. - #(5.56 5.89 4.66 5.69 5.34 4.79 4.80 7.86 3.64 5.70) - do: [ :x | accC accumulate: x ]. + #( 5.56 5.89 4.66 5.69 5.34 4.79 4.80 7.86 3.64 5.70 ) do: [ :x | accC accumulate: x ]. accMM := PMStatisticalMoments new. - #(7.48 6.75 3.77 5.71 7.25 4.73 6.23 5.60 5.94 4.58) - do: [ :x | accMM accumulate: x ]. + #( 7.48 6.75 3.77 5.71 7.25 4.73 6.23 5.60 5.94 4.58 ) do: [ :x | accMM accumulate: x ]. confidenceLevel := accC fConfidenceLevel: accMM. - self assert: (accC average - 5.393) abs < 0.000000001. - self - assert: (accC standardDeviation - 1.0990809292) abs < 0.000000001. - self assert: (accMM average - 5.804) abs < 0.000000001. - self assert: (accMM standardDeviation - 1.19415428) abs < 0.000000001. - self assert: (confidenceLevel - 79.8147614536) abs < 0.000000001 + self assert: accC average - 5.393 closeTo: 0. + self assert: accC standardDeviation - 1.0990809292 closeTo: 0. + self assert: accMM average - 5.804 closeTo: 0. + self assert: accMM standardDeviation - 1.19415428 closeTo: 0. + self assert: confidenceLevel - 79.8147614536 closeTo: 0 ] { #category : #statistics } @@ -162,10 +151,8 @@ PMNumericalMethodsTestCase >> testIncompleteBetaFunction [ { #category : #'iterative algorithms' } PMNumericalMethodsTestCase >> testIncompleteGammaFunction [ - | function | - function := PMIncompleteGammaFunction shape: 2. - self - assert: ((function value: 2) - 0.59399414981) abs < 0.00000000001 + + self assert: ((PMIncompleteGammaFunction shape: 2) value: 2) - 0.59399414981 closeTo: 0 ] { #category : #'iterative algorithms' } @@ -461,15 +448,20 @@ PMNumericalMethodsTestCase >> testLineSearch3 [ This case does not require line search, should return 1. " + | xOld eps p functionBlock g0 g1 dg0 lineSearch xAnswer | - eps := PMFloatingPointMachine new defaultNumericalPrecision. + eps := Float defaultComparisonPrecision. xOld := -1.0 + eps. p := eps. - functionBlock := [ :t | 0.5 * ((t * p + xOld) + 1) squared ]. + functionBlock := [ :t | 0.5 * (t * p + xOld + 1) squared ]. g0 := functionBlock value: 0. g1 := functionBlock value: 1. dg0 := 2.0 * g0 negated. - lineSearch := PMLineSearch function: functionBlock valueAtZero: g0 derivativeAtZero: dg0 valueAtOne: g1. + lineSearch := PMLineSearch + function: functionBlock + valueAtZero: g0 + derivativeAtZero: dg0 + valueAtOne: g1. lineSearch desiredPrecision: eps. xAnswer := lineSearch evaluate. self assert: xAnswer equals: 1.0 @@ -819,9 +811,10 @@ 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. + self assert: maximum - 5 closeTo: 0. self assert: finder precision < 1.0e-6 ] @@ -848,15 +841,16 @@ 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. self assert: simplex precision < 1.0e-6. - self assert: (result at: 1) abs < 1.0e-6. - self assert: (result at: 2) abs < 1.0e-6. - self assert: (result at: 3) abs < 1.0e-6 + self assert: (result at: 1) closeTo: 0. + self assert: (result at: 2) closeTo: 0. + self assert: (result at: 3) closeTo: 0 ] { #category : #statistics } @@ -952,20 +946,18 @@ PMNumericalMethodsTestCase >> testSymmetricMatrixAdd3 [ { #category : #estimation } PMNumericalMethodsTestCase >> testTTest [ + | accC accMM confidenceLevel | accC := PMStatisticalMoments new. - #(5.56 5.89 4.66 5.69 5.34 4.79 4.80 7.86 3.64 5.70) - do: [ :x | accC accumulate: x ]. + #( 5.56 5.89 4.66 5.69 5.34 4.79 4.80 7.86 3.64 5.70 ) do: [ :x | accC accumulate: x ]. accMM := PMStatisticalMoments new. - #(7.48 6.75 3.77 5.71 7.25 4.73 6.23 5.60 5.94 4.58) - do: [ :x | accMM accumulate: x ]. + #( 7.48 6.75 3.77 5.71 7.25 4.73 6.23 5.60 5.94 4.58 ) do: [ :x | accMM accumulate: x ]. confidenceLevel := accC tConfidenceLevel: accMM. - self assert: (accC average - 5.393) abs < 0.000000001. - self - assert: (accC standardDeviation - 1.0990809292) abs < 0.000000001. - self assert: (accMM average - 5.804) abs < 0.000000001. - self assert: (accMM standardDeviation - 1.19415428) abs < 0.000000001. - self assert: (confidenceLevel - 56.6320739989) abs < 0.000000001 + self assert: accC average - 5.393 closeTo: 0. + self assert: accC standardDeviation - 1.0990809292 closeTo: 0. + self assert: accMM average - 5.804 closeTo: 0. + self assert: accMM standardDeviation - 1.19415428 closeTo: 0. + self assert: confidenceLevel - 56.6320739989 closeTo: 0 ] { #category : #'linear algebra' } diff --git a/src/Math-Tests-Polynomials/PMPolynomialTest.class.st b/src/Math-Tests-Polynomials/PMPolynomialTest.class.st index e3b49181..3b5a2fc9 100644 --- a/src/Math-Tests-Polynomials/PMPolynomialTest.class.st +++ b/src/Math-Tests-Polynomials/PMPolynomialTest.class.st @@ -234,21 +234,12 @@ PMPolynomialTest >> testPolynomialRoots [ "Code Example 5.5" | polynomial roots | - polynomial := PMPolynomial coefficients: #(-10 -13 -2 1). + polynomial := PMPolynomial coefficients: #( -10 -13 -2 1 ). roots := polynomial roots asSortedCollection asArray. self assert: roots size equals: 3. - self - assert: - ((roots at: 1) + 2) abs - < PMFloatingPointMachine new defaultNumericalPrecision. - self - assert: - ((roots at: 2) + 1) abs - < PMFloatingPointMachine new defaultNumericalPrecision. - self - assert: - ((roots at: 3) - 5) abs - < PMFloatingPointMachine new defaultNumericalPrecision + self assert: (roots at: 1) + 2 closeTo: 0. + self assert: (roots at: 2) + 1 closeTo: 0. + self assert: (roots at: 3) - 5 closeTo: 0 ] { #category : #'function evaluation' }