diff --git a/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st b/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st index 409453689..c7246fe7e 100644 --- a/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st +++ b/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st @@ -25,7 +25,7 @@ BaselineOfPolyMath >> baseline: spec [ xmlWriter: spec; vectorMatrix: spec; randomNumbers: spec. - + spec package: 'ExtendedNumberParser'; package: 'Math-Accuracy-Core'; diff --git a/src/ExtendedNumberParser/ExtendedNumberParser.class.st b/src/ExtendedNumberParser/ExtendedNumberParser.class.st index 2bc68c444..d1c7dd59b 100644 --- a/src/ExtendedNumberParser/ExtendedNumberParser.class.st +++ b/src/ExtendedNumberParser/ExtendedNumberParser.class.st @@ -10,7 +10,7 @@ An ExtendedNumberParser is extending Squeak number syntax with these rules Class { #name : #ExtendedNumberParser, #superclass : #NumberParser, - #category : 'ExtendedNumberParser' + #category : #ExtendedNumberParser } { #category : #accessing } @@ -21,7 +21,7 @@ ExtendedNumberParser >> allowPlusSign [ { #category : #accessing } ExtendedNumberParser >> exponentLetters [ "Allow uppercase exponent letter." - + ^'edqEDQ' ] @@ -76,135 +76,131 @@ ExtendedNumberParser >> nextFraction [ ExtendedNumberParser >> nextNumber [ "main method for reading a number. This one can read Float Integer and ScaledDecimal" - + | numberOfTrailingZeroInIntegerPart | base := 10. neg := self peekSignIsMinus. integerPart := self nextUnsignedIntegerOrNilBase: base. - integerPart ifNil: [(sourceStream peekFor: $.) - ifTrue: [ - "Try .1 syntax" - ^self readNumberWithoutIntegerPart] - ifFalse: [ - "This is not a regular number beginning with a digit + integerPart ifNil: [ + ^ (sourceStream peekFor: $.) + ifTrue: [ "Try .1 syntax" self readNumberWithoutIntegerPart ] + ifFalse: [ "This is not a regular number beginning with a digit It is time to check for exceptional condition NaN and Infinity" - ^self readNamedFloatOrFail]]. + self readNamedFloatOrFail ] ]. numberOfTrailingZeroInIntegerPart := nDigits - lastNonZero. - (sourceStream peekFor: $r) - ifTrue: ["r" - | oldNeg pos | - pos := sourceStream position. - (base := integerPart) < 2 - ifTrue: ["A radix currently need to be greater than 1, ungobble the r and return the integer part" - sourceStream skip: -1. - ^neg - ifTrue: [base negated] - ifFalse: [base]]. - oldNeg := neg. - self peekSignIsMinus ifTrue: [neg := neg not]. - integerPart := self nextUnsignedIntegerOrNilBase: base. - integerPart ifNil: [ - (sourceStream peekFor: $.) ifTrue: [self readNumberWithoutIntegerPartOrNil ifNotNil: [:aNumber | ^aNumber]]. - sourceStream position: pos. - ^oldNeg - ifTrue: [base negated] - ifFalse: [base]]. - numberOfTrailingZeroInIntegerPart := nDigits - lastNonZero]. + (sourceStream peekFor: $r) ifTrue: [ "r" + | oldNeg pos | + pos := sourceStream position. + (base := integerPart) < 2 ifTrue: [ "A radix currently need to be greater than 1, ungobble the r and return the integer part" + sourceStream skip: -1. + ^ neg + ifTrue: [ base negated ] + ifFalse: [ base ] ]. + oldNeg := neg. + self peekSignIsMinus ifTrue: [ neg := neg not ]. + integerPart := self nextUnsignedIntegerOrNilBase: base. + integerPart ifNil: [ + (sourceStream peekFor: $.) ifTrue: [ self readNumberWithoutIntegerPartOrNil ifNotNil: [ :aNumber | ^ aNumber ] ]. + sourceStream position: pos. + ^ oldNeg + ifTrue: [ base negated ] + ifFalse: [ base ] ]. + numberOfTrailingZeroInIntegerPart := nDigits - lastNonZero ]. ^ (sourceStream peekFor: $.) - ifTrue: [self readNumberWithFractionPartNumberOfTrailingZeroInIntegerPart: numberOfTrailingZeroInIntegerPart] - ifFalse: [self makeIntegerOrScaledInteger] + ifTrue: [ self readNumberWithFractionPartNumberOfTrailingZeroInIntegerPart: numberOfTrailingZeroInIntegerPart ] + ifFalse: [ self makeIntegerOrScaledInteger ] ] { #category : #'parsing-private' } ExtendedNumberParser >> readFractionPartNumberOfTrailingZeroInIntegerPart: numberOfTrailingZeroInIntegerPart [ "at this stage, sign integerPart and a fraction point have been read. try and form a number with a fractionPart" - + | numberOfNonZeroFractionDigits numberOfTrailingZeroInFractionPart mantissa value | fractionPart := self nextUnsignedIntegerOrNilBase: base. - fractionPart - ifNil: [ - "No fractionPart found, but can be an extended 1.e2 syntax" - integerPart ifNil: ["No integerPart, nor fractionPart found, ungobble the fraction point and raise an error" - sourceStream skip: -1. - ^self expected: 'a digit']. - fractionPart := 0. - numberOfNonZeroFractionDigits := 0. - numberOfTrailingZeroInFractionPart := 0] - ifNotNil: [. - numberOfNonZeroFractionDigits := lastNonZero. - numberOfTrailingZeroInFractionPart := nDigits - lastNonZero]. + numberOfTrailingZeroInFractionPart := fractionPart + ifNil: [ "No fractionPart found, but can be an extended 1.e2 syntax" + integerPart ifNil: [ "No integerPart, nor fractionPart found, ungobble the fraction point and raise an error" + sourceStream skip: -1. + ^ self expected: 'a digit' ]. + fractionPart := 0. + numberOfNonZeroFractionDigits := 0. + 0 ] + ifNotNil: [ + numberOfNonZeroFractionDigits := lastNonZero. + nDigits - lastNonZero ]. self readExponent. - integerPart ifNil: [integerPart := 0]. - - fractionPart isZero - ifTrue: [mantissa := integerPart - // (base raisedToInteger: numberOfTrailingZeroInIntegerPart). - exponent := exponent + numberOfTrailingZeroInIntegerPart] - ifFalse: [mantissa := integerPart - * (base raisedToInteger: numberOfNonZeroFractionDigits) + (fractionPart // (base raisedToInteger: numberOfTrailingZeroInFractionPart)). - exponent := exponent - numberOfNonZeroFractionDigits]. + integerPart ifNil: [ integerPart := 0 ]. + exponent := fractionPart isZero + ifTrue: [ + mantissa := integerPart // (base raisedToInteger: numberOfTrailingZeroInIntegerPart). + exponent + numberOfTrailingZeroInIntegerPart ] + ifFalse: [ + mantissa := integerPart * (base raisedToInteger: numberOfNonZeroFractionDigits) + + (fractionPart // (base raisedToInteger: numberOfTrailingZeroInFractionPart)). + exponent - numberOfNonZeroFractionDigits ]. value := exponent positive - ifTrue: [mantissa * (base raisedToInteger: exponent)] - ifFalse: [mantissa / (base raisedToInteger: exponent negated)]. + ifTrue: [ mantissa * (base raisedToInteger: exponent) ] + ifFalse: [ mantissa / (base raisedToInteger: exponent negated) ]. ^ neg - ifTrue: [value negated] - ifFalse: [value] + ifTrue: [ value negated ] + ifFalse: [ value ] ] { #category : #'parsing-private' } ExtendedNumberParser >> readNumberWithFractionPartNumberOfTrailingZeroInIntegerPart: numberOfTrailingZeroInIntegerPart [ "at this stage, sign integerPart and a decimal point have been read. try and form a number with a fractionPart" - + | numberOfNonZeroFractionDigits numberOfTrailingZeroInFractionPart mantissa value | fractionPart := self nextUnsignedIntegerOrNilBase: base. - fractionPart - ifNil: [ - "No fractionPart found, but can be a 1.e2 syntax" - fractionPart := 0. - numberOfNonZeroFractionDigits := 0. - numberOfTrailingZeroInFractionPart := 0] - ifNotNil: [ - numberOfNonZeroFractionDigits := lastNonZero. - numberOfTrailingZeroInFractionPart := nDigits - lastNonZero]. - self readExponent - ifFalse: [self readScale - ifTrue: [^self makeScaledDecimalWithNumberOfNonZeroFractionDigits: numberOfNonZeroFractionDigits - andNumberOfTrailingZeroInFractionPart: numberOfTrailingZeroInFractionPart]]. - - fractionPart isZero - ifTrue: [mantissa := integerPart - // (base raisedToInteger: numberOfTrailingZeroInIntegerPart). - exponent := exponent + numberOfTrailingZeroInIntegerPart] - ifFalse: [mantissa := integerPart - * (base raisedToInteger: numberOfNonZeroFractionDigits) + (fractionPart // (base raisedToInteger: numberOfTrailingZeroInFractionPart)). - exponent := exponent - numberOfNonZeroFractionDigits]. + numberOfTrailingZeroInFractionPart := fractionPart + ifNil: [ "No fractionPart found, but can be a 1.e2 syntax" + fractionPart := 0. + numberOfNonZeroFractionDigits := 0. + 0 ] + ifNotNil: [ + numberOfNonZeroFractionDigits := lastNonZero. + nDigits - lastNonZero ]. + self readExponent ifFalse: [ + self readScale ifTrue: [ + ^ self + makeScaledDecimalWithNumberOfNonZeroFractionDigits: numberOfNonZeroFractionDigits + andNumberOfTrailingZeroInFractionPart: numberOfTrailingZeroInFractionPart ] ]. + exponent := fractionPart isZero + ifTrue: [ + mantissa := integerPart // (base raisedToInteger: numberOfTrailingZeroInIntegerPart). + exponent + numberOfTrailingZeroInIntegerPart ] + ifFalse: [ + mantissa := integerPart * (base raisedToInteger: numberOfNonZeroFractionDigits) + + (fractionPart // (base raisedToInteger: numberOfTrailingZeroInFractionPart)). + exponent - numberOfNonZeroFractionDigits ]. value := self makeFloatFromMantissa: mantissa exponent: exponent base: base. ^ neg - ifTrue: [value isZero - ifTrue: [Float negativeZero] - ifFalse: [value negated]] - ifFalse: [value] + ifTrue: [ + value isZero + ifTrue: [ Float negativeZero ] + ifFalse: [ value negated ] ] + ifFalse: [ value ] ] { #category : #'parsing-private' } ExtendedNumberParser >> readNumberWithoutIntegerPart [ "at this stage, sign followed by a decimal point have been read, but no intergerPart try and form a number with a fractionPart" - + ^self readNumberWithoutIntegerPartOrNil ifNil: [ "No integer part, no fractionPart, this does not look like a number..." - ^self expected: 'a digit between 0 and 9']. + ^self expected: 'a digit between 0 and 9'] ] { #category : #'parsing-private' } ExtendedNumberParser >> readNumberWithoutIntegerPartOrNil [ "at this stage, sign followed by a decimal point have been read, but no intergerPart try and form a number with a fractionPart" - + | numberOfNonZeroFractionDigits numberOfTrailingZeroInFractionPart mantissa value | integerPart := 0. fractionPart := self nextUnsignedIntegerOrNilBase: base. diff --git a/src/Math-Accuracy-Core/PMAccuracy.class.st b/src/Math-Accuracy-Core/PMAccuracy.class.st index e8fdff98f..6a65d18c0 100644 --- a/src/Math-Accuracy-Core/PMAccuracy.class.st +++ b/src/Math-Accuracy-Core/PMAccuracy.class.st @@ -28,8 +28,8 @@ PMAccuracy class >> decimalPlaces [ ] { #category : #accessing } -PMAccuracy class >> decimalPlaces: anInteger [ -^DecimalPlaces:=anInteger +PMAccuracy class >> decimalPlaces: anInteger [ +^DecimalPlaces:=anInteger ] { #category : #util } @@ -38,20 +38,20 @@ PMAccuracy class >> floatAsShortString: aFloat [ ] { #category : #util } -PMAccuracy class >> floatAsShortString: aFloat digitCount: digitCount [ +PMAccuracy class >> floatAsShortString: aFloat digitCount: digitCount [ "essentially copied fromFloat>>absPrintOn:base:digitCount:" | fuzz x exp q fBase scale logScale xi aStream posFloat | aFloat isNaN ifTrue:[^'NaN']. aFloat =0 ifTrue:[^'0.0']. aStream:=WriteStream on:''. - posFloat :=aFloat <0 + posFloat :=aFloat <0 ifTrue:[aStream nextPut: $-.aFloat negated] ifFalse:[aFloat ]. posFloat isInfinite ifTrue: [aStream nextPutAll: 'Infinity'. ^ aStream contents]. fBase := 10.0. "x is myself normalized to [1.0, fBase), exp is my exponent" - exp := + exp := posFloat < 1.0 ifTrue: [posFloat reciprocalFloorLog: fBase] ifFalse: [posFloat floorLog: fBase]. @@ -66,21 +66,21 @@ PMAccuracy class >> floatAsShortString: aFloat digitCount: digitCount [ "round the last digit to be printed" x := 0.5 * fuzz + x. x >= fBase - ifTrue: + ifTrue: ["check if rounding has unnormalized x" x := x / fBase. exp := exp + 1]. (exp < (digitCount-1) and: [exp > (-2) ]) - ifTrue: + ifTrue: ["decimal notation" q := 0. exp < 0 ifTrue: [1 to: 1 - exp do: [:i | aStream nextPut: ('0.' at:i)]]] - ifFalse: + ifFalse: ["scientific notation" q := exp. exp := 0]. [x >= fuzz] - whileTrue: + whileTrue: ["use fuzz to track significance" xi := x asInteger. aStream nextPut: (Character digitValue: xi). @@ -89,20 +89,20 @@ PMAccuracy class >> floatAsShortString: aFloat digitCount: digitCount [ exp := exp - 1. exp = -1 ifTrue: [aStream nextPut: $.]]. [exp >= -1] - whileTrue: + whileTrue: [aStream nextPut: $0. exp := exp - 1. exp = -1 ifTrue: [aStream nextPut: $.]]. q ~= 0 - ifTrue: + ifTrue: [aStream nextPut: $e. q printOn: aStream]. ^ aStream contents ] -{ #category : #'class initialization' } -PMAccuracy class >> initialize [ -DecimalPlaces ifNil: [DecimalPlaces :=3]. +{ #category : #initialization } +PMAccuracy class >> initialize [ +DecimalPlaces ifNil: [DecimalPlaces :=3] ] { #category : #accessing } @@ -131,9 +131,9 @@ PMAccuracy >> argumentAt: aName [ ] { #category : #private } -PMAccuracy >> asArray: aCol [ - ^(aCol isCollection and: [ aCol isSequenceable and: [aCol isString not] ]) - ifTrue: [ aCol asArray ] +PMAccuracy >> asArray: aCol [ + ^(aCol isCollection and: [ aCol isSequenceable and: [aCol isString not] ]) + ifTrue: [ aCol asArray ] ifFalse: [ Array with: aCol ] ] @@ -141,21 +141,21 @@ PMAccuracy >> asArray: aCol [ PMAccuracy >> calcDeviations: aValue in: aCol max: aBoolean [ | c | c := self extremeCollection: aCol max:aBoolean . - c := aCol inject: c into: [:a :b| a with: b collect: [:a1 :b1| - aBoolean - ifTrue: [ a1 max: b1 ] + c := aCol inject: c into: [:a :b| a with: b collect: [:a1 :b1| + aBoolean + ifTrue: [ a1 max: b1 ] ifFalse: [a1 min: b1]]]. ^ c with: aValue collect: [:rr :r| self calcErrorOf: r realResult: rr ] ] { #category : #private } PMAccuracy >> calcErrorOf: aResult realResult: aRResult [ - ^ aResult = 0 - ifTrue: [aRResult =0 - ifTrue: [0] - ifFalse: [aRResult >0 + ^ aResult = 0 + ifTrue: [aRResult =0 + ifTrue: [0] + ifFalse: [aRResult >0 ifTrue: [ Float infinity] - ifFalse: [Float infinity negated ]]] + ifFalse: [Float infinity negated ]]] ifFalse:[ 100.0 * ( aRResult - aResult ) /aResult ] ] @@ -168,7 +168,7 @@ PMAccuracy >> calcResult: aName tree: aTree [ self ifSeveralterations: [aStream <<'mean '] . (self format: aResult type: 'result' postfix: nil tree: aTree)space. self ifSeveralterations: [ self streamDeviationsOfResult: aResult inCollection: c tree: aTree]. - ^ aResult + ^ aResult ] { #category : #accessing } @@ -179,9 +179,9 @@ PMAccuracy >> dataTree [ { #category : #running } PMAccuracy >> displayProgress: anArrayOfNames [ 'Checking' - displayProgressFrom: 1 - to: anArrayOfNames size - during: [ :bar | anArrayOfNames do: [ :n | + displayProgressFrom: 1 + to: anArrayOfNames size + during: [ :bar | anArrayOfNames do: [ :n | bar label: 'Checking ' , n. bar increment. self streamTest: n ] ]. @@ -191,19 +191,19 @@ PMAccuracy >> displayProgress: anArrayOfNames [ { #category : #private } PMAccuracy >> extractFromResults: theResults which: num onlyOne: aBoolean [ | aResult | - numberOfResults := aBoolean + numberOfResults := aBoolean ifTrue: [ aResult := theResults. nil ] ifFalse: [ aResult := theResults at: num. num ]. ^ aResult ] { #category : #private } -PMAccuracy >> extremeCollection: acol max:aBoolean [ +PMAccuracy >> extremeCollection: acol max:aBoolean [ |c| c := acol first. - c := c isCollection ifTrue: [c size] ifFalse: [1]. - ^ Array new: c withAll: (aBoolean - ifTrue: [ Float infinity negated ] + c := c isCollection ifTrue: [c size] ifFalse: [1]. + ^ Array new: c withAll: (aBoolean + ifTrue: [ Float infinity negated ] ifFalse: [ Float infinity ]) ] @@ -224,10 +224,9 @@ PMAccuracy >> findKey [ PMAccuracy >> format: aCollection [ |col| col:= self asArray: aCollection. - ^col collect: [ :a | a isNumber + ^col collect: [ :a | a isNumber ifTrue: [ self class floatAsShortString: a ] - ifFalse: [ a ] ]. - + ifFalse: [ a ] ] ] { #category : #printing } @@ -236,23 +235,22 @@ PMAccuracy >> format: aCollection type: aString postfix: pf [ c := self format: aCollection. aStream << aString <<': '<< (c joinUsing: (pf ifNil: [ ' , ' ] ifNotNil: [ pf , ' , ' ])). pf ifNotNil: [ aStream << pf ]. - ^aStream space. + ^aStream space ] { #category : #printing } PMAccuracy >> format: aCollection type: aString postfix: pf tree: aTree [ self format: aCollection type: aString postfix: pf. aTree at:aString put: (aCollection size=1 ifTrue:[aCollection first] ifFalse:[aCollection]). - ^aStream + ^aStream ] { #category : #private } PMAccuracy >> ifSeveralterations: aBlock [ - iterations >1 ifTrue:[ ^aBlock value ]. - + iterations >1 ifTrue:[ ^aBlock value ] ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMAccuracy >> initRest: aName [ | initializationMessage | initializationMessage := ('initialize' , aName) asSymbol. @@ -261,7 +259,7 @@ PMAccuracy >> initRest: aName [ self perform: initializationMessage ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMAccuracy >> initSubclassSelectorNames [ names := (self class allSelectorsBelow: Object) select: [ :selectorName | selectorName beginsWith: #check ] @@ -269,8 +267,10 @@ PMAccuracy >> initSubclassSelectorNames [ names := names asArray sort ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMAccuracy >> initialize [ + + super initialize. parameters := Dictionary new. arguments := Dictionary new. results := Dictionary new. @@ -278,14 +278,13 @@ PMAccuracy >> initialize [ names do: [ :name | self initRest: name ]. aStream := WriteStream with: ''. iterations := 1. - dataTree := KeyedTree new. - + dataTree := KeyedTree new ] { #category : #accessing } -PMAccuracy >> iterations: anInteger [ +PMAccuracy >> iterations: anInteger [ anInteger <1 ifTrue:[^iterations]. -^iterations :=anInteger +^iterations :=anInteger ] { #category : #accessing } @@ -325,7 +324,7 @@ PMAccuracy >> parameter: aParameter [ ifFalse: [ self error: 'parameter must be an Array' ]. (aParameter isArray and: [ aParameter size = 1 ]) ifTrue: [ self error: 'parameter of size 1 is not possible' ]. - ^ parameters at: self findKey put: aParameter + ^ parameters at: self findKey put: aParameter ] { #category : #accessing } @@ -334,7 +333,7 @@ PMAccuracy >> parameterAt: aName [ par := parameters at: aName ifAbsent: [ parameters at: 'AllTheRest' ifAbsent: [ nil ] ]. (par isCollection and: [ par isEmpty ]) ifTrue: [ par := nil ]. - ^ par + ^ par ] { #category : #running } @@ -349,7 +348,7 @@ PMAccuracy >> printOn: aStream1 [ super printOn: aStream1. self report ifEmpty: [ aStream1 nextPutAll: ' ()' ] - ifNotEmpty: [ :c | + ifNotEmpty: [ :c | aStream1 nextPutAll: ' ( @@ -364,7 +363,7 @@ PMAccuracy >> putExpectedResult: anExpectedResult totree: aTree [ e := anExpectedResult. [ (aTree at: e ifPresent: [ Array new: e size + 1 ]) ifNil: [ ^ aTree at: e put: KeyedTree new ] - ifNotNil: [ :a | + ifNotNil: [ :a | a replaceFrom: 1 to: e size @@ -377,20 +376,18 @@ PMAccuracy >> putExpectedResult: anExpectedResult totree: aTree [ { #category : #printing } PMAccuracy >> report [ - ^ aStream contents - + ^ aStream contents ] { #category : #accessing } PMAccuracy >> result: aResult [ results at: self findKey put: (self asArray: aResult). - ^ aResult - + ^ aResult ] { #category : #accessing } PMAccuracy >> resultsAt: aName [ - ^ results at: aName ifAbsent: [ results at: 'AllTheRest' ifAbsent: [ nil ] ] + ^ results at: aName ifAbsent: [ results at: 'AllTheRest' ifAbsent: [ nil ] ] ] { #category : #accessing } @@ -447,8 +444,7 @@ PMAccuracy >> severalChecksOn: aName with: anExpectedResult tree: aTree [ error := aResult isCollection ifTrue: [ aResult with: anExpectedResult collect: [ :r :e | self calcErrorOf: r realResult: e ] ] ifFalse: [ self calcErrorOf: aResult realResult: anExpectedResult ]. - (self format: error type: 'error' postfix: '%' tree: aTree) cr; cr. - + (self format: error type: 'error' postfix: '%' tree: aTree) cr; cr ] { #category : #streaming } @@ -457,7 +453,7 @@ PMAccuracy >> streamArgumentsAt: anInteger for: aName tree: aTree [ ar := self argumentAt: aName. ar ifNil: [ aStream cr ] - ifNotNil: [ :a | + ifNotNil: [ :a | (self format: (a at: anInteger) type: 'arguments' @@ -467,19 +463,19 @@ PMAccuracy >> streamArgumentsAt: anInteger for: aName tree: aTree [ { #category : #streaming } PMAccuracy >> streamDeviationsOfResult: aResult inCollection: aCollection tree: aTree [ - |sd| + |sd| self format: (self calcDeviations: aResult in: aCollection max: true) type:'+dev' postfix:'%'tree: aTree. (self format: (self calcDeviations: aResult in: aCollection max: false) type: '-dev' postfix:'%'tree: aTree) cr. - sd := aCollection first isCollection - ifTrue: [(1 to: aCollection first size) collect: [:k| (aCollection collect:[:j| j at: k ]) stdev ]. ] + sd := aCollection first isCollection + ifTrue: [(1 to: aCollection first size) collect: [:k| (aCollection collect:[:j| j at: k ]) stdev ]. ] ifFalse:[aCollection stdev]. - (self format: sd type: 'standard deviation' postfix:nil tree: aTree) cr. + (self format: sd type: 'standard deviation' postfix:nil tree: aTree) cr ] { #category : #streaming } PMAccuracy >> streamResultsFor: aName tree: aTree single: oneResult [ | anExpectedResult aNewTree | - 1 to: (self numberOfDifferentResultsAt: aName) do: [ :num | + 1 to: (self numberOfDifferentResultsAt: aName) do: [ :num | anExpectedResult := self extractFromResults: (self resultsAt: aName) which: num onlyOne: oneResult. aNewTree := oneResult ifTrue: [ aTree ] ifFalse: [ self putExpectedResult: anExpectedResult totree: aTree ]. self format: anExpectedResult type: 'expected result' postfix: nil tree: aNewTree. @@ -494,10 +490,10 @@ PMAccuracy >> streamTest: aName [ pno := self numberOfDifferentParametersAt: aName. oneResult := (self numberOfDifferentResultsAt: aName) = 1. aStream << 'test ' << aName; cr. - 1 to: pno do: [ :parameterNo | + 1 to: pno do: [ :parameterNo | pno > 1 ifTrue: [ subTree:=self streamTest: aName withParameter: parameterNo tree: namesTree ]. oneResult ifFalse: [ self tree: subTree type: 'expected result' data: (self resultsAt: aName) ]. - self streamResultsFor: aName tree: subTree single: oneResult ] + self streamResultsFor: aName tree: subTree single: oneResult ] ] { #category : #streaming } @@ -518,7 +514,7 @@ PMAccuracy >> tearDown [ ] { #category : #private } -PMAccuracy >> tree: aTree type: aString data: aData [ +PMAccuracy >> tree: aTree type: aString data: aData [ aTree at: 'type' put: aString. aTree at: 'data' put: aData. ^ aTree diff --git a/src/Math-Accuracy-ODE/PMODEAccuracy.class.st b/src/Math-Accuracy-ODE/PMODEAccuracy.class.st index 29c1dfadc..4c3d3e076 100644 --- a/src/Math-Accuracy-ODE/PMODEAccuracy.class.st +++ b/src/Math-Accuracy-ODE/PMODEAccuracy.class.st @@ -9,10 +9,10 @@ Class { 'endTime', 'standard' ], - #category : 'Math-Accuracy-ODE' + #category : #'Math-Accuracy-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #running } PMODEAccuracy class >> run [ | instance checkSelectors | instance := self new. @@ -29,29 +29,26 @@ PMODEAccuracy class >> runToXML [ writer enablePrettyPrinting; xml. - writer tag: 'accuracy' with: [ + writer tag: 'accuracy' with: [ self run keysAndValuesDo: [ :key :value | writer tag: key with: value asString]]. - ^ writer + ^ writer ] { #category : #checks } PMODEAccuracy >> checkAB2 [ ^ self checkSolverClass: PMAB2Solver systemClass: PMExplicitSystem stepperClass: PMAB2Stepper - ] { #category : #checks } PMODEAccuracy >> checkAB3 [ ^ self checkSolverClass: PMAB3Solver systemClass: PMExplicitSystem stepperClass: PMAB3Stepper - ] { #category : #checks } PMODEAccuracy >> checkAB4 [ ^ self checkSolverClass: PMAB4Solver systemClass: PMExplicitSystem stepperClass: PMAB4Stepper - ] { #category : #checks } @@ -60,8 +57,6 @@ PMODEAccuracy >> checkAM3 [ checkSolverClass: PMAM3Solver systemClass: PMImplicitSystem stepperClass: PMAM3Stepper - - ] { #category : #checks } @@ -144,7 +139,7 @@ PMODEAccuracy >> checkRungeKutta [ stepperClass: PMRungeKuttaStepper ] -{ #category : #utils } +{ #category : #utilities } PMODEAccuracy >> checkSolverClass: solverClass systemClass: systemClass stepperClass: stepperClass [ | solver stepper system | system := systemClass block: function. @@ -163,16 +158,18 @@ PMODEAccuracy >> checkTrapezoidAM2 [ { #category : #initialization } PMODEAccuracy >> initialize [ - dt :=0.09. - function := [:x :t | (t ** 4) * (t sin ** (2 * t cos)) * ( (2 * t negated) * (2 * t sin) * (t sin log) + t * (2 * t cos) * (t tan reciprocal) + 5)]. + + super initialize. + dt := 0.09. + function := [ :x :t | t ** 4 * (t sin ** (2 * t cos)) * (2 * t negated * (2 * t sin) * t sin log + t * (2 * t cos) * t tan reciprocal + 5) ]. startState := 0. - startTime := 0.3 . - endTime := Float halfPi + startTime := 0.3. + endTime := Float halfPi ] { #category : #initialization } PMODEAccuracy >> standard [ standard - ifNil: [ standard := [ :t | t ** 5 * (t sin ** (2 * t cos)) - 0.000888511 ] value: endTime ]. + ifNil: [ standard := [ :t | t ** 5 * (t sin ** (2 * t cos)) - 0.000888511 ] value: endTime ]. ^ standard ] diff --git a/src/Math-ArbitraryPrecisionFloat/Float.extension.st b/src/Math-ArbitraryPrecisionFloat/Float.extension.st index 1b0c90db2..c085a0704 100644 --- a/src/Math-ArbitraryPrecisionFloat/Float.extension.st +++ b/src/Math-ArbitraryPrecisionFloat/Float.extension.st @@ -1,7 +1,7 @@ Extension { #name : #Float } { #category : #'*Math-ArbitraryPrecisionFloat' } -Float >> asArbitraryPrecisionFloatNumBits: n [ +Float >> asArbitraryPrecisionFloatNumBits: n [ self isNaN ifTrue: [self error: 'cannot convert NaN to arbitrary precision']. self isInfinite ifTrue: [self error: 'cannot convert Infinity to arbitrary precision']. self isZero ifTrue: [^0 asArbitraryPrecisionFloatNumBits: n ]. diff --git a/src/Math-ArbitraryPrecisionFloat/Fraction.extension.st b/src/Math-ArbitraryPrecisionFloat/Fraction.extension.st index a915e1a71..9d159a9ba 100644 --- a/src/Math-ArbitraryPrecisionFloat/Fraction.extension.st +++ b/src/Math-ArbitraryPrecisionFloat/Fraction.extension.st @@ -1,7 +1,7 @@ Extension { #name : #Fraction } { #category : #'*Math-ArbitraryPrecisionFloat' } -Fraction >> asArbitraryPrecisionFloatNumBits: n [ +Fraction >> asArbitraryPrecisionFloatNumBits: n [ "Answer a Floating point with arbitrary precision close to the receiver." @@ -18,15 +18,15 @@ Fraction >> asArbitraryPrecisionFloatNumBits: n [ "If both numerator and denominator are represented exactly in floating point number, then fastest thing to do is to use hardwired float division" nBits := n + 1. - (ha < nBits and: [hb < nBits]) - ifTrue: - [^(numerator asArbitraryPrecisionFloatNumBits: n) + (ha < nBits and: [hb < nBits]) + ifTrue: + [^(numerator asArbitraryPrecisionFloatNumBits: n) inPlaceDivideBy: (denominator asArbitraryPrecisionFloatNumBits: n)]. "Shift the fraction by a power of two exponent so as to obtain a mantissa with n+1 bits. First guess is rough, the mantissa might have n+2 bits." exponent := ha - hb - nBits. - exponent > 0 + exponent > 0 ifTrue: [b := b bitShift: exponent] ifFalse: [a := a bitShift: exponent negated]. mantissa := a quo: b. @@ -34,8 +34,8 @@ Fraction >> asArbitraryPrecisionFloatNumBits: n [ hm := mantissa highBit. "Remove excess bits in the mantissa." - hm > nBits - ifTrue: + hm > nBits + ifTrue: [exponent := exponent + hm - nBits. hasTruncatedBits := hasTruncatedBits or: [mantissa anyBitOfMagnitudeFrom: 1 to: hm - nBits]. mantissa := mantissa bitShift: nBits - hm]. @@ -47,8 +47,8 @@ Fraction >> asArbitraryPrecisionFloatNumBits: n [ ifTrue: [mantissa := mantissa + 1]. "build the ArbitraryPrecisionFloat from mantissa and exponent" - ^(self positive + ^(self positive ifTrue: [mantissa asArbitraryPrecisionFloatNumBits: n] - ifFalse: [mantissa negated asArbitraryPrecisionFloatNumBits: n]) + ifFalse: [mantissa negated asArbitraryPrecisionFloatNumBits: n]) inPlaceTimesTwoPower: exponent ] diff --git a/src/Math-ArbitraryPrecisionFloat/Integer.extension.st b/src/Math-ArbitraryPrecisionFloat/Integer.extension.st index 3f7ac897e..60ff426e9 100644 --- a/src/Math-ArbitraryPrecisionFloat/Integer.extension.st +++ b/src/Math-ArbitraryPrecisionFloat/Integer.extension.st @@ -2,7 +2,7 @@ Extension { #name : #Integer } { #category : #'*Math-ArbitraryPrecisionFloat' } Integer >> asArbitraryPrecisionFloatNumBits: n [ - ^PMArbitraryPrecisionFloat + ^PMArbitraryPrecisionFloat mantissa: self exponent: 0 nBits: n diff --git a/src/Math-ArbitraryPrecisionFloat/LargePositiveInteger.extension.st b/src/Math-ArbitraryPrecisionFloat/LargePositiveInteger.extension.st index 5996f5f7e..326227488 100644 --- a/src/Math-ArbitraryPrecisionFloat/LargePositiveInteger.extension.st +++ b/src/Math-ArbitraryPrecisionFloat/LargePositiveInteger.extension.st @@ -3,6 +3,6 @@ Extension { #name : #LargePositiveInteger } { #category : #'*Math-ArbitraryPrecisionFloat' } LargePositiveInteger >> isZero [ "faster than super" - + ^false ] diff --git a/src/Math-ArbitraryPrecisionFloat/Number.extension.st b/src/Math-ArbitraryPrecisionFloat/Number.extension.st index 7981ef055..64732b228 100644 --- a/src/Math-ArbitraryPrecisionFloat/Number.extension.st +++ b/src/Math-ArbitraryPrecisionFloat/Number.extension.st @@ -1,10 +1,10 @@ Extension { #name : #Number } { #category : #'*Math-ArbitraryPrecisionFloat' } -Number >> adaptToArbitraryPrecisionFloat: rcvr andCompare: selector [ +Number >> adaptToArbitraryPrecisionFloat: rcvr andCompare: selector [ "If I am involved in comparison with a Float, convert rcvr to a Fraction. This way, no bit is lost and comparison is exact." - + ^ rcvr asTrueFraction perform: selector with: self ] @@ -17,7 +17,7 @@ Number >> adaptToArbitraryPrecisionFloat: rcvr andSend: selector [ ] { #category : #'*Math-ArbitraryPrecisionFloat' } -Number >> asArbitraryPrecisionFloatNumBits: n [ +Number >> asArbitraryPrecisionFloatNumBits: n [ self subclassResponsibility ] diff --git a/src/Math-ArbitraryPrecisionFloat/NumberParser.extension.st b/src/Math-ArbitraryPrecisionFloat/NumberParser.extension.st index f22cde6dc..fbd70e3b1 100644 --- a/src/Math-ArbitraryPrecisionFloat/NumberParser.extension.st +++ b/src/Math-ArbitraryPrecisionFloat/NumberParser.extension.st @@ -13,29 +13,33 @@ NumberParser >> makeArbitraryPrecisionFloatFromMantissa: m exponent: k base: aRa NumberParser >> nextArbitraryPrecisionFloatNumBits: numBits [ "Always make an ArbitraryPrecisionFloat whether there is a decimal point or not. Do not bother with radix scale or other things" - + | numberOfTrailingZeroInIntegerPart mantissa numberOfNonZeroFractionDigits numberOfTrailingZeroInFractionPart | base := 10. neg := self peekSignIsMinus. integerPart := self nextUnsignedIntegerBase: base. numberOfTrailingZeroInIntegerPart := nDigits - lastNonZero. - ((sourceStream peekFor: $.) and: [(fractionPart := self nextUnsignedIntegerOrNilBase: base) notNil]) - ifTrue: - [numberOfNonZeroFractionDigits := lastNonZero. - numberOfTrailingZeroInFractionPart := nDigits - lastNonZero] - ifFalse: - [fractionPart := 0. - numberOfNonZeroFractionDigits := 0. - numberOfTrailingZeroInFractionPart := 0]. + numberOfTrailingZeroInFractionPart := ((sourceStream peekFor: $.) and: [ (fractionPart := self nextUnsignedIntegerOrNilBase: base) notNil ]) + ifTrue: [ + numberOfNonZeroFractionDigits := lastNonZero. + nDigits - lastNonZero ] + ifFalse: [ + fractionPart := 0. + numberOfNonZeroFractionDigits := 0. + 0 ]. self readExponent. - fractionPart isZero - ifTrue: - [mantissa := integerPart // (base raisedToInteger: numberOfTrailingZeroInIntegerPart). - exponent := exponent + numberOfTrailingZeroInIntegerPart] - ifFalse: - [mantissa := integerPart * (base raisedToInteger: numberOfNonZeroFractionDigits) - + (fractionPart // (base raisedToInteger: numberOfTrailingZeroInFractionPart)). - exponent := exponent - numberOfNonZeroFractionDigits]. - neg ifTrue: [mantissa := mantissa negated]. - ^self makeArbitraryPrecisionFloatFromMantissa: mantissa exponent: exponent base: base numBits: numBits + exponent := fractionPart isZero + ifTrue: [ + mantissa := integerPart // (base raisedToInteger: numberOfTrailingZeroInIntegerPart). + exponent + numberOfTrailingZeroInIntegerPart ] + ifFalse: [ + mantissa := integerPart * (base raisedToInteger: numberOfNonZeroFractionDigits) + + (fractionPart // (base raisedToInteger: numberOfTrailingZeroInFractionPart)). + exponent - numberOfNonZeroFractionDigits ]. + neg ifTrue: [ mantissa := mantissa negated ]. + ^ self + makeArbitraryPrecisionFloatFromMantissa: mantissa + exponent: exponent + base: base + numBits: numBits ] diff --git a/src/Math-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloat.class.st b/src/Math-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloat.class.st index 048c23d0c..cf2def26d 100644 --- a/src/Math-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloat.class.st +++ b/src/Math-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloat.class.st @@ -28,7 +28,7 @@ Class { 'mantissa', 'biasedExponent' ], - #category : 'Math-ArbitraryPrecisionFloat' + #category : #'Math-ArbitraryPrecisionFloat' } { #category : #examples } @@ -45,7 +45,7 @@ c := a timesTwoPower: -1. k := 1. oldpi := Float pi. oldExpo := 2. - + [| am gm a2 | am := a + b timesTwoPower: -1. gm := (a * b) sqrt. @@ -55,8 +55,8 @@ oldExpo := 2. c inPlaceSubtract: (a2 - b squared timesTwoPower: k). pi := (a2 timesTwoPower: 1) / c. expo := (oldpi - pi) exponent. - expo isZero or: [expo > oldExpo or: [expo < (-1 - nBits)]]] - whileFalse: + expo isZero or: [expo > oldExpo or: [expo < (-1 - nBits)]]] + whileFalse: [oldpi := pi. oldExpo := expo. k := k + 1]. @@ -67,8 +67,8 @@ str contents ] { #category : #'instance creation' } -PMArbitraryPrecisionFloat class >> mantissa: mantisInteger exponent: expoInteger nBits: nbitsInteger [ - ^self basicNew +PMArbitraryPrecisionFloat class >> mantissa: mantisInteger exponent: expoInteger nBits: nbitsInteger [ + ^self basicNew mantissa: mantisInteger exponent: expoInteger nBits: nbitsInteger @@ -88,7 +88,7 @@ PMArbitraryPrecisionFloat class >> readFrom: aStream numBits: n [ ] { #category : #arithmetic } -PMArbitraryPrecisionFloat >> * aNumber [ +PMArbitraryPrecisionFloat >> * aNumber [ | n | aNumber class = self class ifFalse: [^ aNumber adaptToArbitraryPrecisionFloat: self andSend: #*]. @@ -98,7 +98,7 @@ PMArbitraryPrecisionFloat >> * aNumber [ ] { #category : #arithmetic } -PMArbitraryPrecisionFloat >> + aNumber [ +PMArbitraryPrecisionFloat >> + aNumber [ | n | aNumber class = self class ifFalse: [^ aNumber adaptToArbitraryPrecisionFloat: self andSend: #+]. @@ -108,7 +108,7 @@ PMArbitraryPrecisionFloat >> + aNumber [ ] { #category : #arithmetic } -PMArbitraryPrecisionFloat >> - aNumber [ +PMArbitraryPrecisionFloat >> - aNumber [ | n | aNumber class = self class ifFalse: [^ aNumber adaptToArbitraryPrecisionFloat: self andSend: #-]. @@ -118,7 +118,7 @@ PMArbitraryPrecisionFloat >> - aNumber [ ] { #category : #arithmetic } -PMArbitraryPrecisionFloat >> / aNumber [ +PMArbitraryPrecisionFloat >> / aNumber [ | n | aNumber class = self class ifFalse: [^ aNumber adaptToArbitraryPrecisionFloat: self andSend: #/]. @@ -129,39 +129,44 @@ PMArbitraryPrecisionFloat >> / aNumber [ { #category : #comparing } PMArbitraryPrecisionFloat >> < aNumber [ - aNumber class = self class ifTrue: - [self negative == aNumber negative - ifTrue: [self negative - ifTrue: [^ (self digitCompare: aNumber) > 0] - ifFalse: [^ (self digitCompare: aNumber) < 0]] - ifFalse: [^ self negative]]. + + aNumber class = self class ifTrue: [ + ^ self negative == aNumber negative + ifTrue: [ + self negative + ifTrue: [ (self digitCompare: aNumber) > 0 ] + ifFalse: [ (self digitCompare: aNumber) < 0 ] ] + ifFalse: [ self negative ] ]. ^ aNumber adaptToArbitraryPrecisionFloat: self andCompare: #< ] { #category : #comparing } PMArbitraryPrecisionFloat >> = aNumber [ - aNumber isNumber ifFalse: [^ false]. - aNumber class = self class ifTrue: - [aNumber negative == self negative - ifTrue: [^ (self digitCompare: aNumber) = 0] - ifFalse: [^ false]]. + + aNumber isNumber ifFalse: [ ^ false ]. + aNumber class = self class ifTrue: [ + ^ aNumber negative == self negative + ifTrue: [ (self digitCompare: aNumber) = 0 ] + ifFalse: [ false ] ]. ^ aNumber adaptToArbitraryPrecisionFloat: self andCompare: #= ] { #category : #comparing } PMArbitraryPrecisionFloat >> > aNumber [ - aNumber class = self class ifTrue: - [self negative == aNumber negative - ifTrue: [self negative - ifTrue: [^(self digitCompare: aNumber) < 0] - ifFalse: [^(self digitCompare: aNumber) > 0]] - ifFalse: [^ aNumber negative]]. + + aNumber class = self class ifTrue: [ + ^ self negative == aNumber negative + ifTrue: [ + self negative + ifTrue: [ (self digitCompare: aNumber) < 0 ] + ifFalse: [ (self digitCompare: aNumber) > 0 ] ] + ifFalse: [ aNumber negative ] ]. ^ aNumber adaptToArbitraryPrecisionFloat: self andCompare: #> ] { #category : #printing } PMArbitraryPrecisionFloat >> absPrintExactlyOn: aStream base: base [ - "Print my value on a stream in the given base. + "Print my value on a stream in the given base. Based upon the algorithm outlined in: Robert G. Burger and R. Kent Dybvig Printing Floating Point Numbers Quickly and Accurately @@ -178,69 +183,66 @@ PMArbitraryPrecisionFloat >> absPrintExactlyOn: aStream base: base [ exp := biasedExponent. baseExpEstimate := (self exponent * fBase reciprocalLogBase2 - 1.0e-10) ceiling. exp >= 0 - ifTrue: - [significand isPowerOfTwo - ifTrue: - [r := significand bitShift: 2 + exp. - s := 4. - mPlus := 2 * (mMinus := 1 bitShift: exp)] - ifFalse: - [r := significand bitShift: 1 + exp. - s := 2. - mPlus := mMinus := 1 bitShift: exp]] - ifFalse: - [significand isPowerOfTwo - ifTrue: - [r := significand bitShift: 2. + ifTrue: [ + mPlus := significand isPowerOfTwo + ifTrue: [ + r := significand bitShift: 2 + exp. + s := 4. + 2 * (mMinus := 1 bitShift: exp) ] + ifFalse: [ + r := significand bitShift: 1 + exp. + s := 2. + mMinus := 1 bitShift: exp ] ] + ifFalse: [ + significand isPowerOfTwo + ifTrue: [ + r := significand bitShift: 2. s := 1 bitShift: 2 - exp. mPlus := 2. - mMinus := 1] - ifFalse: - [r := significand bitShift: 1. + mMinus := 1 ] + ifFalse: [ + r := significand bitShift: 1. s := 1 bitShift: 1 - exp. - mPlus := mMinus := 1]]. + mPlus := mMinus := 1 ] ]. baseExpEstimate >= 0 - ifTrue: [s := s * (base raisedToInteger: baseExpEstimate)] - ifFalse: - [scale := base raisedToInteger: baseExpEstimate negated. + ifTrue: [ s := s * (base raisedToInteger: baseExpEstimate) ] + ifFalse: [ + scale := base raisedToInteger: baseExpEstimate negated. r := r * scale. mPlus := mPlus * scale. - mMinus := mMinus * scale]. - ((r + mPlus >= s) and: [roundingIncludesLimits or: [r + mPlus > s]]) - ifTrue: [baseExpEstimate := baseExpEstimate + 1] - ifFalse: - [r := r * base. + mMinus := mMinus * scale ]. + (r + mPlus >= s and: [ roundingIncludesLimits or: [ r + mPlus > s ] ]) + ifTrue: [ baseExpEstimate := baseExpEstimate + 1 ] + ifFalse: [ + r := r * base. mPlus := mPlus * base. - mMinus := mMinus * base]. + mMinus := mMinus * base ]. (fixedFormat := baseExpEstimate between: -3 and: 6) - ifTrue: - [decPointCount := baseExpEstimate. - baseExpEstimate <= 0 - ifTrue: [aStream nextPutAll: ('0.000000' truncateTo: 2 - baseExpEstimate)]] - ifFalse: - [decPointCount := 1]. - slowbit := 1 - s lowBit . + ifTrue: [ + decPointCount := baseExpEstimate. + baseExpEstimate <= 0 ifTrue: [ aStream nextPutAll: ('0.000000' truncateTo: 2 - baseExpEstimate) ] ] + ifFalse: [ decPointCount := 1 ]. + slowbit := 1 - s lowBit. shead := s bitShift: slowbit. - [d := (r bitShift: slowbit) // shead. + [ + d := (r bitShift: slowbit) // shead. r := r - (d * s). - (tc1 := (r <= mMinus) and: [roundingIncludesLimits or: [r < mMinus]]) | - (tc2 := (r + mPlus >= s) and: [roundingIncludesLimits or: [r + mPlus > s]])] whileFalse: - [aStream nextPut: (Character digitValue: d). - r := r * base. - mPlus := mPlus * base. - mMinus := mMinus * base. - decPointCount := decPointCount - 1. - decPointCount = 0 ifTrue: [aStream nextPut: $.]]. - tc2 ifTrue: - [(tc1 not or: [r * 2 >= s]) ifTrue: [d := d + 1]]. + (tc1 := r <= mMinus and: [ roundingIncludesLimits or: [ r < mMinus ] ]) | (tc2 := r + mPlus >= s and: [ roundingIncludesLimits or: [ r + mPlus > s ] ]) ] + whileFalse: [ + aStream nextPut: (Character digitValue: d). + r := r * base. + mPlus := mPlus * base. + mMinus := mMinus * base. + decPointCount := decPointCount - 1. + decPointCount = 0 ifTrue: [ aStream nextPut: $. ] ]. + tc2 ifTrue: [ (tc1 not or: [ r * 2 >= s ]) ifTrue: [ d := d + 1 ] ]. aStream nextPut: (Character digitValue: d). - decPointCount > 0 - ifTrue: - [decPointCount - 1 to: 1 by: -1 do: [:i | aStream nextPut: $0]. - aStream nextPutAll: '.0']. - fixedFormat ifFalse: - [aStream nextPut: $e. - aStream nextPutAll: (baseExpEstimate - 1) printString] + decPointCount > 0 ifTrue: [ + decPointCount - 1 to: 1 by: -1 do: [ :i | aStream nextPut: $0 ]. + aStream nextPutAll: '.0' ]. + fixedFormat ifFalse: [ + aStream nextPut: $e. + aStream nextPutAll: (baseExpEstimate - 1) printString ] ] { #category : #converting } @@ -258,7 +260,7 @@ PMArbitraryPrecisionFloat >> adaptToFloat: rcvr andSend: selector [ ] { #category : #converting } -PMArbitraryPrecisionFloat >> adaptToFraction: rcvr andCompare: selector [ +PMArbitraryPrecisionFloat >> adaptToFraction: rcvr andCompare: selector [ "If I am involved in comparison with a Fraction, convert myself to a Fraction. This way, no bit is lost and comparison is exact." @@ -271,7 +273,7 @@ PMArbitraryPrecisionFloat >> adaptToFraction: rcvr andSend: selector [ ] { #category : #converting } -PMArbitraryPrecisionFloat >> adaptToInteger: rcvr andCompare: selector [ +PMArbitraryPrecisionFloat >> adaptToInteger: rcvr andCompare: selector [ "If I am involved in comparison with an Integer, convert myself to a Fraction. This way, no bit is lost and comparison is exact." @@ -284,7 +286,7 @@ PMArbitraryPrecisionFloat >> adaptToInteger: rcvr andSend: selector [ ] { #category : #converting } -PMArbitraryPrecisionFloat >> adaptToScaledDecimal: rcvr andCompare: selector [ +PMArbitraryPrecisionFloat >> adaptToScaledDecimal: rcvr andCompare: selector [ "If I am involved in comparison with a ScaledDecimal, convert myself to a Fraction. This way, no bit is lost and comparison is exact." @@ -297,17 +299,17 @@ PMArbitraryPrecisionFloat >> adaptToScaledDecimal: rcvr andSend: selector [ ] { #category : #'mathematical functions' } -PMArbitraryPrecisionFloat >> agm: aNumber [ +PMArbitraryPrecisionFloat >> agm: aNumber [ "Answer the arithmetic geometric mean of self and aNumber" | a b am gm | a := self. b := aNumber. - + [am := a + b timesTwoPower: -1. "am is arithmetic mean" gm := (a * b) sqrt. "gm is geometric mean" - a = am or: [b = gm]] - whileFalse: + a = am or: [b = gm]] + whileFalse: [a := am. b := gm]. ^am @@ -320,18 +322,18 @@ PMArbitraryPrecisionFloat >> arCosh [ | arCosh x one y two | x := self asArbitraryPrecisionFloatNumBits: 16 + nBits. one := x one. - x < one ifTrue: [DomainError signal: 'cannot compute arCosh of a number less than 1']. - x = one ifTrue: [^self zero]. + x < one ifTrue: [ DomainError signal: 'cannot compute arCosh of a number less than 1' ]. + x = one ifTrue: [ ^ self zero ]. y := x - one. - y < one - ifTrue: - [y exponent * -4 >= nBits - ifTrue: [arCosh := (y powerExpansionArCoshp1Precision: y numBits) * (y timesTwoPower: 1) sqrt] - ifFalse: - [two := one timesTwoPower: 1. - arCosh := ((y * (y + two)) sqrt + y + one) ln]] - ifFalse: [arCosh := ((x squared - one) sqrt + x) ln]. - ^arCosh asArbitraryPrecisionFloatNumBits: nBits + arCosh := y < one + ifTrue: [ + y exponent * -4 >= nBits + ifTrue: [ (y powerExpansionArCoshp1Precision: y numBits) * (y timesTwoPower: 1) sqrt ] + ifFalse: [ + two := one timesTwoPower: 1. + ((y * (y + two)) sqrt + y + one) ln ] ] + ifFalse: [ ((x squared - one) sqrt + x) ln ]. + ^ arCosh asArbitraryPrecisionFloatNumBits: nBits ] { #category : #'mathematical functions' } @@ -339,17 +341,17 @@ PMArbitraryPrecisionFloat >> arSinh [ "Evaluate the area hyperbolic sine of the receiver." | arSinh x one | - self isZero ifTrue: [^self]. - self exponent negated > nBits ifTrue: [^self]. + self isZero ifTrue: [ ^ self ]. + self exponent negated > nBits ifTrue: [ ^ self ]. x := self asArbitraryPrecisionFloatNumBits: 16 + nBits. x inPlaceAbs. - self exponent * -4 >= nBits - ifTrue: [arSinh := x powerExpansionArSinhPrecision: x numBits] - ifFalse: - [one := x one. - arSinh := ((x squared + one) sqrt + x) ln]. - self negative ifTrue: [arSinh inPlaceNegated]. - ^arSinh asArbitraryPrecisionFloatNumBits: nBits + arSinh := self exponent * -4 >= nBits + ifTrue: [ x powerExpansionArSinhPrecision: x numBits ] + ifFalse: [ + one := x one. + ((x squared + one) sqrt + x) ln ]. + self negative ifTrue: [ arSinh inPlaceNegated ]. + ^ arSinh asArbitraryPrecisionFloatNumBits: nBits ] { #category : #'mathematical functions' } @@ -456,7 +458,7 @@ PMArbitraryPrecisionFloat >> arcTan: denominator [ ] { #category : #converting } -PMArbitraryPrecisionFloat >> asArbitraryPrecisionFloatNumBits: n [ +PMArbitraryPrecisionFloat >> asArbitraryPrecisionFloatNumBits: n [ ^ nBits = n ifTrue: [self] ifFalse: [self copy setPrecisionTo: n] @@ -465,7 +467,7 @@ PMArbitraryPrecisionFloat >> asArbitraryPrecisionFloatNumBits: n [ { #category : #converting } PMArbitraryPrecisionFloat >> asFloat [ "Convert to a IEEE 754 double precision floating point." - + nBits > Float precision ifTrue: [^(self copy setPrecisionTo: Float precision) asFloat]. ^mantissa asFloat timesTwoPower: biasedExponent ] @@ -482,8 +484,8 @@ PMArbitraryPrecisionFloat >> asMinimalDecimalFraction [ For example, 0.1 asMinimalDecimalFraction = (1/10)." | significand exp baseExpEstimate r s mPlus mMinus scale roundingIncludesLimits d tc1 tc2 fixedFormat decPointCount shead slowbit numerator denominator | - self isZero ifTrue: [^0]. - self negative ifTrue: [^self negated asMinimalDecimalFraction negated]. + self isZero ifTrue: [ ^ 0 ]. + self negative ifTrue: [ ^ self negated asMinimalDecimalFraction negated ]. self normalize. significand := mantissa abs. roundingIncludesLimits := significand even. @@ -492,73 +494,69 @@ PMArbitraryPrecisionFloat >> asMinimalDecimalFraction [ numerator := 0. denominator := 0. exp >= 0 - ifTrue: - [significand isPowerOfTwo - ifTrue: - [r := significand bitShift: 2 + exp. - s := 4. - mPlus := 2 * (mMinus := 1 bitShift: exp)] - ifFalse: - [r := significand bitShift: 1 + exp. - s := 2. - mPlus := mMinus := 1 bitShift: exp]] - ifFalse: - [significand isPowerOfTwo - ifTrue: - [r := significand bitShift: 2. + ifTrue: [ + mPlus := significand isPowerOfTwo + ifTrue: [ + r := significand bitShift: 2 + exp. + s := 4. + 2 * (mMinus := 1 bitShift: exp) ] + ifFalse: [ + r := significand bitShift: 1 + exp. + s := 2. + mMinus := 1 bitShift: exp ] ] + ifFalse: [ + significand isPowerOfTwo + ifTrue: [ + r := significand bitShift: 2. s := 1 bitShift: 2 - exp. mPlus := 2. - mMinus := 1] - ifFalse: - [r := significand bitShift: 1. + mMinus := 1 ] + ifFalse: [ + r := significand bitShift: 1. s := 1 bitShift: 1 - exp. - mPlus := mMinus := 1]]. + mPlus := mMinus := 1 ] ]. baseExpEstimate >= 0 - ifTrue: [s := s * (10 raisedToInteger: baseExpEstimate)] - ifFalse: - [scale := 10 raisedToInteger: baseExpEstimate negated. + ifTrue: [ s := s * (10 raisedToInteger: baseExpEstimate) ] + ifFalse: [ + scale := 10 raisedToInteger: baseExpEstimate negated. r := r * scale. mPlus := mPlus * scale. - mMinus := mMinus * scale]. - ((r + mPlus >= s) and: [roundingIncludesLimits or: [r + mPlus > s]]) - ifTrue: [baseExpEstimate := baseExpEstimate + 1] - ifFalse: - [r := r * 10. + mMinus := mMinus * scale ]. + (r + mPlus >= s and: [ roundingIncludesLimits or: [ r + mPlus > s ] ]) + ifTrue: [ baseExpEstimate := baseExpEstimate + 1 ] + ifFalse: [ + r := r * 10. mPlus := mPlus * 10. - mMinus := mMinus * 10]. + mMinus := mMinus * 10 ]. (fixedFormat := baseExpEstimate between: -3 and: 6) - ifTrue: - [decPointCount := baseExpEstimate. - baseExpEstimate <= 0 - ifTrue: [denominator := 10 raisedTo: baseExpEstimate negated]] - ifFalse: - [decPointCount := 1]. - slowbit := 1 - s lowBit . + ifTrue: [ + decPointCount := baseExpEstimate. + baseExpEstimate <= 0 ifTrue: [ denominator := 10 raisedTo: baseExpEstimate negated ] ] + ifFalse: [ decPointCount := 1 ]. + slowbit := 1 - s lowBit. shead := s bitShift: slowbit. - [d := (r bitShift: slowbit) // shead. + [ + d := (r bitShift: slowbit) // shead. r := r - (d * s). - (tc1 := (r <= mMinus) and: [roundingIncludesLimits or: [r < mMinus]]) | - (tc2 := (r + mPlus >= s) and: [roundingIncludesLimits or: [r + mPlus > s]])] whileFalse: - [numerator := 10 * numerator + d. - denominator := 10 * denominator. - r := r * 10. - mPlus := mPlus * 10. - mMinus := mMinus * 10. - decPointCount := decPointCount - 1. - decPointCount = 0 ifTrue: [denominator := 1]]. - tc2 ifTrue: - [(tc1 not or: [r * 2 >= s]) ifTrue: [d := d + 1]]. + (tc1 := r <= mMinus and: [ roundingIncludesLimits or: [ r < mMinus ] ]) | (tc2 := r + mPlus >= s and: [ roundingIncludesLimits or: [ r + mPlus > s ] ]) ] + whileFalse: [ + numerator := 10 * numerator + d. + denominator := 10 * denominator. + r := r * 10. + mPlus := mPlus * 10. + mMinus := mMinus * 10. + decPointCount := decPointCount - 1. + decPointCount = 0 ifTrue: [ denominator := 1 ] ]. + tc2 ifTrue: [ (tc1 not or: [ r * 2 >= s ]) ifTrue: [ d := d + 1 ] ]. numerator := 10 * numerator + d. denominator := 10 * denominator. - decPointCount > 0 - ifTrue: - [numerator := (10 raisedTo: decPointCount - 1) * numerator]. - fixedFormat ifFalse: - [(baseExpEstimate - 1) > 0 - ifTrue: [numerator := (10 raisedTo: baseExpEstimate - 1) * numerator] - ifFalse: [denominator := (10 raisedTo: 1 - baseExpEstimate) * (denominator max: 1)]]. - denominator < 2 ifTrue: [^numerator]. - ^numerator / denominator + decPointCount > 0 ifTrue: [ numerator := (10 raisedTo: decPointCount - 1) * numerator ]. + fixedFormat ifFalse: [ + baseExpEstimate - 1 > 0 + ifTrue: [ numerator := (10 raisedTo: baseExpEstimate - 1) * numerator ] + ifFalse: [ denominator := (10 raisedTo: 1 - baseExpEstimate) * (denominator max: 1) ] ]. + denominator < 2 ifTrue: [ ^ numerator ]. + ^ numerator / denominator ] { #category : #converting } @@ -567,7 +565,7 @@ PMArbitraryPrecisionFloat >> asTrueFraction [ "First remove lowBits from mantissa. This can save a useless division and prevent gcd: cost" self reduce. - + ^ biasedExponent >= 0 ifTrue: [self shift: mantissa by: biasedExponent] ifFalse: [ @@ -588,7 +586,6 @@ PMArbitraryPrecisionFloat >> cos [ mantissa: mantissa exponent: biasedExponent nBits: nBits) cos - ] { #category : #'mathematical functions' } @@ -612,21 +609,20 @@ PMArbitraryPrecisionFloat >> decimalPrecision [ ] { #category : #private } -PMArbitraryPrecisionFloat >> digitCompare: b [ +PMArbitraryPrecisionFloat >> digitCompare: b [ "both are positive or negative. answer +1 if i am of greater magnitude, -1 if i am of smaller magnitude, 0 if equal magnitude" - + | compare | - self isZero - ifTrue: [b isZero - ifTrue: [^ 0] - ifFalse: [^ -1]]. - b isZero - ifTrue: [^ 1]. + self isZero ifTrue: [ + ^ b isZero + ifTrue: [ 0 ] + ifFalse: [ -1 ] ]. + b isZero ifTrue: [ ^ 1 ]. compare := (self exponent - b exponent) sign. ^ compare = 0 - ifTrue: [(self abs - b abs) sign] - ifFalse: [compare] + ifTrue: [ (self abs - b abs) sign ] + ifFalse: [ compare ] ] { #category : #'mathematical functions' } @@ -652,7 +648,7 @@ PMArbitraryPrecisionFloat >> exp [ res := ri copy. n := 0. maxIter := 1 + ((nBits + 16) / p) ceiling. - [n <= maxIter] whileTrue: + [n <= maxIter] whileTrue: [n := n + 1. ri inPlaceMultiplyBy: r / n. res inPlaceAdd: ri]. @@ -666,9 +662,9 @@ PMArbitraryPrecisionFloat >> exp [ res := res asArbitraryPrecisionFloatNumBits: res numBits + 32. res inPlaceMultiplyBy: self - res ln + 1. delta := (res - oldres) exponent. - delta = 0 or: [delta <= (res exponent - nBits - 8)]] + delta = 0 or: [delta <= (res exponent - nBits - 8)]] whileFalse. - + ^res asArbitraryPrecisionFloatNumBits: nBits ] @@ -677,7 +673,7 @@ PMArbitraryPrecisionFloat >> exponent [ "anwser the floating point like exponent e, of self normalized as 1.mmmmmm * (2 raisedTo: e)" - + self isZero ifTrue: [^0]. ^biasedExponent + self numBitsInMantissa - 1 ] @@ -685,7 +681,7 @@ PMArbitraryPrecisionFloat >> exponent [ { #category : #comparing } PMArbitraryPrecisionFloat >> hash [ "Hash is reimplemented because = is implemented." - + ^ self asTrueFraction hash ] @@ -695,30 +691,30 @@ PMArbitraryPrecisionFloat >> inPlaceAbs [ ] { #category : #private } -PMArbitraryPrecisionFloat >> inPlaceAdd: b [ +PMArbitraryPrecisionFloat >> inPlaceAdd: b [ | delta | b isZero ifTrue: [^self round]. - self isZero - ifTrue: + self isZero + ifTrue: [mantissa := b mantissa. biasedExponent := b biasedExponent] - ifFalse: - [biasedExponent = b biasedExponent + ifFalse: + [biasedExponent = b biasedExponent ifTrue: [mantissa := mantissa + b mantissa] - ifFalse: + ifFalse: ["check for early truncation. beware, keep 2 bits for rounding" delta := self exponent - b exponent. - delta - 2 > (nBits max: self numBitsInMantissa) - ifFalse: - [delta negated - 2 > (nBits max: b numBitsInMantissa) - ifTrue: + delta - 2 > (nBits max: self numBitsInMantissa) + ifFalse: + [delta negated - 2 > (nBits max: b numBitsInMantissa) + ifTrue: [mantissa := b mantissa. biasedExponent := b biasedExponent] - ifFalse: + ifFalse: [delta := biasedExponent - b biasedExponent. - delta > 0 - ifTrue: + delta > 0 + ifTrue: [mantissa := (self shift: mantissa by: delta) + b mantissa. biasedExponent := biasedExponent - delta] ifFalse: [mantissa := mantissa + (self shift: b mantissa by: delta negated)]]]]]. @@ -726,27 +722,27 @@ PMArbitraryPrecisionFloat >> inPlaceAdd: b [ ] { #category : #private } -PMArbitraryPrecisionFloat >> inPlaceAddNoRound: b [ +PMArbitraryPrecisionFloat >> inPlaceAddNoRound: b [ | delta | b isZero ifTrue: [^self]. - self isZero - ifTrue: + self isZero + ifTrue: [mantissa := b mantissa. biasedExponent := b biasedExponent] - ifFalse: + ifFalse: [delta := biasedExponent - b biasedExponent. - delta isZero + delta isZero ifTrue: [mantissa := mantissa + b mantissa] - ifFalse: - [delta > 0 - ifTrue: + ifFalse: + [delta > 0 + ifTrue: [mantissa := (self shift: mantissa by: delta) + b mantissa. biasedExponent := biasedExponent - delta] ifFalse: [mantissa := mantissa + (self shift: b mantissa by: delta negated)]]] ] { #category : #private } -PMArbitraryPrecisionFloat >> inPlaceCopy: b [ +PMArbitraryPrecisionFloat >> inPlaceCopy: b [ "copy another arbitrary precision float into self" mantissa := b mantissa. @@ -755,7 +751,7 @@ PMArbitraryPrecisionFloat >> inPlaceCopy: b [ ] { #category : #private } -PMArbitraryPrecisionFloat >> inPlaceDivideBy: y [ +PMArbitraryPrecisionFloat >> inPlaceDivideBy: y [ "Reference: Accelerating Correctly Rounded Floating-Point Division when the Divisor Is Known in Advance - Nicolas Brisebarre, @@ -786,10 +782,10 @@ PMArbitraryPrecisionFloat >> inPlaceMultiplyBy: b [ ] { #category : #private } -PMArbitraryPrecisionFloat >> inPlaceMultiplyBy: b andAccumulate: c [ +PMArbitraryPrecisionFloat >> inPlaceMultiplyBy: b andAccumulate: c [ "only do rounding after the two operations. This is the traditional muladd operation in aritmetic units" - + self inPlaceMultiplyNoRoundBy: b. self inPlaceAdd: c ] @@ -797,7 +793,7 @@ PMArbitraryPrecisionFloat >> inPlaceMultiplyBy: b andAccumulate: c [ { #category : #private } PMArbitraryPrecisionFloat >> inPlaceMultiplyNoRoundBy: b [ mantissa := mantissa * b mantissa. - biasedExponent := biasedExponent + b biasedExponent. + biasedExponent := biasedExponent + b biasedExponent ] { #category : #private } @@ -814,7 +810,7 @@ PMArbitraryPrecisionFloat >> inPlaceReciprocal [ mantissa := (1 bitShift: h + nBits) + ma quo: (self shift: mantissa by: 1). biasedExponent := biasedExponent negated - h - nBits + 1. self round - + "Implementation notes: if m is a power of 2, reciprocal is trivial. Else, we have 2^h > m >2^(h-1) thus 1 < 2^h/m < 2. @@ -831,8 +827,8 @@ PMArbitraryPrecisionFloat >> inPlaceSqrt [ "Replace the receiver by its square root." | guess guessSquared delta shift | - self negative - ifTrue: + self negative + ifTrue: [^ DomainError signal: 'sqrt undefined for number less than zero.']. self isZero ifTrue: [^self]. @@ -854,34 +850,34 @@ PMArbitraryPrecisionFloat >> inPlaceSqrt [ [(guessSquared - guess - mantissa) negative ifFalse: [guess := guess - 1]]. mantissa := guess. biasedExponent := biasedExponent quo: 2. - self round + self round ] { #category : #private } -PMArbitraryPrecisionFloat >> inPlaceSubtract: b [ +PMArbitraryPrecisionFloat >> inPlaceSubtract: b [ | delta | b isZero ifTrue: [^self round]. - self isZero - ifTrue: + self isZero + ifTrue: [mantissa := b mantissa negated. biasedExponent := b biasedExponent] - ifFalse: + ifFalse: [biasedExponent = b biasedExponent ifTrue: [mantissa := mantissa - b mantissa] - ifFalse: + ifFalse: ["check for early truncation. beware, keep 2 bits for rounding" delta := self exponent - b exponent. - delta - 2 > (nBits max: self numBitsInMantissa) - ifFalse: - [delta negated - 2 > (nBits max: b numBitsInMantissa) - ifTrue: + delta - 2 > (nBits max: self numBitsInMantissa) + ifFalse: + [delta negated - 2 > (nBits max: b numBitsInMantissa) + ifTrue: [mantissa := b mantissa negated. biasedExponent := b biasedExponent] - ifFalse: + ifFalse: [delta := biasedExponent - b biasedExponent. - delta >= 0 - ifTrue: + delta >= 0 + ifTrue: [mantissa := (self shift: mantissa by: delta) - b mantissa. biasedExponent := biasedExponent - delta] ifFalse: [mantissa := mantissa - (self shift: b mantissa by: delta negated)]]]]]. @@ -889,27 +885,27 @@ PMArbitraryPrecisionFloat >> inPlaceSubtract: b [ ] { #category : #private } -PMArbitraryPrecisionFloat >> inPlaceSubtractNoRound: b [ +PMArbitraryPrecisionFloat >> inPlaceSubtractNoRound: b [ | delta | b isZero ifTrue: [^self]. - self isZero - ifTrue: + self isZero + ifTrue: [mantissa := b mantissa negated. biasedExponent := b biasedExponent] - ifFalse: + ifFalse: [delta := biasedExponent - b biasedExponent. - delta isZero + delta isZero ifTrue: [mantissa := mantissa - b mantissa] - ifFalse: - [delta >= 0 - ifTrue: + ifFalse: + [delta >= 0 + ifTrue: [mantissa := (self shift: mantissa by: delta) - b mantissa. biasedExponent := biasedExponent - delta] ifFalse: [mantissa := mantissa - (self shift: b mantissa by: delta negated)]]] ] { #category : #private } -PMArbitraryPrecisionFloat >> inPlaceTimesTwoPower: n [ +PMArbitraryPrecisionFloat >> inPlaceTimesTwoPower: n [ self isZero ifFalse: [biasedExponent := biasedExponent + n] ] @@ -932,7 +928,7 @@ PMArbitraryPrecisionFloat >> ln [ | x4 one two p res selfHighRes prec e | self <= self zero ifTrue: [DomainError signal: 'ln is only defined for x > 0.0']. - + one := self one. self = one ifTrue: [^self zero]. two := one timesTwoPower: 1. @@ -952,11 +948,11 @@ PMArbitraryPrecisionFloat >> ln [ selfHighRes := self asArbitraryPrecisionFloatNumBits: prec. (selfHighRes - one) exponent * -4 >= nBits ifTrue: [^(selfHighRes powerExpansionLnPrecision: prec) asArbitraryPrecisionFloatNumBits: nBits]. self < one ifTrue: [selfHighRes inPlaceReciprocal]. "Use ln(1/x) => - ln(x)" - x4 := (4 asArbitraryPrecisionFloatNumBits: prec) + x4 := (4 asArbitraryPrecisionFloatNumBits: prec) inPlaceDivideBy: selfHighRes; inPlaceTimesTwoPower: p negated. res := selfHighRes pi / (one agm: x4) timesTwoPower: -1. - res := selfHighRes = two + res := selfHighRes = two ifTrue: [res / (p + 1)] ifFalse: [p = 0 ifTrue: [res] ifFalse: [res - ((two asArbitraryPrecisionFloatNumBits: prec) ln * p)]]. self < one ifTrue: [res inPlaceNegated]. @@ -968,8 +964,8 @@ PMArbitraryPrecisionFloat >> mantissa [ ^mantissa ] -{ #category : #'initialize-release' } -PMArbitraryPrecisionFloat >> mantissa: m exponent: e nBits: n [ +{ #category : #initialization } +PMArbitraryPrecisionFloat >> mantissa: m exponent: e nBits: n [ mantissa := m. biasedExponent := e. nBits := n. @@ -1002,10 +998,9 @@ PMArbitraryPrecisionFloat >> naiveRaisedToInteger: n [ "Very naive algorithm: use full precision. Use only for small n" | m e | - m := mantissa raisedToInteger: n. + m := mantissa raisedToInteger: n. e := biasedExponent * n. ^(m asArbitraryPrecisionFloatNumBits: nBits) timesTwoPower: e - ] { #category : #arithmetic } @@ -1019,7 +1014,7 @@ PMArbitraryPrecisionFloat >> negative [ ] { #category : #accessing } -PMArbitraryPrecisionFloat >> nextToward: aNumber [ +PMArbitraryPrecisionFloat >> nextToward: aNumber [ "answer the nearest floating point number to self with same precision than self, toward the direction of aNumber argument. If the nearest one falls on the other side of aNumber, than answer a Number" @@ -1027,17 +1022,17 @@ PMArbitraryPrecisionFloat >> nextToward: aNumber [ | next | "if self is greater, decrease self, but never under aNumber" - self > aNumber - ifTrue: + self > aNumber + ifTrue: [next := self predecessor. - ^next >= aNumber + ^next >= aNumber ifTrue: [next] ifFalse: [aNumber]]. "if self is smaller, increase self, but never above aNumber" - self < aNumber + self < aNumber ifTrue: [next := self successor. - ^next <= aNumber + ^next <= aNumber ifTrue: [next] ifFalse: [aNumber]]. @@ -1049,15 +1044,15 @@ PMArbitraryPrecisionFloat >> nextToward: aNumber [ PMArbitraryPrecisionFloat >> normalize [ "normalize the receiver. a normalized floating point is either 0, or has mantissa highBit = nBits" - + | delta | mantissa isZero ifTrue: [biasedExponent := 0] - ifFalse: + ifFalse: [self round. delta := self numBitsInMantissa - nBits. - delta < 0 - ifTrue: + delta < 0 + ifTrue: [mantissa := self shift: mantissa by: delta negated. biasedExponent := biasedExponent + delta]] ] @@ -1078,7 +1073,7 @@ PMArbitraryPrecisionFloat >> numBitsInMantissa [ { #category : #arithmetic } PMArbitraryPrecisionFloat >> one [ - ^self class + ^self class mantissa: 1 exponent: 0 nBits: nBits @@ -1096,7 +1091,7 @@ PMArbitraryPrecisionFloat >> pi [ k := 1. oldpi := Float pi. oldExpo := 2. - + [| am gm a2 | am := a + b timesTwoPower: -1. gm := (a * b) sqrt. @@ -1106,8 +1101,8 @@ PMArbitraryPrecisionFloat >> pi [ c inPlaceSubtract: (a2 - b squared timesTwoPower: k). pi := (a2 timesTwoPower: 1) / c. expo := (oldpi - pi) exponent. - expo isZero or: [expo > oldExpo or: [expo < (-1 - nBits)]]] - whileFalse: + expo isZero or: [expo > oldExpo or: [expo < (-1 - nBits)]]] + whileFalse: [oldpi := pi. oldExpo := expo. k := k + 1]. @@ -1123,7 +1118,7 @@ PMArbitraryPrecisionFloat >> positive [ PMArbitraryPrecisionFloat >> powerExpansionArCoshp1Precision: precBits [ "Evaluate arcosh(x+1)/sqrt(2*x) for the receiver x by power series expansion. The algorithm is interesting when the receiver is close to zero" - + | one two count count2 sum term term1 term2 | one := self one. two := one timesTwoPower: 1. @@ -1132,7 +1127,7 @@ PMArbitraryPrecisionFloat >> powerExpansionArCoshp1Precision: precBits [ sum := one copy. term1 := one copy. term2 := one copy. - + [term1 inPlaceMultiplyBy: self. term1 inPlaceNegated. term2 inPlaceMultiplyBy: count2. @@ -1152,7 +1147,7 @@ PMArbitraryPrecisionFloat >> powerExpansionArCoshp1Precision: precBits [ PMArbitraryPrecisionFloat >> powerExpansionArSinhPrecision: precBits [ "Evaluate the area hypebolic sine of the receiver by power series expansion. The algorithm is interesting when the receiver is close to zero" - + | one x2 two count sum term | one := self one. two := one timesTwoPower: 1. @@ -1160,7 +1155,7 @@ PMArbitraryPrecisionFloat >> powerExpansionArSinhPrecision: precBits [ sum := one copy. term := one copy. x2 := self squared. - + [term inPlaceMultiplyBy: x2. term inPlaceMultiplyBy: count. term inPlaceDivideBy: count + one. @@ -1177,7 +1172,7 @@ PMArbitraryPrecisionFloat >> powerExpansionArTanhPrecision: precBits [ "Evaluate the area hyperbolic tangent of the receiver by power series expansion. arTanh (x) = x (1 + x^2/3 + x^4/5 + ... ) for -1 < x < 1 The algorithm is interesting when the receiver is close to zero" - + | one x2 two count sum term | one := self one. two := one timesTwoPower: 1. @@ -1185,7 +1180,7 @@ PMArbitraryPrecisionFloat >> powerExpansionArTanhPrecision: precBits [ sum := one copy. term := one copy. x2 := self squared. - + [term inPlaceMultiplyBy: x2. count inPlaceAdd: two. sum inPlaceAdd: term / count. @@ -1198,7 +1193,7 @@ PMArbitraryPrecisionFloat >> powerExpansionArTanhPrecision: precBits [ PMArbitraryPrecisionFloat >> powerExpansionArcSinPrecision: precBits [ "Evaluate the arc sine of the receiver by power series expansion. The algorithm is interesting when the receiver is close to zero" - + | one x2 two count sum term | one := self one. two := one timesTwoPower: 1. @@ -1206,7 +1201,7 @@ PMArbitraryPrecisionFloat >> powerExpansionArcSinPrecision: precBits [ sum := one copy. term := one copy. x2 := self squared. - + [term inPlaceMultiplyBy: x2. term inPlaceMultiplyBy: count. term inPlaceDivideBy: count + one. @@ -1222,7 +1217,7 @@ PMArbitraryPrecisionFloat >> powerExpansionArcTanPrecision: precBits [ "Evaluate the arc tangent of the receiver by power series expansion. arcTan (x) = x (1 - x^2/3 + x^4/5 - ... ) for -1 < x < 1 The algorithm is interesting when the receiver is close to zero" - + | count one sum term two x2 | one := self one. two := one timesTwoPower: 1. @@ -1230,7 +1225,7 @@ PMArbitraryPrecisionFloat >> powerExpansionArcTanPrecision: precBits [ sum := one copy. term := one copy. x2 := self squared. - + [term inPlaceMultiplyBy: x2. term inPlaceNegated. count inPlaceAdd: two. @@ -1244,7 +1239,7 @@ PMArbitraryPrecisionFloat >> powerExpansionArcTanPrecision: precBits [ PMArbitraryPrecisionFloat >> powerExpansionCosPrecision: precBits [ "Evaluate the cosine of the receiver by power series expansion. The algorithm is interesting when the receiver is close to zero" - + | count one sum term two x2 | one := self one. two := one timesTwoPower: 1. @@ -1252,7 +1247,7 @@ PMArbitraryPrecisionFloat >> powerExpansionCosPrecision: precBits [ sum := one copy. term := one copy. x2 := self squared. - + [term inPlaceMultiplyBy: x2. term inPlaceDivideBy: count * (count + one). term inPlaceNegated. @@ -1266,7 +1261,7 @@ PMArbitraryPrecisionFloat >> powerExpansionCosPrecision: precBits [ PMArbitraryPrecisionFloat >> powerExpansionCoshPrecision: precBits [ "Evaluate the hyperbolic cosine of the receiver by power series expansion. The algorithm is interesting when the receiver is close to zero" - + | count one sum term two x2 | one := self one. two := one timesTwoPower: 1. @@ -1274,7 +1269,7 @@ PMArbitraryPrecisionFloat >> powerExpansionCoshPrecision: precBits [ sum := one copy. term := one copy. x2 := self squared. - + [term inPlaceMultiplyBy: x2. term inPlaceDivideBy: count * (count + one). count inPlaceAdd: two. @@ -1290,7 +1285,7 @@ PMArbitraryPrecisionFloat >> powerExpansionLnPrecision: precBits [ ln ((1+y)/(1-y)) = 2 y (1 + y^2/3 + y^4/5 + ... ) = 2 ar tanh( y ) (1+y)/(1-y) = self => y = (self-1)/(self+1) This algorithm is interesting when the receiver is close to 1" - + | one | one := self one. ^((self - one)/(self + one) powerExpansionArTanhPrecision: precBits) timesTwoPower: 1 @@ -1300,14 +1295,14 @@ PMArbitraryPrecisionFloat >> powerExpansionLnPrecision: precBits [ PMArbitraryPrecisionFloat >> powerExpansionSinCosPrecision: precBits [ "Evaluate the sine and cosine of the receiver by power series expansion. The algorithm is interesting when the receiver is close to zero" - + | count one sin cos term | one := self one. count := one copy. cos := one copy. sin := self copy. term := self copy. - + [count inPlaceAdd: one. term inPlaceMultiplyBy: self; @@ -1320,7 +1315,7 @@ PMArbitraryPrecisionFloat >> powerExpansionSinCosPrecision: precBits [ inPlaceMultiplyBy: self; inPlaceDivideBy: count. sin inPlaceAdd: term. - + term exponent + precBits < sin exponent] whileFalse. ^Array with: sin with: cos ] @@ -1329,7 +1324,7 @@ PMArbitraryPrecisionFloat >> powerExpansionSinCosPrecision: precBits [ PMArbitraryPrecisionFloat >> powerExpansionSinPrecision: precBits [ "Evaluate the sine of the receiver by power series expansion. The algorithm is interesting when the receiver is close to zero" - + | count one sum term two x2 | one := self one. two := one timesTwoPower: 1. @@ -1337,7 +1332,7 @@ PMArbitraryPrecisionFloat >> powerExpansionSinPrecision: precBits [ sum := self copy. term := self copy. x2 := self squared. - + [term inPlaceMultiplyBy: x2. term inPlaceDivideBy: count * (count + one). term inPlaceNegated. @@ -1351,7 +1346,7 @@ PMArbitraryPrecisionFloat >> powerExpansionSinPrecision: precBits [ PMArbitraryPrecisionFloat >> powerExpansionSinhPrecision: precBits [ "Evaluate the hyperbolic sine of the receiver by power series expansion. The algorithm is interesting when the receiver is close to zero" - + | count one sum term two x2 | one := self one. two := one timesTwoPower: 1. @@ -1359,7 +1354,7 @@ PMArbitraryPrecisionFloat >> powerExpansionSinhPrecision: precBits [ sum := self copy. term := self copy. x2 := self squared. - + [term inPlaceMultiplyBy: x2. term inPlaceDivideBy: count * (count + one). count inPlaceAdd: two. @@ -1372,7 +1367,7 @@ PMArbitraryPrecisionFloat >> powerExpansionSinhPrecision: precBits [ PMArbitraryPrecisionFloat >> powerExpansionTanPrecision: precBits [ "Evaluate the tangent of the receiver by power series expansion. The algorithm is interesting when the receiver is close to zero" - + | count one sum term pow two x2 seidel | one := self one. two := one timesTwoPower: 1. @@ -1382,7 +1377,7 @@ PMArbitraryPrecisionFloat >> powerExpansionTanPrecision: precBits [ x2 := self squared. seidel := OrderedCollection new: 256. seidel add: 1. - + [pow inPlaceMultiplyBy: x2. pow inPlaceDivideBy: count * (count + one). count inPlaceAdd: two. @@ -1401,7 +1396,7 @@ PMArbitraryPrecisionFloat >> powerExpansionTanPrecision: precBits [ PMArbitraryPrecisionFloat >> powerExpansionTanhPrecision: precBits [ "Evaluate the hyperbolic tangent of the receiver by power series expansion. The algorithm is interesting when the receiver is close to zero" - + | count one sum term pow two x2 seidel | one := self one. two := one timesTwoPower: 1. @@ -1411,7 +1406,7 @@ PMArbitraryPrecisionFloat >> powerExpansionTanhPrecision: precBits [ x2 := self squared. seidel := OrderedCollection new: 256. seidel add: 1. - + [pow inPlaceMultiplyBy: x2. pow inPlaceDivideBy: count * (count + one). pow inPlaceNegated. @@ -1447,7 +1442,7 @@ PMArbitraryPrecisionFloat >> printOn: aStream [ ] { #category : #printing } -PMArbitraryPrecisionFloat >> printOn: aStream base: base [ +PMArbitraryPrecisionFloat >> printOn: aStream base: base [ aStream nextPut: $(; nextPutAll: self class name; @@ -1469,7 +1464,7 @@ PMArbitraryPrecisionFloat >> printOn: aStream base: base [ ] { #category : #arithmetic } -PMArbitraryPrecisionFloat >> raisedToInteger: anInteger [ +PMArbitraryPrecisionFloat >> raisedToInteger: anInteger [ | bitProbe highPrecisionSelf n result | n := anInteger abs. (n < 5 or: [n * nBits < 512]) @@ -1477,11 +1472,11 @@ PMArbitraryPrecisionFloat >> raisedToInteger: anInteger [ bitProbe := 1 bitShift: n highBit - 1. highPrecisionSelf := self asArbitraryPrecisionFloatNumBits: n highBit * 2 + nBits + 2. result := highPrecisionSelf one. - + [(n bitAnd: bitProbe) = 0 ifFalse: [result := result * highPrecisionSelf]. (bitProbe := bitProbe bitShift: -1) > 0] whileTrue: [result := result squared]. - + ^ (anInteger negative ifTrue: [result reciprocal] ifFalse: [result]) @@ -1514,7 +1509,7 @@ PMArbitraryPrecisionFloat >> round [ | excess ma carry | mantissa isZero - ifTrue: [ + ifTrue: [ biasedExponent := 0. ^ self ]. ma := mantissa abs. @@ -1530,8 +1525,8 @@ PMArbitraryPrecisionFloat >> round [ self truncate ] -{ #category : #'initialize-release' } -PMArbitraryPrecisionFloat >> setPrecisionTo: n [ +{ #category : #initialization } +PMArbitraryPrecisionFloat >> setPrecisionTo: n [ nBits := n. self round ] @@ -1539,7 +1534,7 @@ PMArbitraryPrecisionFloat >> setPrecisionTo: n [ { #category : #private } PMArbitraryPrecisionFloat >> shift: m by: d [ "shift mantissa m absolute value by some d bits, then restore sign" - + ^m negative ifTrue: [(m negated bitShift: d) negated] ifFalse: [m bitShift: d] @@ -1567,7 +1562,6 @@ PMArbitraryPrecisionFloat >> sin [ mantissa: mantissa exponent: biasedExponent nBits: nBits) sin - ] { #category : #'mathematical functions' } @@ -1576,7 +1570,6 @@ PMArbitraryPrecisionFloat >> sincos [ mantissa: mantissa exponent: biasedExponent nBits: nBits) sincos - ] { #category : #'mathematical functions' } @@ -1599,15 +1592,15 @@ PMArbitraryPrecisionFloat >> sqrt [ "Answer the square root of the receiver." | decimalPlaces n norm guess previousGuess one stopIteration | - self negative - ifTrue: + self negative + ifTrue: [^ DomainError signal: 'sqrt undefined for number less than zero.']. self isZero ifTrue: [^self]. "use additional bits" decimalPlaces := nBits + 16. n := self asArbitraryPrecisionFloatNumBits: decimalPlaces. - + "constants" one := n one. @@ -1616,14 +1609,14 @@ PMArbitraryPrecisionFloat >> sqrt [ n := n timesTwoPower: norm * -2. "Initial guess for sqrt(1/n)" - previousGuess := self class + previousGuess := self class mantissa: 3 exponent: -2 - (n exponent quo: 2) nBits: decimalPlaces. guess := previousGuess copy. "use iterations x(k+1) := x*( 1 + (1-x*x*n)/2) to guess sqrt(1/n)" - + [guess inPlaceMultiplyNoRoundBy: guess. guess inPlaceMultiplyBy: n. guess inPlaceNegated. @@ -1636,8 +1629,8 @@ PMArbitraryPrecisionFloat >> sqrt [ guess inPlaceMultiplyNoRoundBy: previousGuess. guess negative ifTrue: [guess inPlaceNegated]. - guess isZero or: [stopIteration]] - whileFalse: + guess isZero or: [stopIteration]] + whileFalse: [guess round. previousGuess inPlaceCopy: guess]. @@ -1677,7 +1670,6 @@ PMArbitraryPrecisionFloat >> tan [ mantissa: mantissa exponent: biasedExponent nBits: nBits) tan - ] { #category : #'mathematical functions' } @@ -1699,7 +1691,7 @@ PMArbitraryPrecisionFloat >> tanh [ ] { #category : #arithmetic } -PMArbitraryPrecisionFloat >> timesTwoPower: n [ +PMArbitraryPrecisionFloat >> timesTwoPower: n [ ^ self isZero ifTrue: [self] ifFalse: [self copy inPlaceTimesTwoPower: n] @@ -1720,8 +1712,8 @@ PMArbitraryPrecisionFloat >> truncate [ { #category : #converting } PMArbitraryPrecisionFloat >> truncated [ "answer the integer that is nearest to self in the interval between zero and self" - - ^biasedExponent negated > self numBitsInMantissa + + ^biasedExponent negated > self numBitsInMantissa ifTrue: [0] ifFalse: [self shift: mantissa by: biasedExponent] ] @@ -1734,7 +1726,7 @@ PMArbitraryPrecisionFloat >> ulp [ { #category : #arithmetic } PMArbitraryPrecisionFloat >> zero [ - ^self class + ^self class mantissa: 0 exponent: 0 nBits: nBits diff --git a/src/Math-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloatForTrigonometry.class.st b/src/Math-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloatForTrigonometry.class.st index df6f75c49..b5e823e60 100644 --- a/src/Math-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloatForTrigonometry.class.st +++ b/src/Math-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloatForTrigonometry.class.st @@ -14,7 +14,7 @@ Class { #instVars : [ 'pi' ], - #category : 'Math-ArbitraryPrecisionFloat' + #category : #'Math-ArbitraryPrecisionFloat' } { #category : #private } @@ -25,22 +25,27 @@ PMArbitraryPrecisionFloatForTrigonometry >> cos [ x := self moduloNegPiToPi. x inPlaceAbs. halfPi := pi timesTwoPower: -1. - (neg := x > halfPi) ifTrue: [x inPlaceSubtract: pi; inPlaceNegated]. + (neg := x > halfPi) ifTrue: [ + x + inPlaceSubtract: pi; + inPlaceNegated ]. quarterPi := halfPi timesTwoPower: -1. - x > quarterPi - ifTrue: - [x inPlaceSubtract: halfPi; inPlaceNegated. - x := self sin: x] - ifFalse: [x := self cos: x]. - neg ifTrue: [x inPlaceNegated]. - ^x asArbitraryPrecisionFloatNumBits: nBits + x := x > quarterPi + ifTrue: [ + x + inPlaceSubtract: halfPi; + inPlaceNegated. + self sin: x ] + ifFalse: [ self cos: x ]. + neg ifTrue: [ x inPlaceNegated ]. + ^ x asArbitraryPrecisionFloatNumBits: nBits ] { #category : #private } PMArbitraryPrecisionFloatForTrigonometry >> cos: x [ "Evaluate the cosine of x by recursive cos(2x) formula and power series expansion. Note that it is better to use this method with x <= pi/4." - + | one cos fraction power | x isZero ifTrue: [^x one]. power := ((nBits bitShift: -1) + x exponent max: 0) highBit. @@ -98,21 +103,26 @@ PMArbitraryPrecisionFloatForTrigonometry >> sin [ neg := x negative. x inPlaceAbs. halfPi := pi timesTwoPower: -1. - x > halfPi ifTrue: [x inPlaceSubtract: pi; inPlaceNegated]. + x > halfPi ifTrue: [ + x + inPlaceSubtract: pi; + inPlaceNegated ]. quarterPi := halfPi timesTwoPower: -1. - x > quarterPi - ifTrue: - [x inPlaceSubtract: halfPi; inPlaceNegated. - x := self cos: x] - ifFalse: [x := self sin: x]. - neg ifTrue: [x inPlaceNegated]. - ^x asArbitraryPrecisionFloatNumBits: nBits + x := x > quarterPi + ifTrue: [ + x + inPlaceSubtract: halfPi; + inPlaceNegated. + self cos: x ] + ifFalse: [ self sin: x ]. + neg ifTrue: [ x inPlaceNegated ]. + ^ x asArbitraryPrecisionFloatNumBits: nBits ] { #category : #private } PMArbitraryPrecisionFloatForTrigonometry >> sin: x [ "Evaluate the sine of x by sin(5x) formula and power series expansion." - + | sin sin2 sin4 fifth five | x isZero ifTrue: [^x zero]. five := 5 asArbitraryPrecisionFloatNumBits: x numBits. @@ -138,24 +148,28 @@ PMArbitraryPrecisionFloatForTrigonometry >> sincos [ sinneg := x negative. x inPlaceAbs. halfPi := pi timesTwoPower: -1. - (cosneg := x > halfPi) ifTrue: [x inPlaceSubtract: pi; inPlaceNegated]. + (cosneg := x > halfPi) ifTrue: [ + x + inPlaceSubtract: pi; + inPlaceNegated ]. quarterPi := halfPi timesTwoPower: -1. - x > quarterPi - ifTrue: - [x inPlaceSubtract: halfPi; inPlaceNegated. - sincos := (self sincos: x) reversed] - ifFalse: - [sincos := self sincos: x]. - sinneg ifTrue: [sincos first inPlaceNegated]. - cosneg ifTrue: [sincos last inPlaceNegated]. - ^sincos collect: [:e | e asArbitraryPrecisionFloatNumBits: nBits] + sincos := x > quarterPi + ifTrue: [ + x + inPlaceSubtract: halfPi; + inPlaceNegated. + (self sincos: x) reversed ] + ifFalse: [ self sincos: x ]. + sinneg ifTrue: [ sincos first inPlaceNegated ]. + cosneg ifTrue: [ sincos last inPlaceNegated ]. + ^ sincos collect: [ :e | e asArbitraryPrecisionFloatNumBits: nBits ] ] { #category : #private } PMArbitraryPrecisionFloatForTrigonometry >> sincos: x [ "Evaluate the sine and cosine of x by recursive sin(2x) and cos(2x) formula and power series expansion. Note that it is better to use this method with x <= pi/4." - + | one sin cos sincos fraction power | x isZero ifTrue: [^Array with: x zero with: x one]. power := ((nBits bitShift: -1) + x exponent max: 0) highBit. @@ -181,22 +195,24 @@ PMArbitraryPrecisionFloatForTrigonometry >> tan [ neg := x negative. x inPlaceAbs. halfPi := pi timesTwoPower: -1. - (x > halfPi) - ifTrue: - [x inPlaceSubtract: pi; inPlaceNegated. - neg := neg not]. - x exponent * -4 >= nBits - ifTrue: [tan := x powerExpansionTanPrecision: x numBits] - ifFalse: - [quarterPi := halfPi timesTwoPower: -1. - x > quarterPi - ifTrue: - [x inPlaceSubtract: halfPi; inPlaceNegated. - sincos := (self sincos: x) reversed] - ifFalse: - [sincos := self sincos: x]. - sincos first inPlaceDivideBy: sincos last. - tan := sincos first]. - neg ifTrue: [tan inPlaceNegated]. - ^tan asArbitraryPrecisionFloatNumBits: nBits + x > halfPi ifTrue: [ + x + inPlaceSubtract: pi; + inPlaceNegated. + neg := neg not ]. + tan := x exponent * -4 >= nBits + ifTrue: [ x powerExpansionTanPrecision: x numBits ] + ifFalse: [ + quarterPi := halfPi timesTwoPower: -1. + sincos := x > quarterPi + ifTrue: [ + x + inPlaceSubtract: halfPi; + inPlaceNegated. + (self sincos: x) reversed ] + ifFalse: [ self sincos: x ]. + sincos first inPlaceDivideBy: sincos last. + sincos first ]. + neg ifTrue: [ tan inPlaceNegated ]. + ^ tan asArbitraryPrecisionFloatNumBits: nBits ] diff --git a/src/Math-AutomaticDifferenciation/PMDualNumber.class.st b/src/Math-AutomaticDifferenciation/PMDualNumber.class.st index d41b785e0..7f8f60d04 100644 --- a/src/Math-AutomaticDifferenciation/PMDualNumber.class.st +++ b/src/Math-AutomaticDifferenciation/PMDualNumber.class.st @@ -71,7 +71,7 @@ PMDualNumber >> < aDualNumber [ ^ value < aDualNumber value ] -{ #category : #testing } +{ #category : #comparing } PMDualNumber >> = aMagnitude [ ^ aMagnitude = value ] @@ -79,7 +79,6 @@ PMDualNumber >> = aMagnitude [ { #category : #arithmetic } PMDualNumber >> abs [ ^value<0 ifTrue:[self negated]ifFalse:[self] - ] { #category : #arithmetic } @@ -106,15 +105,15 @@ PMDualNumber >> addDualNumber: aDualNumber [ { #category : #'mathematical functions' } PMDualNumber >> arcCos [ - ^ self class - value: value arcCos + ^ self class + value: value arcCos eps: eps negated / (1 - value squared)sqrt ] { #category : #'mathematical functions' } PMDualNumber >> arcSin [ - ^ self class - value: value arcSin + ^ self class + value: value arcSin eps: eps / (1 - value squared)sqrt ] @@ -136,7 +135,7 @@ PMDualNumber >> asInteger [ { #category : #comparing } PMDualNumber >> closeTo: aDualNumber [ - ^ (value closeTo: aDualNumber value) and: [ + ^ (value closeTo: aDualNumber value) and: [ eps closeTo: aDualNumber eps ] ] @@ -170,7 +169,7 @@ PMDualNumber >> equalsTo: aDualNumber [ deprecated: 'Use closeTo: instead' transformWith: '`@rec equalsTo: `@arg' -> '`@rec closeTo: `@arg'. - ^ self closeTo: aDualNumber + ^ self closeTo: aDualNumber ] { #category : #testing } @@ -205,14 +204,9 @@ PMDualNumber >> isNaN [ ^ value isNaN ] -{ #category : #testing } -PMDualNumber >> isNumber [ -^true -] - { #category : #testing } PMDualNumber >> isZero [ - ^value = 0 + ^value = 0 ] { #category : #'mathematical functions' } @@ -320,8 +314,8 @@ PMDualNumber >> squared [ { #category : #'mathematical functions' } PMDualNumber >> tan [ - ^ self class - value: value tan + ^ self class + value: value tan eps: eps / value cos squared ] diff --git a/src/Math-AutomaticDifferenciation/PMGradient.class.st b/src/Math-AutomaticDifferenciation/PMGradient.class.st index 135ff3051..93752a5b7 100644 --- a/src/Math-AutomaticDifferenciation/PMGradient.class.st +++ b/src/Math-AutomaticDifferenciation/PMGradient.class.st @@ -28,11 +28,11 @@ PMGradient >> function: aBlock [ ] { #category : #printing } -PMGradient >> printOn: aStream [ +PMGradient >> printOn: aStream [ aStream nextPutAll: self class name; nextPutAll: ' of: ' ; - print: function + print: function ] { #category : #accessing } @@ -40,7 +40,7 @@ PMGradient >> value: anArray [ | dualValueTemplate dualValue | dualValueTemplate := anArray collect: [ :i | PMDualNumber value: i ]. ^ (1 to: anArray size) - collect: [ :i | + collect: [ :i | dualValue := dualValueTemplate deepCopy. (dualValue at: i) eps: 1. (function value: dualValue) eps ] diff --git a/src/Math-AutomaticDifferenciation/PMHessian.class.st b/src/Math-AutomaticDifferenciation/PMHessian.class.st index e020f0442..83a2d6d79 100644 --- a/src/Math-AutomaticDifferenciation/PMHessian.class.st +++ b/src/Math-AutomaticDifferenciation/PMHessian.class.st @@ -16,7 +16,7 @@ Class { 'result', 'gradient' ], - #category : 'Math-AutomaticDifferenciation' + #category : #'Math-AutomaticDifferenciation' } { #category : #'instance creation' } @@ -36,11 +36,11 @@ PMHessian >> gradient [ ] { #category : #printing } -PMHessian >> printOn: aStream [ +PMHessian >> printOn: aStream [ aStream nextPutAll: self class name; nextPutAll: ' of: ' ; - print: function + print: function ] { #category : #accessing } @@ -55,15 +55,15 @@ PMHessian >> value: anArray [ hDualValueTemplate := anArray collect: [ :i | PMHyperDualNumber value: i ]. ^ result := PMSymmetricMatrix new: anArray size - function: [ :x :y | + function: [ :x :y | | r | hDualValue := hDualValueTemplate deepCopy. x = y - ifTrue: [ + ifTrue: [ (hDualValue at: x) eps: 1; eps2: 1 ] - ifFalse: [ + ifFalse: [ (hDualValue at: x) eps: 1. (hDualValue at: y) eps2: 1 ]. r := function value: hDualValue. diff --git a/src/Math-AutomaticDifferenciation/PMHyperDualNumber.class.st b/src/Math-AutomaticDifferenciation/PMHyperDualNumber.class.st index 6693484d7..2453881cf 100644 --- a/src/Math-AutomaticDifferenciation/PMHyperDualNumber.class.st +++ b/src/Math-AutomaticDifferenciation/PMHyperDualNumber.class.st @@ -33,8 +33,8 @@ PMHyperDualNumber >> * aHyperDualNumber [ |r| r := super * aHyperDualNumber. aHyperDualNumber isDualNumber - ifFalse:[ r eps2:eps2 * aHyperDualNumber; eps1eps2: eps1eps2 * aHyperDualNumber] - ifTrue: [r eps2: eps2 * aHyperDualNumber value + (aHyperDualNumber eps2 *value); + ifFalse:[ r eps2:eps2 * aHyperDualNumber; eps1eps2: eps1eps2 * aHyperDualNumber] + ifTrue: [r eps2: eps2 * aHyperDualNumber value + (aHyperDualNumber eps2 *value); eps1eps2: value * aHyperDualNumber eps1eps2 +(eps * aHyperDualNumber eps2)+(eps2 * aHyperDualNumber eps)+(eps1eps2 * aHyperDualNumber value)]. ^ r ] @@ -44,7 +44,7 @@ PMHyperDualNumber >> + aHyperDualNumber [ |r| r := super + aHyperDualNumber. aHyperDualNumber isDualNumber - ifFalse:[ r eps2:eps2; eps1eps2: eps1eps2] + ifFalse:[ r eps2:eps2; eps1eps2: eps1eps2] ifTrue: [r eps2: eps2 + aHyperDualNumber eps2; eps1eps2: eps1eps2 + aHyperDualNumber eps1eps2]. ^ r ] @@ -54,14 +54,14 @@ PMHyperDualNumber >> - aHyperDualNumber [ |r| r := super - aHyperDualNumber. aHyperDualNumber isDualNumber - ifFalse: [ r eps2: eps2; eps1eps2: eps1eps2] + ifFalse: [ r eps2: eps2; eps1eps2: eps1eps2] ifTrue: [ r eps2: eps2 - aHyperDualNumber eps2; eps1eps2: eps1eps2 - aHyperDualNumber eps1eps2]. ^ r ] { #category : #arithmetic } PMHyperDualNumber >> / aHyperDualNumber [ - ^self * aHyperDualNumber reciprocal + ^self * aHyperDualNumber reciprocal ] { #category : #'mathematical functions' } @@ -99,8 +99,8 @@ PMHyperDualNumber >> arcTan [ { #category : #comparing } PMHyperDualNumber >> closeTo: aHyperDualNumber [ - ^ (super closeTo: aHyperDualNumber) and: [ - (eps2 closeTo: aHyperDualNumber eps2) and: [ + ^ (super closeTo: aHyperDualNumber) and: [ + (eps2 closeTo: aHyperDualNumber eps2) and: [ eps1eps2 closeTo: aHyperDualNumber eps1eps2 ] ] ] diff --git a/src/Math-Benchmarks-KDTree/PMKDTreeBenchmark.class.st b/src/Math-Benchmarks-KDTree/PMKDTreeBenchmark.class.st index a5f6df24e..70aeeabcf 100644 --- a/src/Math-Benchmarks-KDTree/PMKDTreeBenchmark.class.st +++ b/src/Math-Benchmarks-KDTree/PMKDTreeBenchmark.class.st @@ -28,26 +28,25 @@ PMKDTreeBenchmark class >> defaultProblemSize [ PMKDTreeBenchmark class >> fastRun: nIterations with: aSequentalCollectionClass [ "omits the slow StupidNNSearch, that generally isnt interesting" |b| -(b:=self new) - selectedBenchmarks: +(b:=self new) + selectedBenchmarks: { #benchBuildTree1Dim. #benchBuildTree4Dim. #benchSearchTree1Dim. #benchSearchTree4Dim}; collType: aSequentalCollectionClass . -^self defaultRunner execute: b with: nIterations. - +^self defaultRunner execute: b with: nIterations. ] { #category : #benchmarking } PMKDTreeBenchmark class >> run: nIterations with: aSequentalCollectionClass [ |b| (b:=self new) collType: aSequentalCollectionClass . -^self defaultRunner execute: b with: nIterations. +^self defaultRunner execute: b with: nIterations. ] { #category : #benchmarking } PMKDTreeBenchmark >> benchBuildAndSearchStupidNN1Dim [ | n s | s := PMStupidNN withAll: r. - 1 to: self class defaultProblemSize do: [ :v | + 1 to: self class defaultProblemSize do: [ :v | n := 1.0 / v. s nnSearch: (collType with: n) i: 10 ] ] @@ -56,7 +55,7 @@ PMKDTreeBenchmark >> benchBuildAndSearchStupidNN1Dim [ PMKDTreeBenchmark >> benchBuildAndSearchStupidNN4Dim [ | n s | s := PMStupidNN withAll: m. - 1 to: self class defaultProblemSize do: [ :v | + 1 to: self class defaultProblemSize do: [ :v | n := 1.0 / v. s nnSearch: @@ -70,18 +69,18 @@ PMKDTreeBenchmark >> benchBuildAndSearchStupidNN4Dim [ { #category : #benchmarking } PMKDTreeBenchmark >> benchBuildTree1Dim [ - bTree :=PMIndexedKDTree withAll: r. + bTree :=PMIndexedKDTree withAll: r ] { #category : #benchmarking } PMKDTreeBenchmark >> benchBuildTree4Dim [ - aTree :=PMIndexedKDTree withAll: m. + aTree :=PMIndexedKDTree withAll: m ] { #category : #benchmarking } PMKDTreeBenchmark >> benchSearchTree1Dim [ | n | - 1 to: self class defaultProblemSize do: [ :v | + 1 to: self class defaultProblemSize do: [ :v | n := 1.0 / v. bTree nnSearch: (collType with: n) i: 10 ] ] @@ -89,7 +88,7 @@ PMKDTreeBenchmark >> benchSearchTree1Dim [ { #category : #benchmarking } PMKDTreeBenchmark >> benchSearchTree4Dim [ | n | - 1 to: self class defaultProblemSize do: [ :v | + 1 to: self class defaultProblemSize do: [ :v | n := 1.0 / v. aTree nnSearch: @@ -106,7 +105,7 @@ PMKDTreeBenchmark >> collType: aSequencableCollectionClass [ ^ collType := aSequencableCollectionClass ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMKDTreeBenchmark >> initialize [ super initialize. collType := Float32Array. diff --git a/src/Math-Benchmarks-ODE/PMExplicitBenchmark.class.st b/src/Math-Benchmarks-ODE/PMExplicitBenchmark.class.st index 35e31aba9..bde4c66b8 100644 --- a/src/Math-Benchmarks-ODE/PMExplicitBenchmark.class.st +++ b/src/Math-Benchmarks-ODE/PMExplicitBenchmark.class.st @@ -4,7 +4,7 @@ Class { #instVars : [ 'system' ], - #category : 'Math-Benchmarks-ODE' + #category : #'Math-Benchmarks-ODE' } { #category : #benchmarking } @@ -12,7 +12,7 @@ PMExplicitBenchmark >> benchEuler [ | solver stepper | stepper := PMExplicitStepper onSystem: system. solver := (PMExplicitSolver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -21,7 +21,7 @@ PMExplicitBenchmark >> benchHeun [ | solver stepper | stepper := PMHeunStepper onSystem: system. solver := (PMExplicitSolver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -30,7 +30,7 @@ PMExplicitBenchmark >> benchMidpoint [ | solver stepper | stepper := PMMidpointStepper onSystem: system. solver := (PMExplicitSolver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -39,13 +39,12 @@ PMExplicitBenchmark >> benchRungeKutta [ | solver stepper | stepper := PMRungeKuttaStepper onSystem: system. solver := (PMExplicitSolver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] { #category : #running } PMExplicitBenchmark >> setUp [ super setUp. - system := PMExplicitSystem block: function. - + system := PMExplicitSystem block: function ] diff --git a/src/Math-Benchmarks-ODE/PMExplicitMultiBenchmark.class.st b/src/Math-Benchmarks-ODE/PMExplicitMultiBenchmark.class.st index fbe88cfe7..95b6e928f 100644 --- a/src/Math-Benchmarks-ODE/PMExplicitMultiBenchmark.class.st +++ b/src/Math-Benchmarks-ODE/PMExplicitMultiBenchmark.class.st @@ -4,7 +4,7 @@ Class { #instVars : [ 'system' ], - #category : 'Math-Benchmarks-ODE' + #category : #'Math-Benchmarks-ODE' } { #category : #benchmarking } @@ -12,7 +12,7 @@ PMExplicitMultiBenchmark >> benchAB2 [ | solver stepper | stepper := PMAB2Stepper onSystem: system. solver := (PMAB2Solver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -21,7 +21,7 @@ PMExplicitMultiBenchmark >> benchAB3 [ | solver stepper | stepper := PMAB3Stepper onSystem: system. solver := (PMAB3Solver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -30,11 +30,11 @@ PMExplicitMultiBenchmark >> benchAB4 [ | solver stepper | stepper := PMAB4Stepper onSystem: system. solver := (PMAB4Solver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] -{ #category : #'as yet unclassified' } +{ #category : #running } PMExplicitMultiBenchmark >> setUp [ super setUp. system := PMExplicitSystem block: function diff --git a/src/Math-Benchmarks-ODE/PMImplicitBenchmark.class.st b/src/Math-Benchmarks-ODE/PMImplicitBenchmark.class.st index e01560b3b..427cca6f9 100644 --- a/src/Math-Benchmarks-ODE/PMImplicitBenchmark.class.st +++ b/src/Math-Benchmarks-ODE/PMImplicitBenchmark.class.st @@ -4,7 +4,7 @@ Class { #instVars : [ 'system' ], - #category : 'Math-Benchmarks-ODE' + #category : #'Math-Benchmarks-ODE' } { #category : #benchmarking } @@ -12,7 +12,7 @@ PMImplicitBenchmark >> benchBeckwardEuler [ | solver stepper | stepper := PMImplicitStepper onSystem: system. solver := (PMImplicitSolver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -21,12 +21,12 @@ PMImplicitBenchmark >> benchImplicitMidpoint [ | solver stepper | stepper := PMImplicitMidpointStepper onSystem: system. solver := (PMImplicitMidpointSolver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] -{ #category : #'as yet unclassified' } +{ #category : #running } PMImplicitBenchmark >> setUp [ super setUp. - system := PMImplicitSystem block: function. + system := PMImplicitSystem block: function ] diff --git a/src/Math-Benchmarks-ODE/PMImplicitMultiBenchmark.class.st b/src/Math-Benchmarks-ODE/PMImplicitMultiBenchmark.class.st index 9e532a512..8ba51424e 100644 --- a/src/Math-Benchmarks-ODE/PMImplicitMultiBenchmark.class.st +++ b/src/Math-Benchmarks-ODE/PMImplicitMultiBenchmark.class.st @@ -4,7 +4,7 @@ Class { #instVars : [ 'system' ], - #category : 'Math-Benchmarks-ODE' + #category : #'Math-Benchmarks-ODE' } { #category : #benchmarking } @@ -12,7 +12,7 @@ PMImplicitMultiBenchmark >> benchAM3 [ | solver stepper | stepper := PMAM3Stepper onSystem: system. solver := (PMAM3Solver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -21,7 +21,7 @@ PMImplicitMultiBenchmark >> benchAM4 [ | solver stepper | stepper := PMAM4Stepper onSystem: system. solver := (PMAM4Solver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -30,7 +30,7 @@ PMImplicitMultiBenchmark >> benchBDF2 [ | solver stepper | stepper := PMBDF2Stepper onSystem: system. solver := (PMBDF2Solver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -39,7 +39,7 @@ PMImplicitMultiBenchmark >> benchBDF3 [ | solver stepper | stepper := PMBDF3Stepper onSystem: system. solver := (PMBDF3Solver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -48,7 +48,7 @@ PMImplicitMultiBenchmark >> benchBDF4 [ | solver stepper | stepper := PMBDF4Stepper onSystem: system. solver := (PMBDF4Solver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] @@ -57,11 +57,11 @@ PMImplicitMultiBenchmark >> benchTrapezoidAM2 [ | solver stepper | stepper := PMTrapezoidStepper onSystem: system. solver := (PMImplicitSolver new) stepper: stepper; system: system; dt: dt. - 1 to: self problemSize do: [ :i + 1 to: self problemSize do: [ :i |solver solve: system startState: startState startTime:startTime endTime: endTime] ] -{ #category : #'as yet unclassified' } +{ #category : #running } PMImplicitMultiBenchmark >> setUp [ super setUp. system := PMImplicitSystem block: function diff --git a/src/Math-Benchmarks-ODE/PMODEBenchmark.class.st b/src/Math-Benchmarks-ODE/PMODEBenchmark.class.st index 79c3b7445..9dd383022 100644 --- a/src/Math-Benchmarks-ODE/PMODEBenchmark.class.st +++ b/src/Math-Benchmarks-ODE/PMODEBenchmark.class.st @@ -8,10 +8,10 @@ Class { 'startTime', 'endTime' ], - #category : 'Math-Benchmarks-ODE' + #category : #'Math-Benchmarks-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #defaults } PMODEBenchmark class >> defaultProblemSize [ ^200 ] @@ -19,7 +19,7 @@ PMODEBenchmark class >> defaultProblemSize [ { #category : #'as yet unclassified' } PMODEBenchmark class >> runAll: numOfIterations [ ^ ((self withAllSubclasses collect: [ :suite | - suite run: numOfIterations]) do: [ :suiteResult | + suite run: numOfIterations]) do: [ :suiteResult | suiteResult results removeKey: #baseBenchmark ]) reject: [ :runner | runner results isEmpty ] ] @@ -36,14 +36,14 @@ PMODEBenchmark class >> runAllToXML: numOfIterations [ writer enablePrettyPrinting; xml. - writer tag: 'smark' with: [ + writer tag: 'smark' with: [ (self runAll: numOfIterations) do: [ :runner | - writer tag: 'suite' attributes: (Dictionary with: #name -> runner suite class name asString) with: [ + writer tag: 'suite' attributes: (Dictionary with: #name -> runner suite class name asString) with: [ runner results keysAndValuesDo: [ :key :value | writer tag: key with: ((value inject: 0 into: [ :subTotal :result | subTotal + result total ]) / value size) asFloat asString] ] ] ]. - ^ writer + ^ writer ] { #category : #running } @@ -59,9 +59,9 @@ PMODEBenchmark >> nil [ { #category : #running } PMODEBenchmark >> setUp [ dt := 0.09. - function := [:x :t | (t ** 4) * (t sin ** (2 * t cos)) * ( (2 * t negated) * (2 * t sin) * (t sin log) + + function := [:x :t | (t ** 4) * (t sin ** (2 * t cos)) * ( (2 * t negated) * (2 * t sin) * (t sin log) + t * (2 * t cos) * (t tan reciprocal) + 5)]. startState := 0. startTime := 0.3 . - endTime := Float halfPi + endTime := Float halfPi ] diff --git a/src/Math-Chromosome/PMChromosomeManager.class.st b/src/Math-Chromosome/PMChromosomeManager.class.st index 8ceb1d4fe..61cd206c1 100644 --- a/src/Math-Chromosome/PMChromosomeManager.class.st +++ b/src/Math-Chromosome/PMChromosomeManager.class.st @@ -13,7 +13,7 @@ Class { { #category : #creation } PMChromosomeManager class >> new: anInteger mutation: aNumber1 crossover: aNumber2 [ - + ^self new populationSize: anInteger; rateOfMutation: aNumber1; rateOfCrossover: aNumber2; yourself ] @@ -25,54 +25,54 @@ PMChromosomeManager >> clone: aChromosome [ { #category : #operation } PMChromosomeManager >> crossover: aChromosome1 and: aChromosome2 [ - + ^self subclassResponsibility ] { #category : #initialization } -PMChromosomeManager >> initialize [ +PMChromosomeManager >> initialize [ super initialize. - randomNumberGenerator := Random new. + randomNumberGenerator := Random new ] { #category : #information } PMChromosomeManager >> isFullyPopulated [ - + ^population size >= populationSize ] { #category : #operation } PMChromosomeManager >> mutate: aChromosome [ - + ^self subclassResponsibility ] { #category : #information } PMChromosomeManager >> population [ - + ^population ] { #category : #initialization } PMChromosomeManager >> populationSize: anInteger [ - populationSize := anInteger. + populationSize := anInteger ] { #category : #operation } -PMChromosomeManager >> process: aChromosome1 and: aChromosome2 [ - +PMChromosomeManager >> process: aChromosome1 and: aChromosome2 [ + | roll | roll := randomNumberGenerator next. - roll < rateOfCrossover + roll < rateOfCrossover ifTrue: [population addAll: (self crossover: aChromosome1 and: aChromosome2)] - ifFalse: - [roll < (rateOfCrossover + rateOfMutation) - ifTrue: + ifFalse: + [roll < (rateOfCrossover + rateOfMutation) + ifTrue: [population add: (self mutate: aChromosome1); add: (self mutate: aChromosome2)] - ifFalse: + ifFalse: [population add: (self clone: aChromosome1); add: (self clone: aChromosome2)]] @@ -87,28 +87,28 @@ PMChromosomeManager >> randomChromosome [ PMChromosomeManager >> randomizePopulation [ self reset. - [self isFullyPopulated] + [self isFullyPopulated] whileFalse: [population add: self randomChromosome] ] { #category : #initialization } -PMChromosomeManager >> rateOfCrossover: aNumber [ +PMChromosomeManager >> rateOfCrossover: aNumber [ - (aNumber between: 0 and: 1) + (aNumber between: 0 and: 1) ifFalse: [self error: 'Illegal rate of cross-over']. rateOfCrossover := aNumber ] { #category : #initialization } -PMChromosomeManager >> rateOfMutation: aNumber [ +PMChromosomeManager >> rateOfMutation: aNumber [ - (aNumber between: 0 and: 1) + (aNumber between: 0 and: 1) ifFalse: [self error: 'Illegal rate of mutation']. rateOfMutation := aNumber ] { #category : #transformation } PMChromosomeManager >> reset [ - - population := OrderedCollection new: populationSize. + + population := OrderedCollection new: populationSize ] diff --git a/src/Math-Chromosome/PMVectorChromosomeManager.class.st b/src/Math-Chromosome/PMVectorChromosomeManager.class.st index 028c66701..2aeea6461 100644 --- a/src/Math-Chromosome/PMVectorChromosomeManager.class.st +++ b/src/Math-Chromosome/PMVectorChromosomeManager.class.st @@ -10,23 +10,23 @@ Class { { #category : #operation } PMVectorChromosomeManager >> crossover: aChromosome1 and: aChromosome2 [ - + | index new1 new2 | index := randomNumberGenerator nextIntegerBetween: 2 and: aChromosome1 size. new1 := self clone: aChromosome1. new1 replaceFrom: index to: new1 size with: aChromosome2 startingAt: index. - + new2 := self clone: aChromosome2. new2 replaceFrom: index to: new2 size with: aChromosome1 startingAt: index. - + ^ Array with: new1 with: new2 ] { #category : #operation } PMVectorChromosomeManager >> mutate: aVector [ - + | index | index := randomNumberGenerator nextIntegerBetween: 1 and: aVector size. @@ -37,13 +37,13 @@ PMVectorChromosomeManager >> mutate: aVector [ { #category : #initialization } PMVectorChromosomeManager >> origin: aVector [ - - origin := aVector. + + origin := aVector ] { #category : #creation } PMVectorChromosomeManager >> randomChromosome [ - + ^ ((1 to: origin size) collect: [ :n | self randomComponent: n ]) asPMVector ] @@ -55,6 +55,6 @@ PMVectorChromosomeManager >> randomComponent: anInteger [ { #category : #initialization } PMVectorChromosomeManager >> range: aVector [ - - range := aVector. + + range := aVector ] diff --git a/src/Math-Clustering/PMCluster.class.st b/src/Math-Clustering/PMCluster.class.st index 998ce8d0d..859f427d8 100644 --- a/src/Math-Clustering/PMCluster.class.st +++ b/src/Math-Clustering/PMCluster.class.st @@ -5,12 +5,12 @@ Class { 'accumulator', 'previousSampleSize' ], - #category : 'Math-Clustering' + #category : #'Math-Clustering' } { #category : #transformation } PMCluster >> accumulate: aVector [ - + accumulator accumulate: aVector ] @@ -39,20 +39,20 @@ PMCluster >> distanceTo: aVector [ { #category : #initialization } PMCluster >> initialize [ - + previousSampleSize := 0. ^ self ] { #category : #testing } PMCluster >> isInsignificantIn: aClusterFinder [ - + ^ self sampleSize <= aClusterFinder minimumClusterSize ] { #category : #testing } PMCluster >> isUndefined [ - + ^ self subclassResponsibility ] diff --git a/src/Math-Clustering/PMClusterFinder.class.st b/src/Math-Clustering/PMClusterFinder.class.st index 48cbed9e0..7751ca63b 100644 --- a/src/Math-Clustering/PMClusterFinder.class.st +++ b/src/Math-Clustering/PMClusterFinder.class.st @@ -6,15 +6,15 @@ Class { 'dataSetSize', 'minimumRelativeClusterSize' ], - #category : 'Math-Clustering' + #category : #'Math-Clustering' } { #category : #creation } PMClusterFinder class >> new: anInteger server: aClusterDataServer type: aClusterClass [ - - ^ self new - initialize: anInteger - server: aClusterDataServer + + ^ self new + initialize: anInteger + server: aClusterDataServer type: aClusterClass; yourself ] @@ -22,13 +22,13 @@ PMClusterFinder class >> new: anInteger server: aClusterDataServer type: aCluste { #category : #transformation } PMClusterFinder >> accumulate: aVector [ "Private - Accumulate aVector into the nearest cluster" - + (result at: (self indexOfNearestCluster: aVector)) accumulate: aVector ] { #category : #information } PMClusterFinder >> clusters: aCollectionOfClusters [ - + result := aCollectionOfClusters ] @@ -38,16 +38,16 @@ PMClusterFinder >> collectChangesAndResetClusters [ | hasEmptyClusters changes | changes := 0. hasEmptyClusters := false. - result do: - [ :each | + result do: + [ :each | changes := each changes + changes. (each isInsignificantIn: self) - ifTrue: + ifTrue: [ each centerOn: nil. hasEmptyClusters := true ] ifFalse: [ each reset ]. ]. - hasEmptyClusters + hasEmptyClusters ifTrue: [ result := result reject: [ :each | each isUndefined ]]. ^ changes / 2 ] @@ -61,7 +61,7 @@ PMClusterFinder >> dataServer: aClusterDataServer [ { #category : #operation } PMClusterFinder >> evaluateIteration [ "Perform an accumulation of the data from the server." - + dataServer reset. dataSetSize := 0. [ dataServer atEnd ] @@ -80,7 +80,7 @@ PMClusterFinder >> finalizeIterations [ { #category : #information } PMClusterFinder >> indexOfNearestCluster: aVector [ "Private - Answers the index of the cluster nearest to aVector." - + | distance index | index := 1. distance := (result at: 1) distanceTo: aVector. @@ -95,7 +95,7 @@ PMClusterFinder >> indexOfNearestCluster: aVector [ { #category : #initialization } PMClusterFinder >> initialize: anInteger server: aClusterDataServer type: aClusterClass [ - + self dataServer: aClusterDataServer. self clusters: ( (1 to: anInteger) collect: [ :n | aClusterClass new]). minimumRelativeClusterSize := 0. @@ -106,7 +106,7 @@ PMClusterFinder >> initialize: anInteger server: aClusterDataServer type: aClust PMClusterFinder >> initializeIterations [ dataServer open. - result + result do: [:each | each isUndefined ifTrue: [ each centerOn: dataServer next ]] ] @@ -117,13 +117,13 @@ PMClusterFinder >> minimumClusterSize [ { #category : #initialization } PMClusterFinder >> minimumRelativeClusterSize: aNumber [ - - minimumRelativeClusterSize := aNumber max: 0. + + minimumRelativeClusterSize := aNumber max: 0 ] { #category : #printing } PMClusterFinder >> printOn: aStream [ - + aStream nextPutAll: 'Iterations: '. iterations printOn: aStream. result do: [ :each | aStream cr. each printOn: aStream ] diff --git a/src/Math-Clustering/PMCovarianceCluster.class.st b/src/Math-Clustering/PMCovarianceCluster.class.st index 7ccbca880..cbdfb6a11 100644 --- a/src/Math-Clustering/PMCovarianceCluster.class.st +++ b/src/Math-Clustering/PMCovarianceCluster.class.st @@ -1,32 +1,30 @@ Class { #name : #PMCovarianceCluster, #superclass : #PMCluster, - #category : 'Math-Clustering' + #category : #'Math-Clustering' } { #category : #initialization } -PMCovarianceCluster >> centerOn: aVector [ +PMCovarianceCluster >> centerOn: aVector [ - accumulator := aVector isNil - ifTrue: [nil] - ifFalse: [ PMMahalanobisCenter onVector: aVector ] + accumulator := aVector ifNotNil: [ PMMahalanobisCenter onVector: aVector ] ] { #category : #transformation } PMCovarianceCluster >> collectAccumulatorResults [ - - accumulator computeParameters. + + accumulator computeParameters ] { #category : #information } PMCovarianceCluster >> distanceTo: aVector [ - + ^ accumulator distanceTo: aVector ] { #category : #testing } PMCovarianceCluster >> isUndefined [ - + ^accumulator isNil ] diff --git a/src/Math-Clustering/PMEuclideanCluster.class.st b/src/Math-Clustering/PMEuclideanCluster.class.st index d7f961611..7358b38ff 100644 --- a/src/Math-Clustering/PMEuclideanCluster.class.st +++ b/src/Math-Clustering/PMEuclideanCluster.class.st @@ -4,12 +4,12 @@ Class { #instVars : [ 'center' ], - #category : 'Math-Clustering' + #category : #'Math-Clustering' } { #category : #initialization } PMEuclideanCluster >> centerOn: aVector [ - + center := aVector. accumulator := PMVectorAccumulator new: (aVector ifNil:[0]ifNotNil:[ aVector size ]) ] @@ -22,19 +22,19 @@ PMEuclideanCluster >> collectAccumulatorResults [ { #category : #information } PMEuclideanCluster >> distanceTo: aVector [ - + ^(aVector - center) norm ] { #category : #testing } PMEuclideanCluster >> isUndefined [ - + ^ center isNil ] { #category : #printing } PMEuclideanCluster >> printOn: aStream [ - + accumulator count printOn: aStream. aStream nextPutAll: ': '. center printOn: aStream diff --git a/src/Math-Clustering/PMMahalanobisCenter.class.st b/src/Math-Clustering/PMMahalanobisCenter.class.st index b3ac47257..35a8d3171 100644 --- a/src/Math-Clustering/PMMahalanobisCenter.class.st +++ b/src/Math-Clustering/PMMahalanobisCenter.class.st @@ -6,12 +6,12 @@ Class { 'inverseCovariance', 'accumulator' ], - #category : 'Math-Clustering' + #category : #'Math-Clustering' } { #category : #creation } PMMahalanobisCenter class >> new: anInteger [ - + ^ self new initialize: anInteger ; yourself ] @@ -23,7 +23,7 @@ PMMahalanobisCenter class >> onVector: aVector [ { #category : #transformation } PMMahalanobisCenter >> accumulate: aVector [ - + accumulator accumulate: aVector ] @@ -33,7 +33,6 @@ PMMahalanobisCenter >> center: aVector [ accumulator := PMCovarianceAccumulator new: aVector size. center := aVector. inverseCovariance := PMSymmetricMatrix identity: aVector size - ] { #category : #transformation } @@ -60,18 +59,17 @@ PMMahalanobisCenter >> distanceTo: aVector [ PMMahalanobisCenter >> initialize: anInteger [ accumulator := PMCovarianceAccumulator new: anInteger - ] { #category : #printing } PMMahalanobisCenter >> printOn: aStream [ accumulator count printOn: aStream. aStream nextPutAll: ': '. - center printOn: aStream. + center printOn: aStream ] { #category : #transformation } PMMahalanobisCenter >> reset [ - + accumulator reset ] diff --git a/src/Math-Complex/Object.extension.st b/src/Math-Complex/Object.extension.st index 8208ae18d..15f1435bb 100644 --- a/src/Math-Complex/Object.extension.st +++ b/src/Math-Complex/Object.extension.st @@ -5,12 +5,10 @@ Object >> isComplexNumber [ "Answer true if receiver is a Complex number. False by default." ^ false - ] { #category : #'*Math-Complex' } Object >> isRealNumber [ "Answer true if receiver is a real number. False by default." ^ false - ] diff --git a/src/Math-Complex/PMComplexNumber.class.st b/src/Math-Complex/PMComplexNumber.class.st index adedbfb88..4033f660c 100644 --- a/src/Math-Complex/PMComplexNumber.class.st +++ b/src/Math-Complex/PMComplexNumber.class.st @@ -102,10 +102,10 @@ PMComplexNumber class >> one [ { #category : #information } PMComplexNumber class >> random [ - "Answers a random number with abs between 0 and 1." + "Answers a random number with abs between 0 and 1." | random | random := Random new. - + ^ self abs: random next arg: 2 * (random nextBetween: 0 and: Float pi) @@ -124,52 +124,52 @@ PMComplexNumber class >> zero [ { #category : #arithmetic } PMComplexNumber >> * anObject [ "Answer the result of multiplying the receiver by aNumber." + | a b c d newReal newImaginary | - anObject isComplexNumber - ifTrue: - [a := self real. - b := self imaginary. - c := anObject real. - d := anObject imaginary. - newReal := (a * c) - (b * d). - newImaginary := (a * d) + (b * c). - ^ PMComplexNumber real: newReal imaginary: newImaginary] - ifFalse: - [^ anObject adaptToComplex: self andSend: #*] + ^ anObject isComplexNumber + ifTrue: [ + a := self real. + b := self imaginary. + c := anObject real. + d := anObject imaginary. + newReal := a * c - (b * d). + newImaginary := a * d + (b * c). + PMComplexNumber real: newReal imaginary: newImaginary ] + ifFalse: [ anObject adaptToComplex: self andSend: #* ] ] { #category : #arithmetic } PMComplexNumber >> + anObject [ "Answer the sum of the receiver and aNumber." + | a b c d newReal newImaginary | - anObject isComplexNumber - ifTrue: - [a := self real. - b := self imaginary. - c := anObject real. - d := anObject imaginary. - newReal := a + c. - newImaginary := b + d. - ^ PMComplexNumber real: newReal imaginary: newImaginary] - ifFalse: - [^ anObject adaptToComplex: self andSend: #+] + ^ anObject isComplexNumber + ifTrue: [ + a := self real. + b := self imaginary. + c := anObject real. + d := anObject imaginary. + newReal := a + c. + newImaginary := b + d. + PMComplexNumber real: newReal imaginary: newImaginary ] + ifFalse: [ anObject adaptToComplex: self andSend: #+ ] ] { #category : #arithmetic } PMComplexNumber >> - anObject [ "Answer the difference between the receiver and aNumber." + | a b c d newReal newImaginary | - anObject isComplexNumber - ifTrue: - [a := self real. - b := self imaginary. - c := anObject real. - d := anObject imaginary. - newReal := a - c. - newImaginary := b - d. - ^ PMComplexNumber real: newReal imaginary: newImaginary] - ifFalse: - [^ anObject adaptToComplex: self andSend: #-] + ^ anObject isComplexNumber + ifTrue: [ + a := self real. + b := self imaginary. + c := anObject real. + d := anObject imaginary. + newReal := a - c. + newImaginary := b - d. + PMComplexNumber real: newReal imaginary: newImaginary ] + ifFalse: [ anObject adaptToComplex: self andSend: #- ] ] { #category : #arithmetic } @@ -184,15 +184,16 @@ PMComplexNumber >> / aNumber [ newReal := ((a * c) + (b * d)) / ((c * c) + (d * d)). newImaginary := ((b * c) - (a * d)) / ((c * c) + (d * d)). ^ self class real: newReal imaginary: newImaginary]. - ^ aNumber adaptToComplex: self andSend: #/. + ^ aNumber adaptToComplex: self andSend: #/ ] { #category : #comparing } PMComplexNumber >> = anObject [ - anObject isNumber ifFalse: [^false]. - anObject isComplexNumber - ifTrue: [^ (real = anObject real) & (imaginary = anObject imaginary)] - ifFalse: [^ anObject adaptToComplex: self andSend: #=] + + anObject isNumber ifFalse: [ ^ false ]. + ^ anObject isComplexNumber + ifTrue: [ real = anObject real & (imaginary = anObject imaginary) ] + ifFalse: [ anObject adaptToComplex: self andSend: #= ] ] { #category : #arithmetic } @@ -209,7 +210,7 @@ PMComplexNumber >> absSecure [ | scale | scale := real abs max: imaginary abs. - ^scale isZero + ^scale isZero ifTrue: [scale] ifFalse: [(self class real: real / scale imaginary: imaginary / scale) squaredNorm sqrt * scale] ] @@ -256,22 +257,23 @@ PMComplexNumber >> arCosh [ "Answer receiver's area hyperbolic cosine. That is the inverse function of cosh. Some possible implementations: - ^imaginary > 0 + ^imaginary > 0 ifTrue: [(self + (self * self - 1) sqrt) ln] ifFalse: [(self + (self * self - 1) sqrt) ln negated] ^self arcCos i This implementation provides an answer with a positive real part. It also avoids creating intermediate Complex." - + | x y tmp sh2x shx delta ch2x chx | - imaginary = 0 ifTrue: [real abs > 1 - ifTrue: - [y := real < 0 - ifTrue: [Float pi] - ifFalse: [0]. - x := real abs arCosh. - ^self class real: x imaginary: y] - ifFalse: [^self class real: 0 imaginary: real arcCos]]. + imaginary = 0 ifTrue: [ + ^ real abs > 1 + ifTrue: [ + y := real < 0 + ifTrue: [ Float pi ] + ifFalse: [ 0 ]. + x := real abs arCosh. + self class real: x imaginary: y ] + ifFalse: [ self class real: 0 imaginary: real arcCos ] ]. tmp := self squaredNorm - 1 / 2. delta := tmp squared + imaginary squared. sh2x := tmp + delta sqrt. @@ -280,7 +282,7 @@ PMComplexNumber >> arCosh [ chx := ch2x sqrt. x := shx arSinh. y := imaginary copySignTo: (real / chx) arcCos. - ^self class real: x imaginary: y + ^ self class real: x imaginary: y ] { #category : #'mathematical functions' } @@ -290,7 +292,7 @@ PMComplexNumber >> arSinh [ "Some possible implementation: - ^imaginary * real < 0 + ^imaginary * real < 0 ifTrue: [(self + (self * self + 1) sqrt) ln] ifFalse: [(self - (self * self + 1) sqrt) ln]" @@ -315,14 +317,15 @@ PMComplexNumber >> arcCos [ This is the inverse function of cos." | x y tmp sh2y shy delta ch2y chy | - imaginary = 0 ifTrue: [real abs > 1 - ifTrue: - [x := real < 0 - ifTrue: [Float pi] - ifFalse: [0]. - y := real copySignTo: real abs arCosh. - ^self class real: x imaginary: y] - ifFalse: [^self class real: real arcCos imaginary: 0]]. + imaginary = 0 ifTrue: [ + ^ real abs > 1 + ifTrue: [ + x := real < 0 + ifTrue: [ Float pi ] + ifFalse: [ 0 ]. + y := real copySignTo: real abs arCosh. + self class real: x imaginary: y ] + ifFalse: [ self class real: real arcCos imaginary: 0 ] ]. tmp := self squaredNorm - 1 / 2. delta := tmp squared + imaginary squared. sh2y := tmp + delta sqrt. @@ -331,7 +334,7 @@ PMComplexNumber >> arcCos [ chy := ch2y sqrt. y := imaginary copySignTo: shy arSinh. x := (real / chy) arcCos. - ^self class real: x imaginary: y negated + ^ self class real: x imaginary: y negated ] { #category : #'mathematical functions' } @@ -340,15 +343,14 @@ PMComplexNumber >> arcSin [ This is the inverse function of sin." | x y tmp delta sh2y shy ch2y chy | - imaginary = 0 - ifTrue: - [real abs > 1 - ifTrue: - [x := Float pi / 2 * real sign. - y := (real copySignTo: real abs arCosh) negated. - ^self class real: x imaginary: y] - ifFalse: [^self class real: real arcSin imaginary: 0]]. - tmp := (self squaredNorm - 1) / 2. + imaginary = 0 ifTrue: [ + ^ real abs > 1 + ifTrue: [ + x := Float pi / 2 * real sign. + y := (real copySignTo: real abs arCosh) negated. + self class real: x imaginary: y ] + ifFalse: [ self class real: real arcSin imaginary: 0 ] ]. + tmp := self squaredNorm - 1 / 2. delta := tmp squared + imaginary squared. sh2y := tmp + delta sqrt. shy := sh2y sqrt. @@ -356,7 +358,7 @@ PMComplexNumber >> arcSin [ chy := ch2y sqrt. y := imaginary copySignTo: shy arSinh. x := (real / chy) arcSin. - ^self class real: x imaginary: y + ^ self class real: x imaginary: y ] { #category : #'mathematical functions' } @@ -372,24 +374,24 @@ PMComplexNumber >> arcTan [ ] { #category : #'mathematical functions' } -PMComplexNumber >> arcTan: denominator [ +PMComplexNumber >> arcTan: denominator [ "Answer the four quadrants arc tangent of receiver over denominator." - ^denominator isZero - ifTrue: - [self isZero - ifTrue: + ^denominator isZero + ifTrue: + [self isZero + ifTrue: ["shouldn't it be an error ? ^DomainError signal: '0 arcTan: 0'" ^self class real: 0 imaginary: 0] - ifFalse: + ifFalse: [self class real: Float pi / (real copySignTo: 2) imaginary: 0]] - ifFalse: + ifFalse: [| res | res := (self / denominator) arcTan. denominator real < 0 ifTrue: [res := res + Float pi]. - res real > Float pi + res real > Float pi ifTrue: [res := res - (Float pi * 2)]. res] ] @@ -412,14 +414,14 @@ PMComplexNumber >> closeTo: aNumber precision: aPrecision [ "A complex number self is close to a complex number other with precision epsilon if both self real is close to other real with precision epsilon and self imaginary is close to other imaginary with precision epsilon. - + In case aNumber is real and not complex, we convert it to a complex number other = aNumber + 0i" | other | other := aNumber asComplex. - - ^ (real closeTo: other real precision: aPrecision) and: [ - imaginary closeTo: other imaginary precision: aPrecision ]. + + ^ (real closeTo: other real precision: aPrecision) and: [ + imaginary closeTo: other imaginary precision: aPrecision ] ] { #category : #arithmetic } @@ -454,7 +456,7 @@ PMComplexNumber >> cosh [ Hyperbolic cosine is defined by same power serie expansion as for real numbers, that is in term of exponential: ^ (self exp + self negated exp) / 2. This implementation avoids creating intermediate objects." - + ^self class real: real cosh * imaginary cos imaginary: real sinh * imaginary sin @@ -463,38 +465,37 @@ PMComplexNumber >> cosh [ { #category : #arithmetic } PMComplexNumber >> divideFastAndSecureBy: anObject [ "Answer the result of dividing receiver by aNumber" - " Both operands are scaled to avoid arithmetic overflow. + + " Both operands are scaled to avoid arithmetic overflow. This algorithm works for a wide range of values, and it needs only three divisions. Note: #reciprocal uses #/ for devision " - + | r d newReal newImaginary | - anObject isComplexNumber ifTrue: - [anObject real abs > anObject imaginary abs - ifTrue: - [r := anObject imaginary / anObject real. - d := r*anObject imaginary + anObject real. - newReal := r*imaginary + real/d. - newImaginary := r negated * real + imaginary/d. - ] - ifFalse: - [r := anObject real / anObject imaginary. - d := r*anObject real + anObject imaginary. - newReal := r*real + imaginary/d. - newImaginary := r*imaginary - real/d. - ]. - - ^ PMComplexNumber real: newReal imaginary: newImaginary]. - ^ anObject adaptToComplex: self andSend: #/. + anObject isComplexNumber ifTrue: [ + newImaginary := anObject real abs > anObject imaginary abs + ifTrue: [ + r := anObject imaginary / anObject real. + d := r * anObject imaginary + anObject real. + newReal := r * imaginary + real / d. + r negated * real + imaginary / d ] + ifFalse: [ + r := anObject real / anObject imaginary. + d := r * anObject real + anObject imaginary. + newReal := r * real + imaginary / d. + r * imaginary - real / d ]. + + ^ PMComplexNumber real: newReal imaginary: newImaginary ]. + ^ anObject adaptToComplex: self andSend: #/ ] { #category : #arithmetic } PMComplexNumber >> divideSecureBy: anObject [ "Answer the result of dividing receiver by aNumber" - " Both operands are scaled to avoid arithmetic overflow. This algorithm - works for a wide range of values, but it requires six divisions. + " Both operands are scaled to avoid arithmetic overflow. This algorithm + works for a wide range of values, but it requires six divisions. #divideFastAndSecureBy: is also quite good, but it uses only 3 divisions. Note: #reciprocal uses #/ for devision" - + | s ars ais brs bis newReal newImaginary | anObject isComplexNumber ifTrue: [s := anObject real abs + anObject imaginary abs. @@ -503,11 +504,11 @@ PMComplexNumber >> divideSecureBy: anObject [ brs := anObject real / s. bis := anObject imaginary / s. s := brs squared + bis squared. - + newReal := ars*brs + (ais*bis) /s. newImaginary := ais*brs - (ars*bis)/s. ^ PMComplexNumber real: newReal imaginary: newImaginary]. - ^ anObject adaptToComplex: self andSend: #/. + ^ anObject adaptToComplex: self andSend: #/ ] { #category : #'double dispatch' } @@ -535,8 +536,8 @@ PMComplexNumber >> floatClass [ { #category : #comparing } PMComplexNumber >> hash [ "Hash is reimplemented because = is implemented." - - ^ real hash bitXor: imaginary hash. + + ^ real hash bitXor: imaginary hash ] { #category : #arithmetic } @@ -586,7 +587,7 @@ PMComplexNumber >> ln [ ] { #category : #'mathematical functions' } -PMComplexNumber >> log: aNumber [ +PMComplexNumber >> log: aNumber [ "Answer the log base aNumber of the receiver." ^self ln / aNumber ln @@ -610,7 +611,6 @@ PMComplexNumber >> printOn: aStream [ imaginary abs printOn: aStream. aStream nextPut: Character space. aStream nextPut: $i - ] { #category : #'double dispatch' } @@ -621,24 +621,22 @@ PMComplexNumber >> productWithVector: aVector [ ] { #category : #'mathematical functions' } -PMComplexNumber >> raisedTo: aNumber [ +PMComplexNumber >> raisedTo: aNumber [ "Answer the receiver raised to aNumber." - aNumber isInteger ifTrue: - ["Do the special case of integer power" - ^ self raisedToInteger: aNumber]. - - 0 = aNumber ifTrue: [^ self class one]. "Special case of exponent=0" - 1 = aNumber ifTrue: [^ self]. "Special case of exponent=1" - 0 = self ifTrue: [ "Special case of self = 0" - aNumber < 0 - ifTrue: [^ (ZeroDivide dividend: self) signal] - ifFalse: [^ self]]. - ^ (aNumber * self ln) exp "Otherwise use logarithms" + aNumber isInteger ifTrue: [ "Do the special case of integer power" ^ self raisedToInteger: aNumber ]. + + 0 = aNumber ifTrue: [ ^ self class one ]. "Special case of exponent=0" + 1 = aNumber ifTrue: [ ^ self ]. "Special case of exponent=1" + 0 = self ifTrue: [ "Special case of self = 0" + ^ aNumber < 0 + ifTrue: [ (ZeroDivide dividend: self) signal ] + ifFalse: [ self ] ]. + ^ (aNumber * self ln) exp "Otherwise use logarithms" ] { #category : #'mathematical functions' } -PMComplexNumber >> raisedToInteger: operand [ +PMComplexNumber >> raisedToInteger: operand [ "Answer the receiver raised to the power operand, an Integer." "implementation note: this code is copied from Number. @@ -654,7 +652,7 @@ PMComplexNumber >> raisedToInteger: operand [ count := 1 bitShift: (operand-1) highBit. result := self class one. [count > 0] - whileTrue: + whileTrue: [result := result squared. (operand bitAnd: count) = 0 ifFalse: [result := result * self]. @@ -666,7 +664,6 @@ PMComplexNumber >> raisedToInteger: operand [ PMComplexNumber >> random [ "analog to Number>>random. However, the only bound is that the abs of the produced complex is less than the length of the receive. The receiver effectively defines a disc within which the random element can be produced." ^ self class random * self - ] { #category : #accessing } @@ -678,18 +675,17 @@ PMComplexNumber >> real [ PMComplexNumber >> real: aNumber1 imaginary: aNumber2 [ "Private - initialize the real and imaginary parts of a Complex" real := aNumber1. - imaginary := aNumber2. + imaginary := aNumber2 ] { #category : #arithmetic } PMComplexNumber >> reciprocal [ - "Answer 1 divided by the receiver. Create an error notification if the + "Answer 1 divided by the receiver. Create an error notification if the receiver is 0." - self = 0 - ifTrue: [^ (ZeroDivide dividend: self) signal] - ifFalse: [^1 / self] - + ^ self = 0 + ifTrue: [ (ZeroDivide dividend: self) signal ] + ifFalse: [ 1 / self ] ] { #category : #testing } @@ -715,7 +711,7 @@ PMComplexNumber >> sinh [ Hyperbolic sine is defined by same power serie expansion as for real numbers, that is in term of exponential: ^ (self exp - self negated exp) / 2. This implementation avoids creating intermediate objects." - + ^self class real: real sinh * imaginary cos imaginary: real cosh * imaginary sin @@ -727,13 +723,13 @@ PMComplexNumber >> sqrt [ Implementation based on: https://en.wikipedia.org/wiki/Complex_number#Square_root" | newReal newImaginary imaginarySign | - + imaginarySign := imaginary sign = 0 ifTrue: [ 1 ] ifFalse: [ imaginary sign ]. - + newReal := ((self abs + real) / 2) sqrt. newImaginary := imaginarySign * ((self abs - real) / 2) sqrt. - + ^ newReal + newImaginary i ] diff --git a/src/Math-Core-Process/PMFixpoint.class.st b/src/Math-Core-Process/PMFixpoint.class.st index d480a904b..7bdc637c1 100644 --- a/src/Math-Core-Process/PMFixpoint.class.st +++ b/src/Math-Core-Process/PMFixpoint.class.st @@ -24,9 +24,9 @@ Class { #category : #'Math-Core-Process' } -{ #category : #'instance-creation' } -PMFixpoint class >> block: aBlock value: anObject [ -^self new block: aBlock ;value: anObject; yourself +{ #category : #'instance creation' } +PMFixpoint class >> block: aBlock value: anObject [ +^self new block: aBlock ;value: anObject; yourself ] { #category : #information } @@ -41,8 +41,8 @@ PMFixpoint class >> defaultVerbose [ { #category : #private } PMFixpoint >> adjustIteratorFor: aCycleLength [ -1 to: results size do:[:i| |last| last:=i + aCycleLength. - (equalityTest +1 to: results size do:[:i| |last| last:=i + aCycleLength. + (equalityTest ifNil: [(results at:i)literalEqual:(results at:last)] ifNotNil:[:t|(t value: (results at:i) value: (results at:last))]) ifTrue: [ result1 :=result. @@ -50,7 +50,7 @@ PMFixpoint >> adjustIteratorFor: aCycleLength [ ] { #category : #accessing } -PMFixpoint >> block: aBlock [ +PMFixpoint >> block: aBlock [ ^block := aBlock ] @@ -64,7 +64,7 @@ PMFixpoint >> cycle [ { #category : #printing } PMFixpoint >> cycleInfo: cycleLength [ verbose ifFalse: [ ^self ]. -GrowlMorph +GrowlMorph openWithLabel: 'Info' contents: ('{1} iterations used. warning: {2}-cycle detected' format: (Array with: iterations with: cycleLength)) @@ -77,24 +77,23 @@ PMFixpoint >> cycleLength [ |c| results ifNil:[^nil]. c:=(results copyFrom: 1 to: results size -1)reversed. -c withIndexDo:[:r :i|(equalityTest +c withIndexDo:[:r :i|(equalityTest ifNil: [(result literalEqual: r)] - ifNotNil:[:t|(t value: result value: r)]) + ifNotNil:[:t|(t value: result value: r)]) ifTrue:[^i]]. ^nil - ] { #category : #accessing } PMFixpoint >> equalityTest: aBlock [ -"you can set your own equality test to decide when the fixpoint is reached" +"you can set your own equality test to decide when the fixpoint is reached" self assert: aBlock argumentCount=2. ^equalityTest:=aBlock ] { #category : #operation } PMFixpoint >> evaluateIteration [ -cycleFlag ifTrue: [result1:=result] +cycleFlag ifTrue: [result1:=result] ifFalse:[result2:=result]. cycleFlag :=cycleFlag not. result := block value: result copy . @@ -111,14 +110,14 @@ PMFixpoint >> finalizeIterations [ ifFalse: [ self simpleInfo ] ] ifFalse: [ self cycleLength ifNil: [ self unfinishedInfo ] - ifNotNil: [ :x | + ifNotNil: [ :x | self adjustIteratorFor: x. self cycleInfo: x ] ] ] { #category : #information } PMFixpoint >> hasConverged [ -^equalityTest +^equalityTest ifNil: [(result literalEqual: result1) or: [result literalEqual: result2]] ifNotNil: [:t|(t value: result value: result1)or:[t value: result value: result2]] ] @@ -126,7 +125,7 @@ PMFixpoint >> hasConverged [ { #category : #initialization } PMFixpoint >> initialize [ verbose := self class defaultVerbose . -^super initialize +^super initialize ] { #category : #operation } @@ -146,37 +145,36 @@ PMFixpoint >> printOn: aStream [ block printOn: aStream . aStream nextPutAll: ' value: ' . result printOn: aStream. - aStream nextPut: $). + aStream nextPut: $) ] { #category : #printing } PMFixpoint >> simpleInfo [ verbose ifFalse: [ ^self ]. -GrowlMorph - openWithLabel: 'Info' - contents: ('{1} iterations needed.' format: (Array with: iterations)) +GrowlMorph + openWithLabel: 'Info' + contents: ('{1} iterations needed.' format: (Array with: iterations)) color: Color green muchDarker ] { #category : #printing } PMFixpoint >> unfinishedInfo [ verbose ifFalse: [ ^self ]. -GrowlMorph - openWithLabel: 'Warning' +GrowlMorph + openWithLabel: 'Warning' contents: ('maximumIterations ({1}) reached. -you can run evaluate a second time' format: (Array with: maximumIterations)) +you can run evaluate a second time' format: (Array with: maximumIterations)) color: Color orange darker ] { #category : #accessing } -PMFixpoint >> value: aStartingValue [ +PMFixpoint >> value: aStartingValue [ "the value, that will be fed at first to the block when evaluating" -^result:=aStartingValue. - +^result:=aStartingValue ] { #category : #accessing } PMFixpoint >> verbose: aBoolean [ "decides whether info should be delivered via GrowlMorphs. by default true" -^verbose:=aBoolean +^verbose:=aBoolean ] diff --git a/src/Math-Core-Process/PMIterativeProcess.class.st b/src/Math-Core-Process/PMIterativeProcess.class.st index 7c7b8f196..827d374d9 100644 --- a/src/Math-Core-Process/PMIterativeProcess.class.st +++ b/src/Math-Core-Process/PMIterativeProcess.class.st @@ -41,7 +41,7 @@ PMIterativeProcess >> desiredPrecision: aNumber [ "Defines the desired precision for the result." aNumber > 0 ifFalse: [ ^self error: 'Illegal precision: ', aNumber printString]. - desiredPrecision := aNumber. + desiredPrecision := aNumber ] { #category : #operation } @@ -50,10 +50,10 @@ PMIterativeProcess >> evaluate [ iterations := 0. self initializeIterations. - + [iterations := iterations + 1. precision := self evaluateIteration. - self hasConverged or: [iterations >= maximumIterations]] + self hasConverged or: [iterations >= maximumIterations]] whileFalse: []. self finalizeIterations. ^self result @@ -79,9 +79,11 @@ PMIterativeProcess >> hasConverged [ { #category : #initialization } PMIterativeProcess >> initialize [ + super initialize. + desiredPrecision := self class defaultPrecision. maximumIterations := self class defaultMaximumIterations. - ^self + ^ self ] { #category : #operation } @@ -108,7 +110,7 @@ PMIterativeProcess >> maximumIterations: anInteger [ "Defines the maximum number of iterations." ( anInteger isInteger and: [ anInteger > 1]) ifFalse: [ ^self error: 'Invalid maximum number of iteration: ', anInteger printString]. - maximumIterations := anInteger. + maximumIterations := anInteger ] { #category : #information } @@ -119,7 +121,7 @@ PMIterativeProcess >> precision [ { #category : #information } PMIterativeProcess >> precisionOf: aNumber1 relativeTo: aNumber2 [ - + ^aNumber2 > PMFloatingPointMachine new defaultNumericalPrecision ifTrue: [ aNumber1 / aNumber2] ifFalse:[ aNumber1] diff --git a/src/Math-Distributions/PMAsymptoticChiSquareDistribution.class.st b/src/Math-Distributions/PMAsymptoticChiSquareDistribution.class.st index f7d56f83a..7a2f10f71 100644 --- a/src/Math-Distributions/PMAsymptoticChiSquareDistribution.class.st +++ b/src/Math-Distributions/PMAsymptoticChiSquareDistribution.class.st @@ -22,7 +22,7 @@ PMAsymptoticChiSquareDistribution class >> distributionName [ { #category : #creation } PMAsymptoticChiSquareDistribution class >> new [ - + ^self error: 'Illegal creation message for this class' ] @@ -55,7 +55,7 @@ PMAsymptoticChiSquareDistribution >> distributionValue: aNumber [ | x | ^ aNumber > 0 - ifTrue: [ + ifTrue: [ x := (aNumber * 2) sqrt. PMErfApproximation new value: x - reducedDOF ] ifFalse: [ 0 ] @@ -106,7 +106,7 @@ PMAsymptoticChiSquareDistribution >> value: aNumber [ | x | ^ aNumber > 0 - ifTrue: [ + ifTrue: [ x := (aNumber * 2) sqrt. (PMErfApproximation new normal: x - reducedDOF) / x ] ifFalse: [ 0 ] diff --git a/src/Math-Distributions/PMBetaDistribution.class.st b/src/Math-Distributions/PMBetaDistribution.class.st index c08c58f38..552327ac9 100644 --- a/src/Math-Distributions/PMBetaDistribution.class.st +++ b/src/Math-Distributions/PMBetaDistribution.class.st @@ -19,7 +19,7 @@ PMBetaDistribution class >> distributionName [ ] { #category : #creation } -PMBetaDistribution class >> fromHistogram: aHistogram [ +PMBetaDistribution class >> fromHistogram: aHistogram [ "Create an instance of the receiver with parameters estimated from the given histogram using best guesses. This method can be used to find the initial values for a fit." | average variance a b | @@ -41,7 +41,7 @@ PMBetaDistribution class >> new [ ] { #category : #creation } -PMBetaDistribution class >> shape: aNumber1 shape: aNumber2 [ +PMBetaDistribution class >> shape: aNumber1 shape: aNumber2 [ "Create an instance of the receiver with given shape parameters." ^super new initialize: aNumber1 shape: aNumber2 @@ -61,37 +61,40 @@ PMBetaDistribution >> changeParametersBy: aVector [ self computeNorm. gamma1 := nil. gamma2 := nil. - incompleteBetaFunction := nil. + incompleteBetaFunction := nil ] { #category : #private } PMBetaDistribution >> computeNorm [ "Compute the norm of the receiver because its parameters have changed." - - logNorm := (alpha1 + alpha2) logGamma - alpha1 logGamma - alpha2 logGamma. + + logNorm := (alpha1 + alpha2) logGamma - alpha1 logGamma - alpha2 logGamma ] { #category : #information } PMBetaDistribution >> distributionValue: aNumber [ "Answers the probability of observing a random variable distributed according to the receiver with a value lower than or equal to aNumber." - - incompleteBetaFunction isNil - ifTrue: [ incompleteBetaFunction := PMIncompleteBetaFunction shape: alpha1 shape: alpha2]. - ^aNumber <= 0.0 ifTrue:[0]ifFalse:[aNumber >= 1.0 ifTrue:[1] ifFalse:[incompleteBetaFunction value: aNumber]] + + incompleteBetaFunction ifNil: [ incompleteBetaFunction := PMIncompleteBetaFunction shape: alpha1 shape: alpha2 ]. + ^ aNumber <= 0.0 + ifTrue: [ 0 ] + ifFalse: [ + aNumber >= 1.0 + ifTrue: [ 1 ] + ifFalse: [ incompleteBetaFunction value: aNumber ] ] ] { #category : #information } PMBetaDistribution >> firstGammaDistribution [ - gamma1 isNil - ifTrue: [ gamma1 := PMGammaDistribution shape: alpha1 scale: 1]. - ^gamma1 + gamma1 ifNil: [ gamma1 := PMGammaDistribution shape: alpha1 scale: 1 ]. + ^ gamma1 ] { #category : #initialization } -PMBetaDistribution >> initialize: aNumber1 shape: aNumber2 [ +PMBetaDistribution >> initialize: aNumber1 shape: aNumber2 [ - (aNumber1 > 0 and: [aNumber2 > 0]) + (aNumber1 > 0 and: [aNumber2 > 0]) ifFalse: [self error: 'Illegal distribution parameters']. alpha1 := aNumber1. alpha2 := aNumber2. @@ -122,10 +125,9 @@ PMBetaDistribution >> random [ { #category : #information } PMBetaDistribution >> secondGammaDistribution [ - - gamma2 isNil - ifTrue: [ gamma2 := PMGammaDistribution shape: alpha2 scale: 1]. - ^gamma2 + + gamma2 ifNil: [ gamma2 := PMGammaDistribution shape: alpha2 scale: 1 ]. + ^ gamma2 ] { #category : #information } @@ -135,11 +137,11 @@ PMBetaDistribution >> skewness [ ] { #category : #information } -PMBetaDistribution >> value: aNumber [ +PMBetaDistribution >> value: aNumber [ "Answers the probability that a random variable distributed according to the receiver gives a value between aNumber and aNumber + espilon (infinitesimal interval)." - ^(aNumber > 0 and: [ aNumber < 1]) - ifTrue: + ^(aNumber > 0 and: [ aNumber < 1]) + ifTrue: [( ( aNumber ln * (alpha1 - 1) ) + ( ( 1 - aNumber) ln * ( alpha2 - 1)) + logNorm) exp] ifFalse: [0] ] diff --git a/src/Math-Distributions/PMCauchyDistribution.class.st b/src/Math-Distributions/PMCauchyDistribution.class.st index 785b462eb..ed59f860a 100644 --- a/src/Math-Distributions/PMCauchyDistribution.class.st +++ b/src/Math-Distributions/PMCauchyDistribution.class.st @@ -13,17 +13,17 @@ Class { { #category : #information } PMCauchyDistribution class >> distributionName [ - + ^'Cauchy distribution' ] { #category : #creation } -PMCauchyDistribution class >> fromHistogram: aHistogram [ +PMCauchyDistribution class >> fromHistogram: aHistogram [ "Create an instance of the receiver with parameters estimated from the given histogram using best guesses. This method can be used to find the initial values for a fit." ^self shape: aHistogram average - scale: 4 * aHistogram variance - / (Float pi * (aHistogram maximum squared + aHistogram minimum squared)) + scale: 4 * aHistogram variance + / (Float pi * (aHistogram maximum squared + aHistogram minimum squared)) sqrt ] @@ -35,7 +35,7 @@ PMCauchyDistribution class >> new [ ] { #category : #creation } -PMCauchyDistribution class >> shape: aNumber1 scale: aNumber2 [ +PMCauchyDistribution class >> shape: aNumber1 scale: aNumber2 [ "Create an instance of the receiver with given center and scale parameters." ^super new initialize: aNumber1 scale: aNumber2 @@ -51,7 +51,7 @@ PMCauchyDistribution >> average [ PMCauchyDistribution >> changeParametersBy: aVector [ "Modify the parameters of the receiver by aVector." mu := mu + ( aVector at: 1). - beta := beta + ( aVector at: 2). + beta := beta + ( aVector at: 2) ] { #category : #information } @@ -77,7 +77,7 @@ PMCauchyDistribution >> kurtosis [ { #category : #information } PMCauchyDistribution >> parameters [ - + ^Array with: mu with: beta ] @@ -102,7 +102,7 @@ PMCauchyDistribution >> skewness [ PMCauchyDistribution >> standardDeviation [ "The standard deviation of the receiver is not defined." -self shouldNotImplement +self shouldNotImplement ] { #category : #information } @@ -126,5 +126,5 @@ PMCauchyDistribution >> valueAndGradient: aNumber [ PMCauchyDistribution >> variance [ "The variance of the receiver is not defined." - self shouldNotImplement + self shouldNotImplement ] diff --git a/src/Math-Distributions/PMChiSquareDistribution.class.st b/src/Math-Distributions/PMChiSquareDistribution.class.st index 587a5f7c6..25aeda61f 100644 --- a/src/Math-Distributions/PMChiSquareDistribution.class.st +++ b/src/Math-Distributions/PMChiSquareDistribution.class.st @@ -32,7 +32,7 @@ PMChiSquareDistribution class >> fromHistogram: aHistogram [ { #category : #creation } PMChiSquareDistribution class >> shape: aNumber1 scale: aNumber2 [ - + ^self error: 'Illegal creation message for this class' ] diff --git a/src/Math-Distributions/PMCongruentialRandomNumberGenerator.class.st b/src/Math-Distributions/PMCongruentialRandomNumberGenerator.class.st index ba54324e2..d566898b8 100644 --- a/src/Math-Distributions/PMCongruentialRandomNumberGenerator.class.st +++ b/src/Math-Distributions/PMCongruentialRandomNumberGenerator.class.st @@ -14,9 +14,9 @@ Class { } { #category : #creation } -PMCongruentialRandomNumberGenerator class >> constant: aNumber1 multiplicator: aNumber2 modulus: aNumber3 [ +PMCongruentialRandomNumberGenerator class >> constant: aNumber1 multiplicator: aNumber2 modulus: aNumber3 [ - ^super new + ^super new initialize: aNumber1 multiplicator: aNumber2 modulus: aNumber3 @@ -25,11 +25,11 @@ PMCongruentialRandomNumberGenerator class >> constant: aNumber1 multiplicator: a { #category : #creation } PMCongruentialRandomNumberGenerator class >> new [ "Create a new instance of the receiver with D. Knuth's constants." - UniqueInstance isNil - ifTrue: [ UniqueInstance := super new initialize. - UniqueInstance setSeed: 1. - ]. - ^UniqueInstance + + UniqueInstance ifNil: [ + UniqueInstance := super new initialize. + UniqueInstance setSeed: 1 ]. + ^ UniqueInstance ] { #category : #creation } @@ -46,17 +46,19 @@ PMCongruentialRandomNumberGenerator >> floatValue [ { #category : #initialization } PMCongruentialRandomNumberGenerator >> initialize [ - - self initialize: 2718281829.0 multiplicator: 3141592653.0 modulus: 4294967296.0. + + super initialize. + + self initialize: 2718281829.0 multiplicator: 3141592653.0 modulus: 4294967296.0 ] { #category : #initialization } PMCongruentialRandomNumberGenerator >> initialize: aNumber1 multiplicator: aNumber2 modulus: aNumber3 [ - + constant := aNumber1. modulus := aNumber2. multiplicator := aNumber3. - self setSeed: 1. + self setSeed: 1 ] { #category : #information } @@ -68,7 +70,7 @@ PMCongruentialRandomNumberGenerator >> integerValue: anInteger [ { #category : #transformation } PMCongruentialRandomNumberGenerator >> setSeed: aNumber [ "Set the seed of the receiver to aNumber." - seed := aNumber. + seed := aNumber ] { #category : #information } diff --git a/src/Math-Distributions/PMErfApproximation.class.st b/src/Math-Distributions/PMErfApproximation.class.st index 93baa51bb..a84296799 100644 --- a/src/Math-Distributions/PMErfApproximation.class.st +++ b/src/Math-Distributions/PMErfApproximation.class.st @@ -46,25 +46,26 @@ Class { { #category : #creation } PMErfApproximation class >> new [ "Answer a unique instance. Create it if it does not exist." - UniqueInstance isNil - ifTrue: [ UniqueInstance := super new. - UniqueInstance initialize ]. - ^UniqueInstance + + UniqueInstance ifNil: [ + UniqueInstance := super new. + UniqueInstance initialize ]. + ^ UniqueInstance ] { #category : #creation } PMErfApproximation class >> reset [ "ensure a new UniqueInstance is built when used next" - UniqueInstance := nil. + UniqueInstance := nil ] { #category : #initialization } PMErfApproximation >> initialize [ + + super initialize. constant := 0.2316419. norm := 1 / (Float pi * 2) sqrt. - series := PMPolynomial - coefficients: - #(0.31938153 -0.356563782 1.781477937 -1.821255978 1.330274429) + series := PMPolynomial coefficients: #( 0.31938153 -0.356563782 1.781477937 -1.821255978 1.330274429 ) ] { #category : #information } diff --git a/src/Math-Distributions/PMFisherSnedecorDistribution.class.st b/src/Math-Distributions/PMFisherSnedecorDistribution.class.st index c098d8655..12d6fcc65 100644 --- a/src/Math-Distributions/PMFisherSnedecorDistribution.class.st +++ b/src/Math-Distributions/PMFisherSnedecorDistribution.class.st @@ -13,7 +13,7 @@ Class { } { #category : #creation } -PMFisherSnedecorDistribution class >> degreeOfFreedom: anInteger1 degreeOfFreedom: anInteger2 [ +PMFisherSnedecorDistribution class >> degreeOfFreedom: anInteger1 degreeOfFreedom: anInteger2 [ "Create a new instance of the receiver with given degrees of freedom." ^super new initialize: anInteger1 and: anInteger2 @@ -26,7 +26,7 @@ PMFisherSnedecorDistribution class >> distributionName [ ] { #category : #creation } -PMFisherSnedecorDistribution class >> fromHistogram: aHistogram [ +PMFisherSnedecorDistribution class >> fromHistogram: aHistogram [ "Create an instance of the receiver with parameters estimated from the given histogram using best guesses. This method can be used to find the initial values for a fit." | n1 n2 a | @@ -35,7 +35,7 @@ PMFisherSnedecorDistribution class >> fromHistogram: aHistogram [ n2 > 0 ifFalse: [^nil]. a := (n2 - 2) * (n2 - 4) * aHistogram variance / (n2 squared * 2). n1 := (0.7 * (n2 - 2) / (1 - a)) rounded. - ^n1 > 0 + ^n1 > 0 ifTrue: [self degreeOfFreedom: n1 degreeOfFreedom: n2] ifFalse: [nil] ] @@ -46,12 +46,12 @@ PMFisherSnedecorDistribution class >> new [ ] { #category : #creation } -PMFisherSnedecorDistribution class >> test: aStatisticalMoment1 with: aStatisticalMoment2 [ +PMFisherSnedecorDistribution class >> test: aStatisticalMoment1 with: aStatisticalMoment2 [ "Perform a consistency Fisher test (or F-test) on the variances of two statistical moments ( or histograms). Answer the probability of passing the test." ^(self class degreeOfFreedom: aStatisticalMoment1 count - degreeOfFreedom: aStatisticalMoment2 count) - distributionValue: aStatisticalMoment1 variance + degreeOfFreedom: aStatisticalMoment2 count) + distributionValue: aStatisticalMoment1 variance / aStatisticalMoment2 variance ] @@ -71,14 +71,14 @@ PMFisherSnedecorDistribution >> changeParametersBy: aVector [ self computeNorm. chiSquareDistribution1 := nil. chiSquareDistribution2 := nil. - incompleteBetaFunction := nil. + incompleteBetaFunction := nil ] { #category : #private } PMFisherSnedecorDistribution >> computeNorm [ "Private - Compute the norm of the receiver because its parameters have changed." norm := ( dof1 ln * ( dof1 / 2) ) + ( dof2 ln * ( dof2 / 2) ) - - ( ( dof1 / 2) logBeta: ( dof2 / 2) ). + - ( ( dof1 / 2) logBeta: ( dof2 / 2) ) ] { #category : #information } @@ -99,11 +99,8 @@ PMFisherSnedecorDistribution >> distributionValue: aNumber [ PMFisherSnedecorDistribution >> incompleteBetaFunction [ "Private - Answers the incomplete beta function used to compute the symmetric acceptance integral of the receiver. " - incompleteBetaFunction isNil - ifTrue: - [incompleteBetaFunction := PMIncompleteBetaFunction shape: dof2 / 2 - shape: dof1 / 2]. - ^incompleteBetaFunction + incompleteBetaFunction ifNil: [ incompleteBetaFunction := PMIncompleteBetaFunction shape: dof2 / 2 shape: dof1 / 2 ]. + ^ incompleteBetaFunction ] { #category : #initialization } @@ -132,11 +129,11 @@ PMFisherSnedecorDistribution >> parameters [ { #category : #information } PMFisherSnedecorDistribution >> random [ "Answer a random number distributed according to the receiver." - chiSquareDistribution1 isNil - ifTrue: [ chiSquareDistribution1 := PMChiSquareDistribution degreeOfFreedom: dof1. - chiSquareDistribution2 := PMChiSquareDistribution degreeOfFreedom: dof2. - ]. - ^chiSquareDistribution1 random * dof2 / ( chiSquareDistribution2 random * dof1) + + chiSquareDistribution1 ifNil: [ + chiSquareDistribution1 := PMChiSquareDistribution degreeOfFreedom: dof1. + chiSquareDistribution2 := PMChiSquareDistribution degreeOfFreedom: dof2 ]. + ^ chiSquareDistribution1 random * dof2 / (chiSquareDistribution2 random * dof1) ] { #category : #information } diff --git a/src/Math-Distributions/PMFisherTippettDistribution.class.st b/src/Math-Distributions/PMFisherTippettDistribution.class.st index ea78be645..5c035a352 100644 --- a/src/Math-Distributions/PMFisherTippettDistribution.class.st +++ b/src/Math-Distributions/PMFisherTippettDistribution.class.st @@ -51,7 +51,7 @@ PMFisherTippettDistribution >> average [ PMFisherTippettDistribution >> changeParametersBy: aVector [ "Modify the parameters of the receiver by aVector." alpha := alpha + ( aVector at: 1). - beta := beta + ( aVector at: 2). + beta := beta + ( aVector at: 2) ] { #category : #information } diff --git a/src/Math-Distributions/PMGammaDistribution.class.st b/src/Math-Distributions/PMGammaDistribution.class.st index e87269126..cabbf3dd4 100644 --- a/src/Math-Distributions/PMGammaDistribution.class.st +++ b/src/Math-Distributions/PMGammaDistribution.class.st @@ -53,13 +53,13 @@ PMGammaDistribution >> changeParametersBy: aVector [ beta := beta + ( aVector at: 2). self computeNorm. incompleteGammaFunction := nil. - randomCoefficients := nil. + randomCoefficients := nil ] { #category : #initialization } PMGammaDistribution >> computeNorm [ "Private - Compute the norm of the receiver because its parameters have changed." - norm := beta ln * alpha + alpha logGamma. + norm := beta ln * alpha + alpha logGamma ] { #category : #information } @@ -73,10 +73,8 @@ PMGammaDistribution >> distributionValue: aNumber [ PMGammaDistribution >> incompleteGammaFunction [ "Private" - incompleteGammaFunction isNil - ifTrue: - [incompleteGammaFunction := PMIncompleteGammaFunction shape: alpha]. - ^incompleteGammaFunction + incompleteGammaFunction ifNil: [ incompleteGammaFunction := PMIncompleteGammaFunction shape: alpha ]. + ^ incompleteGammaFunction ] { #category : #initialization } @@ -131,17 +129,17 @@ PMGammaDistribution >> random [ { #category : #information } PMGammaDistribution >> randomCoefficientsForLargeAlpha [ "Private" - randomCoefficients isNil - ifTrue: [ randomCoefficients := self initializeRandomCoefficientsForLargeAlpha]. - ^randomCoefficients + + randomCoefficients ifNil: [ randomCoefficients := self initializeRandomCoefficientsForLargeAlpha ]. + ^ randomCoefficients ] { #category : #information } PMGammaDistribution >> randomCoefficientsForSmallAlpha [ "Private" - randomCoefficients isNil - ifTrue: [ randomCoefficients := self initializeRandomCoefficientsForSmallAlpha]. - ^randomCoefficients + + randomCoefficients ifNil: [ randomCoefficients := self initializeRandomCoefficientsForSmallAlpha ]. + ^ randomCoefficients ] { #category : #information } @@ -159,7 +157,7 @@ PMGammaDistribution >> randomForLargeAlpha [ w := ( c at: 3) * v + ( c at: 2) - y. ( c at: 4) + w >= ( 4.5 * z) ifTrue: [ ^y]. z ln <= w ifTrue: [ ^y]. - ]. + ] ] { #category : #information } @@ -167,16 +165,16 @@ PMGammaDistribution >> randomForSmallAlpha [ "Private - Generate a random number distributed according to the receiver when alpha < 1. " [ true ] - whileTrue: [ + whileTrue: [ | p | p := flatGenerator floatValue * self randomCoefficientsForSmallAlpha. p > 1 - ifTrue: [ + ifTrue: [ | y | y := ((self randomCoefficientsForSmallAlpha - p) / alpha) ln negated. flatGenerator floatValue <= (y raisedTo: alpha - 1) ifTrue: [ ^ y ] ] - ifFalse: [ + ifFalse: [ | y | y := p raisedTo: 1 / alpha. flatGenerator floatValue <= y negated exp diff --git a/src/Math-Distributions/PMIncompleteBetaFractionTermServer.class.st b/src/Math-Distributions/PMIncompleteBetaFractionTermServer.class.st index 3d57d5178..83c72ccb9 100644 --- a/src/Math-Distributions/PMIncompleteBetaFractionTermServer.class.st +++ b/src/Math-Distributions/PMIncompleteBetaFractionTermServer.class.st @@ -14,7 +14,7 @@ PMIncompleteBetaFractionTermServer >> initialTerm [ ] { #category : #initialization } -PMIncompleteBetaFractionTermServer >> setParameter: aNumber1 second: aNumber2 [ +PMIncompleteBetaFractionTermServer >> setParameter: aNumber1 second: aNumber2 [ alpha1 := aNumber1. alpha2 := aNumber2 ] diff --git a/src/Math-Distributions/PMIncompleteBetaFunction.class.st b/src/Math-Distributions/PMIncompleteBetaFunction.class.st index 6e28d3f5e..d2f18bda0 100644 --- a/src/Math-Distributions/PMIncompleteBetaFunction.class.st +++ b/src/Math-Distributions/PMIncompleteBetaFunction.class.st @@ -12,40 +12,38 @@ Class { } { #category : #creation } -PMIncompleteBetaFunction class >> shape: aNumber1 shape: aNumber2 [ +PMIncompleteBetaFunction class >> shape: aNumber1 shape: aNumber2 [ "Create an instance of the receiver with given shape parameters." ^self new initialize: aNumber1 shape: aNumber2 ] { #category : #private } -PMIncompleteBetaFunction >> evaluateFraction: aNumber [ +PMIncompleteBetaFunction >> evaluateFraction: aNumber [ - fraction isNil - ifTrue: - [fraction := PMIncompleteBetaFractionTermServer new. - fraction setParameter: alpha1 second: alpha2]. + fraction ifNil: [ + fraction := PMIncompleteBetaFractionTermServer new. + fraction setParameter: alpha1 second: alpha2 ]. fraction setArgument: aNumber. - ^(PMContinuedFraction server: fraction) - desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; - evaluate + ^ (PMContinuedFraction server: fraction) + desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; + evaluate ] { #category : #private } -PMIncompleteBetaFunction >> evaluateInverseFraction: aNumber [ +PMIncompleteBetaFunction >> evaluateInverseFraction: aNumber [ - inverseFraction isNil - ifTrue: - [inverseFraction := PMIncompleteBetaFractionTermServer new. - inverseFraction setParameter: alpha2 second: alpha1]. - inverseFraction setArgument: (1 - aNumber). - ^(PMContinuedFraction server: inverseFraction) - desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; - evaluate + inverseFraction ifNil: [ + inverseFraction := PMIncompleteBetaFractionTermServer new. + inverseFraction setParameter: alpha2 second: alpha1 ]. + inverseFraction setArgument: 1 - aNumber. + ^ (PMContinuedFraction server: inverseFraction) + desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; + evaluate ] { #category : #initialization } -PMIncompleteBetaFunction >> initialize: aNumber1 shape: aNumber2 [ +PMIncompleteBetaFunction >> initialize: aNumber1 shape: aNumber2 [ alpha1 := aNumber1. alpha2 := aNumber2. diff --git a/src/Math-Distributions/PMIncompleteGammaFractionTermServer.class.st b/src/Math-Distributions/PMIncompleteGammaFractionTermServer.class.st index 941204890..4bd53bafc 100644 --- a/src/Math-Distributions/PMIncompleteGammaFractionTermServer.class.st +++ b/src/Math-Distributions/PMIncompleteGammaFractionTermServer.class.st @@ -14,12 +14,12 @@ PMIncompleteGammaFractionTermServer >> initialTerm [ ] { #category : #initialization } -PMIncompleteGammaFractionTermServer >> setParameter: aNumber [ +PMIncompleteGammaFractionTermServer >> setParameter: aNumber [ alpha := aNumber asFloat ] { #category : #information } -PMIncompleteGammaFractionTermServer >> termsAt: anInteger [ +PMIncompleteGammaFractionTermServer >> termsAt: anInteger [ lastTerm := lastTerm + 2. ^Array with: (alpha - anInteger) * anInteger with: lastTerm ] diff --git a/src/Math-Distributions/PMIncompleteGammaFunction.class.st b/src/Math-Distributions/PMIncompleteGammaFunction.class.st index 321b11e42..47e207f61 100644 --- a/src/Math-Distributions/PMIncompleteGammaFunction.class.st +++ b/src/Math-Distributions/PMIncompleteGammaFunction.class.st @@ -17,34 +17,32 @@ PMIncompleteGammaFunction class >> shape: aNumber [ ] { #category : #private } -PMIncompleteGammaFunction >> evaluateFraction: aNumber [ +PMIncompleteGammaFunction >> evaluateFraction: aNumber [ - fraction isNil - ifTrue: - [fraction := PMIncompleteGammaFractionTermServer new. - fraction setParameter: alpha]. + fraction ifNil: [ + fraction := PMIncompleteGammaFractionTermServer new. + fraction setParameter: alpha ]. fraction setArgument: aNumber. - ^(PMContinuedFraction server: fraction) - desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; - evaluate + ^ (PMContinuedFraction server: fraction) + desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; + evaluate ] { #category : #private } PMIncompleteGammaFunction >> evaluateSeries: aNumber [ - series isNil - ifTrue: [ series := PMIncompleteGammaSeriesTermServer new. - series setParameter: alpha. - ]. + series ifNil: [ + series := PMIncompleteGammaSeriesTermServer new. + series setParameter: alpha ]. series setArgument: aNumber. - ^(PMInfiniteSeries server: series) - desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; - evaluate + ^ (PMInfiniteSeries server: series) + desiredPrecision: PMFloatingPointMachine new defaultNumericalPrecision; + evaluate ] { #category : #initialization } PMIncompleteGammaFunction >> initialize: aNumber [ - + alpha := aNumber asFloat. alphaLogGamma := alpha logGamma. ^self @@ -54,13 +52,13 @@ PMIncompleteGammaFunction >> initialize: aNumber [ PMIncompleteGammaFunction >> value: aNumber [ | x norm | - aNumber = 0 - ifTrue: [ ^0]. + aNumber = 0 ifTrue: [ ^ 0 ]. x := aNumber asFloat. - norm := [ ( x ln * alpha - x - alphaLogGamma) exp] on: Error do: [ :signal | signal return: nil]. - norm isNil - ifTrue: [ ^1]. - ^x - 1 < alpha - ifTrue: [ ( self evaluateSeries: x) * norm] - ifFalse:[ 1 - ( norm / ( self evaluateFraction: x))] + norm := [ (x ln * alpha - x - alphaLogGamma) exp ] + on: Error + do: [ :signal | signal return: nil ]. + norm ifNil: [ ^ 1 ]. + ^ x - 1 < alpha + ifTrue: [ (self evaluateSeries: x) * norm ] + ifFalse: [ 1 - (norm / (self evaluateFraction: x)) ] ] diff --git a/src/Math-Distributions/PMIncompleteGammaSeriesTermServer.class.st b/src/Math-Distributions/PMIncompleteGammaSeriesTermServer.class.st index 9bec12b2e..2d4d89d6c 100644 --- a/src/Math-Distributions/PMIncompleteGammaSeriesTermServer.class.st +++ b/src/Math-Distributions/PMIncompleteGammaSeriesTermServer.class.st @@ -16,7 +16,7 @@ PMIncompleteGammaSeriesTermServer >> initialTerm [ ] { #category : #initialization } -PMIncompleteGammaSeriesTermServer >> setParameter: aNumber [ +PMIncompleteGammaSeriesTermServer >> setParameter: aNumber [ alpha := aNumber asFloat ] diff --git a/src/Math-Distributions/PMKernelSmoothedDensity.class.st b/src/Math-Distributions/PMKernelSmoothedDensity.class.st index acdab60a7..1e916ec2a 100644 --- a/src/Math-Distributions/PMKernelSmoothedDensity.class.st +++ b/src/Math-Distributions/PMKernelSmoothedDensity.class.st @@ -29,7 +29,7 @@ PMKernelSmoothedDensity class >> fromData: aCollectionOfNumbers [ |result| result := self new. result data: aCollectionOfNumbers; normal; ruleOfThumbBandWidth. -^result +^result ] { #category : #information } @@ -46,12 +46,12 @@ PMKernelSmoothedDensity >> bandWidth [ { #category : #accessing } PMKernelSmoothedDensity >> bandWidth: aNumber [ -^bandwidth := aNumber +^bandwidth := aNumber ] { #category : #transformation } -PMKernelSmoothedDensity >> changeParametersBy: aVector [ - ^self shouldNotImplement . +PMKernelSmoothedDensity >> changeParametersBy: aVector [ + ^self shouldNotImplement ] { #category : #accessing } @@ -62,50 +62,45 @@ PMKernelSmoothedDensity >> data [ { #category : #accessing } PMKernelSmoothedDensity >> data: aCollectionOfNumbers [ "sample data" -^data := SortedCollection withAll: aCollectionOfNumbers . +^data := SortedCollection withAll: aCollectionOfNumbers ] { #category : #information } PMKernelSmoothedDensity >> distributionValue: aNumber [ ^(data collect:[:x| - ikernel value: (aNumber - x / bandwidth) ])sum / data size + ikernel value: (aNumber - x / bandwidth) ])sum / data size ] { #category : #accessing } PMKernelSmoothedDensity >> epanechnikov [ kernelName:= #epanechnikov. ikernel:=[:x|x < 5 sqrt negated ifTrue:[0]ifFalse:[x > 5 sqrt ifTrue:[1]ifFalse:[(x - ((x raisedToInteger: 3) / 15)) * (3/(4* 5 sqrt))+(1/2)]]]. -^kernel := [:x|x abs >= 5 sqrt ifTrue:[0]ifFalse: [1 - (x squared /5) * (3/(4* 5 sqrt))]]. - +^kernel := [:x|x abs >= 5 sqrt ifTrue:[0]ifFalse: [1 - (x squared /5) * (3/(4* 5 sqrt))]] ] { #category : #accessing } PMKernelSmoothedDensity >> iKernel: aBlock [ "the integral of the kernel, necessary to set for '#distributionValue:' if you set '#kernel:'." -^ikernel := aBlock - +^ikernel := aBlock ] { #category : #accessing } PMKernelSmoothedDensity >> kernel [ ^kernel - ] { #category : #accessing } PMKernelSmoothedDensity >> kernel: aBlock [ "set also ikernel by hand" kernelName:= 'unknown'. -^kernel := aBlock - +^kernel := aBlock ] { #category : #accessing } PMKernelSmoothedDensity >> normal [ kernelName :='normal'. ikernel:=[:x|PMErfApproximation new value:x]. -^kernel:=[:x|(x squared / -2.0)exp / Float twoPi sqrt]. - +^kernel:=[:x|(x squared / -2.0)exp / Float twoPi sqrt] ] { #category : #information } @@ -122,7 +117,7 @@ PMKernelSmoothedDensity >> printOn: aStream [ print: (kernelName='unknown' ifTrue:[kernel]ifFalse: [kernelName]); nextPutAll: ' bandWidth: '; print: bandwidth ; - nextPut: $) . + nextPut: $) ] { #category : #accessing } @@ -137,11 +132,10 @@ PMKernelSmoothedDensity >> ruleOfThumbBandWidth [ PMKernelSmoothedDensity >> value: aNumber [ "smoothed result" ^(data collect:[:x| - kernel value: (aNumber - x / bandwidth)])sum / (data size * bandwidth) - + kernel value: (aNumber - x / bandwidth)])sum / (data size * bandwidth) ] { #category : #information } -PMKernelSmoothedDensity >> variance [ +PMKernelSmoothedDensity >> variance [ ^data stdev squared + bandwidth squared ] diff --git a/src/Math-Distributions/PMLaplaceDistribution.class.st b/src/Math-Distributions/PMLaplaceDistribution.class.st index 2236aa748..94f7911d1 100644 --- a/src/Math-Distributions/PMLaplaceDistribution.class.st +++ b/src/Math-Distributions/PMLaplaceDistribution.class.st @@ -14,7 +14,7 @@ PMLaplaceDistribution class >> distributionName [ ] { #category : #creation } -PMLaplaceDistribution class >> fromHistogram: aHistogram [ +PMLaplaceDistribution class >> fromHistogram: aHistogram [ "Create an instance of the receiver with parameters estimated from the given histogram using best guesses. This method can be used to find the initial values for a fit." diff --git a/src/Math-Distributions/PMLaplaceGenerator.class.st b/src/Math-Distributions/PMLaplaceGenerator.class.st index 7341ff038..e687ee77e 100644 --- a/src/Math-Distributions/PMLaplaceGenerator.class.st +++ b/src/Math-Distributions/PMLaplaceGenerator.class.st @@ -29,7 +29,7 @@ PMLaplaceGenerator class >> shape: peakValue scale: falloffValue [ ] { #category : #accessing } -PMLaplaceGenerator >> next [ +PMLaplaceGenerator >> next [ next := laplaceDistribution random. ^ next diff --git a/src/Math-Distributions/PMLogNormalDistribution.class.st b/src/Math-Distributions/PMLogNormalDistribution.class.st index 0a510fc96..a267985fe 100644 --- a/src/Math-Distributions/PMLogNormalDistribution.class.st +++ b/src/Math-Distributions/PMLogNormalDistribution.class.st @@ -58,7 +58,7 @@ PMLogNormalDistribution >> average [ { #category : #transformation } PMLogNormalDistribution >> changeParametersBy: aVector [ "Modify the parameters of the receiver by aVector." - normalDistribution changeParametersBy: aVector. + normalDistribution changeParametersBy: aVector ] { #category : #information } diff --git a/src/Math-Distributions/PMMitchellMooreGenerator.class.st b/src/Math-Distributions/PMMitchellMooreGenerator.class.st index 90ead562c..485ff714c 100644 --- a/src/Math-Distributions/PMMitchellMooreGenerator.class.st +++ b/src/Math-Distributions/PMMitchellMooreGenerator.class.st @@ -35,15 +35,15 @@ PMMitchellMooreGenerator class >> generateSeeds: congruentialGenerator [ { #category : #creation } PMMitchellMooreGenerator class >> new [ - UniqueInstance isNil - ifTrue: [ UniqueInstance := self default]. - ^UniqueInstance + + UniqueInstance ifNil: [ UniqueInstance := self default ]. + ^ UniqueInstance ] { #category : #creation } PMMitchellMooreGenerator class >> reset: anInteger [ "Reset the unique instance used for the default series" - UniqueInstance := self seed: anInteger. + UniqueInstance := self seed: anInteger ] { #category : #creation } diff --git a/src/Math-Distributions/PMMultivariateNormalDistribution.class.st b/src/Math-Distributions/PMMultivariateNormalDistribution.class.st index fca627b97..e1ac8f113 100644 --- a/src/Math-Distributions/PMMultivariateNormalDistribution.class.st +++ b/src/Math-Distributions/PMMultivariateNormalDistribution.class.st @@ -25,25 +25,25 @@ PMMultivariateNormalDistribution >> average [ PMMultivariateNormalDistribution >> changeParametersBy: aVector [ "Modify the parameters of the receiver by aVector." meanVector := meanVector + aVector first. - covarianceMatrix := covarianceMatrix + aVector second. + covarianceMatrix := covarianceMatrix + aVector second ] { #category : #information } PMMultivariateNormalDistribution >> covarianceMatrix [ - ^ covarianceMatrix + ^ covarianceMatrix ] { #category : #information } PMMultivariateNormalDistribution >> distributionValue: aNumber [ "Answers the probability of observing a random variable distributed according to the receiver with a value lower than or equal to aNumber. Also known as the cumulative density function (CDF)." - - self shouldBeImplemented + + self shouldBeImplemented ] { #category : #initialization } PMMultivariateNormalDistribution >> initializeMeanVector: aMeanVector covarianceMatrix: aCovarianceMatrix [ meanVector := aMeanVector. - covarianceMatrix := aCovarianceMatrix. + covarianceMatrix := aCovarianceMatrix ] { #category : #information } @@ -54,12 +54,12 @@ PMMultivariateNormalDistribution >> kurtosis [ { #category : #information } PMMultivariateNormalDistribution >> meanVector [ - ^ meanVector + ^ meanVector ] { #category : #information } PMMultivariateNormalDistribution >> parameters [ - "Returns an Array containing the parameters of the distribution. + "Returns an Array containing the parameters of the distribution. It is used to print out the distribution and for fitting." ^ { meanVector . covarianceMatrix } @@ -72,15 +72,15 @@ PMMultivariateNormalDistribution >> power [ ] { #category : #information } -PMMultivariateNormalDistribution >> random [ +PMMultivariateNormalDistribution >> random [ "Answer a vector of random numbers distributed accroding to the receiver." | standardNormalRandom upperTriangular | - + standardNormalRandom := (1 to: self power) asPMVector collect: [ :each | PMNormalDistribution random ]. - + upperTriangular := covarianceMatrix choleskyDecomposition. - + ^ upperTriangular transpose * standardNormalRandom + meanVector ] @@ -93,6 +93,6 @@ PMMultivariateNormalDistribution >> skewness [ { #category : #information } PMMultivariateNormalDistribution >> value: aVector [ "Answers the probability that a random variable distributed according to the receiver gives a value between aVector and aVector + espilon (infinitesimal interval)." - + ^ (-1/2 * (aVector - meanVector) * covarianceMatrix inverse * (aVector - meanVector)) exp / (((2 * Float pi) raisedTo: self power) * covarianceMatrix determinant) sqrt ] diff --git a/src/Math-Distributions/PMNormalDistribution.class.st b/src/Math-Distributions/PMNormalDistribution.class.st index 7e7e4f080..526ea05c2 100644 --- a/src/Math-Distributions/PMNormalDistribution.class.st +++ b/src/Math-Distributions/PMNormalDistribution.class.st @@ -15,23 +15,23 @@ Class { PMNormalDistribution class >> boxMullerTransform [ | random v1 v2 w y | random := Random new. - + [ v1 :=random next * 2 - 1. v2 := random next * 2 - 1. w := v1 squared + v2 squared. w > 1 ] whileTrue. - + y := (w ln * 2 negated / w) sqrt. v1 := y * v1. NextRandom := y * v2. - ^v1. + ^v1 ] { #category : #information } PMNormalDistribution class >> distributionName [ - + ^'Normal distribution' ] @@ -63,7 +63,7 @@ PMNormalDistribution class >> random [ | v1 | NextRandom ifNil: [ - + v1 := self boxMullerTransform ] ifNotNil: [ v1 := NextRandom. NextRandom := nil ]. @@ -80,7 +80,7 @@ PMNormalDistribution >> average [ PMNormalDistribution >> changeParametersBy: aVector [ "Modify the parameters of the receiver by aVector." mu := mu + ( aVector at: 1). - sigma := sigma + ( aVector at: 2). + sigma := sigma + ( aVector at: 2) ] { #category : #information } @@ -129,7 +129,7 @@ PMNormalDistribution >> standardDeviation [ { #category : #information } PMNormalDistribution >> value: aNumber [ "Answers the probability that a random variable distributed according to the receiver gives a value between aNumber and aNumber + espilon (infinitesimal interval)." - + ^( PMErfApproximation new normal: (aNumber - mu) / sigma) / sigma ] diff --git a/src/Math-Distributions/PMProbabilityDensity.class.st b/src/Math-Distributions/PMProbabilityDensity.class.st index 001a3c05f..b1090d8c9 100644 --- a/src/Math-Distributions/PMProbabilityDensity.class.st +++ b/src/Math-Distributions/PMProbabilityDensity.class.st @@ -9,7 +9,7 @@ Class { { #category : #information } PMProbabilityDensity class >> distributionName [ - + ^'Unknown distribution' ] @@ -23,7 +23,7 @@ PMProbabilityDensity class >> fromHistogram: aHistogram [ { #category : #information } PMProbabilityDensity >> acceptanceBetween: aNumber1 and: aNumber2 [ "Answers the probability of observing a random variable distributed according to the receiver with a value larger than aNumber 1 and lower than or equal to aNumber2. " - + ^ (self distributionValue: aNumber2) - (self distributionValue: aNumber1) ] @@ -54,11 +54,11 @@ PMProbabilityDensity >> approximatedValueAndGradient: aNumber [ { #category : #information } PMProbabilityDensity >> average [ "Answer the average of the receiver." - self subclassResponsibility. + self subclassResponsibility ] { #category : #transformation } -PMProbabilityDensity >> changeParametersBy: aVector [ +PMProbabilityDensity >> changeParametersBy: aVector [ self subclassResponsibility ] @@ -78,15 +78,15 @@ PMProbabilityDensity >> distributionValue: aNumber [ PMProbabilityDensity >> flatGenerator: aGenerator [ "To change the default generator (which by default is flat between 0 and 1). aGenerator should know how to answer floatValue." - + flatGenerator := aGenerator ] -{ #category : #initialize } +{ #category : #initialization } PMProbabilityDensity >> initialize [ super initialize. - flatGenerator := PMMitchellMooreGenerator new. + flatGenerator := PMMitchellMooreGenerator new ] { #category : #information } @@ -109,31 +109,28 @@ PMProbabilityDensity >> kurtosis [ { #category : #information } PMProbabilityDensity >> parameters [ - "Returns an Array containing the parameters of the distribution. + "Returns an Array containing the parameters of the distribution. It is used to print out the distribution and for fitting." self subclassResponsibility ] { #category : #display } -PMProbabilityDensity >> printOn: aStream [ +PMProbabilityDensity >> printOn: aStream [ | params | aStream nextPutAll: self class distributionName. - (params := self parameters) notNil - ifTrue: - [| first | - first := true. - aStream nextPut: $(. - params - do: - [:each | - first - ifTrue: [first := false] - ifFalse: [aStream nextPut: $,]. - aStream space. - each printOn: aStream]. - aStream nextPut: $)] + (params := self parameters) ifNotNil: [ + | first | + first := true. + aStream nextPut: $(. + params do: [ :each | + first + ifTrue: [ first := false ] + ifFalse: [ aStream nextPut: $, ]. + aStream space. + each printOn: aStream ]. + aStream nextPut: $) ] ] { #category : #private } diff --git a/src/Math-Distributions/PMStudentDistribution.class.st b/src/Math-Distributions/PMStudentDistribution.class.st index faa82ecb7..e337e9ef4 100644 --- a/src/Math-Distributions/PMStudentDistribution.class.st +++ b/src/Math-Distributions/PMStudentDistribution.class.st @@ -12,18 +12,18 @@ Class { { #category : #creation } PMStudentDistribution class >> asymptoticLimit [ - + ^30 ] { #category : #creation } -PMStudentDistribution class >> degreeOfFreedom: anInteger [ +PMStudentDistribution class >> degreeOfFreedom: anInteger [ "Create a new instance of the receiver with anInteger degrees of freedom." - ^anInteger > self asymptoticLimit + ^anInteger > self asymptoticLimit ifTrue: [PMNormalDistribution new] - ifFalse: - [anInteger = 1 + ifFalse: + [anInteger = 1 ifTrue: [PMCauchyDistribution shape: 0 scale: 1] ifFalse: [super new initialize: anInteger]] ] @@ -70,21 +70,21 @@ PMStudentDistribution >> average [ PMStudentDistribution >> changeParametersBy: aVector [ "Modify the parameters of the receiver by aVector." degreeOfFreedom := degreeOfFreedom + ( aVector at: 1). - self computeNorm. + self computeNorm ] { #category : #information } PMStudentDistribution >> chiSquareDistribution [ "Answer the chi square distribution used to generate random numbers for the receiver." - chiSquareDistribution isNil - ifTrue: [ chiSquareDistribution := PMChiSquareDistribution degreeOfFreedom: (degreeOfFreedom - 1)]. - ^chiSquareDistribution + + chiSquareDistribution ifNil: [ chiSquareDistribution := PMChiSquareDistribution degreeOfFreedom: degreeOfFreedom - 1 ]. + ^ chiSquareDistribution ] { #category : #private } PMStudentDistribution >> computeNorm [ "Private - Compute the norm of the receiver because its parameters have changed." - norm := ( ( degreeOfFreedom / 2 logBeta: ( 1 / 2) ) + ( degreeOfFreedom ln / 2)) negated. + norm := ( ( degreeOfFreedom / 2 logBeta: ( 1 / 2) ) + ( degreeOfFreedom ln / 2)) negated ] { #category : #information } @@ -107,12 +107,8 @@ PMStudentDistribution >> distributionValue: aNumber [ PMStudentDistribution >> incompleteBetaFunction [ "Private - Answers the incomplete beta function used to compute the symmetric acceptance integral of the receiver." - incompleteBetaFunction isNil - ifTrue: - [incompleteBetaFunction := PMIncompleteBetaFunction - shape: degreeOfFreedom / 2 - shape: 0.5]. - ^incompleteBetaFunction + incompleteBetaFunction ifNil: [ incompleteBetaFunction := PMIncompleteBetaFunction shape: degreeOfFreedom / 2 shape: 0.5 ]. + ^ incompleteBetaFunction ] { #category : #initialization } @@ -146,7 +142,7 @@ PMStudentDistribution >> random [ { #category : #information } PMStudentDistribution >> skewness [ - + ^0 ] @@ -165,7 +161,7 @@ PMStudentDistribution >> value: aNumber [ { #category : #information } PMStudentDistribution >> variance [ "Answer the variance of the receiver. Undefined if the degree of freedom is less than 3." - ^degreeOfFreedom > 2 + ^degreeOfFreedom > 2 ifTrue: [ degreeOfFreedom / ( degreeOfFreedom - 2)] ifFalse:[ nil] ] diff --git a/src/Math-Distributions/PMTriangularDistribution.class.st b/src/Math-Distributions/PMTriangularDistribution.class.st index 2c2dbad5f..24a4fc8f0 100644 --- a/src/Math-Distributions/PMTriangularDistribution.class.st +++ b/src/Math-Distributions/PMTriangularDistribution.class.st @@ -24,7 +24,7 @@ PMTriangularDistribution class >> fromHistogram: aHistogram [ b = 0 ifTrue: [ ^nil]. c := aHistogram average. - ^self new: c from: ( c - b) to: ( c + b). + ^self new: c from: ( c - b) to: ( c + b) ] { #category : #creation } diff --git a/src/Math-Distributions/PMUniformDistribution.class.st b/src/Math-Distributions/PMUniformDistribution.class.st index b988d797a..106207c89 100644 --- a/src/Math-Distributions/PMUniformDistribution.class.st +++ b/src/Math-Distributions/PMUniformDistribution.class.st @@ -30,7 +30,7 @@ PMUniformDistribution class >> fromHistogram: aHistogram [ b = 0 ifTrue: [ ^nil]. c := aHistogram average. - ^self from: ( c - b) to: ( c + b). + ^self from: ( c - b) to: ( c + b) ] { #category : #public } diff --git a/src/Math-Distributions/PMWeibullDistribution.class.st b/src/Math-Distributions/PMWeibullDistribution.class.st index c6f19090a..10bfadf00 100644 --- a/src/Math-Distributions/PMWeibullDistribution.class.st +++ b/src/Math-Distributions/PMWeibullDistribution.class.st @@ -38,14 +38,14 @@ PMWeibullDistribution class >> new [ ] { #category : #creation } -PMWeibullDistribution class >> shape: aNumber1 scale: aNumber2 [ +PMWeibullDistribution class >> shape: aNumber1 scale: aNumber2 [ "Create an instance of the receiver with given shape and scale parameters." ^super new initialize: aNumber1 scale: aNumber2 ] { #category : #creation } -PMWeibullDistribution class >> solve: lowX acc: lowAcc upper: highX acc: highAcc [ +PMWeibullDistribution class >> solve: lowX acc: lowAcc upper: highX acc: highAcc [ "Private" | lowLnAcc highLnAcc deltaLnAcc lowLnX highLnX | @@ -69,13 +69,13 @@ PMWeibullDistribution >> changeParametersBy: aVector [ "Modify the parameters of the receiver by aVector." alpha := alpha + ( aVector at: 1). beta := beta + ( aVector at: 2). - self computeNorm. + self computeNorm ] { #category : #initialization } PMWeibullDistribution >> computeNorm [ "Private - Compute the norm of the receiver because its parameters have changed." - norm := alpha/ ( beta raisedTo: alpha). + norm := alpha/ ( beta raisedTo: alpha) ] { #category : #information } diff --git a/src/Math-FastFourierTransform/PMFastFourierTransform.class.st b/src/Math-FastFourierTransform/PMFastFourierTransform.class.st index 708a530fb..a958e0050 100644 --- a/src/Math-FastFourierTransform/PMFastFourierTransform.class.st +++ b/src/Math-FastFourierTransform/PMFastFourierTransform.class.st @@ -21,17 +21,17 @@ Class { PMFastFourierTransform class >> data: anArrayOfNumbersOrComplex [ ^ self new data: anArrayOfNumbersOrComplex; - yourself + yourself ] { #category : #accessing } PMFastFourierTransform >> chop: tolerance [ "sets numbers smaller than tolerance to zero" - | r i | + | r i | ^ data := data collect: - [ :k | + [ :k | r := k real. i := k imaginary. r abs < tolerance @@ -67,14 +67,14 @@ PMFastFourierTransform >> data: anArrayOfNumberOrComplex [ { #category : #accessing } PMFastFourierTransform >> imaginaryData [ - ^ data collect: [ :i | i imaginary ] + ^ data collect: [ :i | i imaginary ] ] { #category : #initializing } PMFastFourierTransform >> initPermTable [ | r | permTable := OrderedCollection new: n // 2. - 2 to: n - 1 do: [ :i | + 2 to: n - 1 do: [ :i | r := (i - 1 bitReverse: nu) + 1. r > i ifTrue: [ permTable @@ -107,11 +107,11 @@ PMFastFourierTransform >> multiplier: theta [ { #category : #accessing } PMFastFourierTransform >> n [ - ^ n + ^ n ] { #category : #accessing } -PMFastFourierTransform >> realData [ +PMFastFourierTransform >> realData [ ^ data collect: [ :i | i real ] ] @@ -129,15 +129,15 @@ PMFastFourierTransform >> transform [ ] { #category : #private } -PMFastFourierTransform >> transformForward: forward [ +PMFastFourierTransform >> transformForward: forward [ | lev lev1 ip temp temp2 i | permTable do: [ :j | data swap: j first with: j second ]. 1 to: nu do: - [ :level | + [ :level | lev := 1 bitShift: level. lev1 := lev // 2. 1 to: lev1 do: - [ :j | + [ :j | temp := self multiplier: (j - 1) * (n // lev). forward ifFalse: [ temp := temp complexConjugate ]. diff --git a/src/Math-FastFourierTransform/SmallInteger.extension.st b/src/Math-FastFourierTransform/SmallInteger.extension.st index 55749345d..702985264 100644 --- a/src/Math-FastFourierTransform/SmallInteger.extension.st +++ b/src/Math-FastFourierTransform/SmallInteger.extension.st @@ -3,10 +3,10 @@ Extension { #name : #SmallInteger } { #category : #'*Math-FastFourierTransform' } SmallInteger >> byteReversed [ "Answer the receiver with bits reversed in a byte. The receiver must be between 0 and 255. The constant has been obtained by this snippet: -(0 to: 255) collect: [:e | - | r | - r := ((e bitAnd: 2r11110000) bitShift: -4) + ((e bitAnd: 2r00001111) bitShift: 4). - r := ((r bitAnd: 2r11001100) bitShift: -2) + ((r bitAnd: 2r00110011) bitShift: 2). +(0 to: 255) collect: [:e | + | r | + r := ((e bitAnd: 2r11110000) bitShift: -4) + ((e bitAnd: 2r00001111) bitShift: 4). + r := ((r bitAnd: 2r11001100) bitShift: -2) + ((r bitAnd: 2r00110011) bitShift: 2). ((r bitAnd: 2r10101010) bitShift: -1) + ((r bitAnd: 2r01010101) bitShift: 1).] as: ByteArray" ^ #[0 128 64 192 32 160 96 224 16 144 80 208 48 176 112 240 8 136 72 200 40 168 104 232 24 152 88 216 56 184 120 248 4 132 68 196 36 164 100 228 20 148 84 212 52 180 116 244 12 140 76 204 44 172 108 236 28 156 92 220 60 188 124 252 2 130 66 194 34 162 98 226 18 146 82 210 50 178 114 242 10 138 74 202 42 170 106 234 26 154 90 218 58 186 122 250 6 134 70 198 38 166 102 230 22 150 86 214 54 182 118 246 14 142 78 206 46 174 110 238 30 158 94 222 62 190 126 254 1 129 65 193 33 161 97 225 17 145 81 209 49 177 113 241 9 137 73 201 41 169 105 233 25 153 89 217 57 185 121 249 5 133 69 197 37 165 101 229 21 149 85 213 53 181 117 245 13 141 77 205 45 173 109 237 29 157 93 221 61 189 125 253 3 131 67 195 35 163 99 227 19 147 83 211 51 179 115 243 11 139 75 203 43 171 107 235 27 155 91 219 59 187 123 251 7 135 71 199 39 167 103 231 23 151 87 215 55 183 119 247 15 143 79 207 47 175 111 239 31 159 95 223 63 191 127 255] diff --git a/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st b/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st index 1e12cc422..43dc664b6 100644 --- a/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st +++ b/src/Math-FunctionFit/PMAnotherChromosomeManager.class.st @@ -16,7 +16,7 @@ Class { #category : #'Math-FunctionFit' } -{ #category : #utils } +{ #category : #utilities } PMAnotherChromosomeManager class >> integerDigitsFor: anInteger base: aBase [ | n integer next result | "n:=(anInteger ln / aBase ln) floor ." "does not always work because of floating point errors. next 2 lines are better" @@ -32,34 +32,34 @@ PMAnotherChromosomeManager class >> integerDigitsFor: anInteger base: aBase [ ^result ] -{ #category : #utils } +{ #category : #utilities } PMAnotherChromosomeManager class >> numberOfHamersleyPoints: n dimension: d randomized: aBoolean [ "a bit randomized " | dist randomNumberGenerator | 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| + 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 ] ] ]]. + ifFalse: [ sum ] ] ]]. ] { #category : #'instance creation' } PMAnotherChromosomeManager class >> origin: anArray range: anotherArray [ -^self new origin: anArray; range: anotherArray; yourself +^self new origin: anArray; range: anotherArray; yourself ] { #category : #operation } @@ -67,20 +67,20 @@ PMAnotherChromosomeManager >> crossover: aChromosome1 and: aChromosome2 [ "the Discrete Recombination operator that does not prefer schemata of certain parameters based on their position" | new1 new2 | - + aChromosome1 = aChromosome2 ifTrue:[ ^ Array with: (self mutate: aChromosome2) with: (self mutate: aChromosome1) ]. - + new1 := self clone: aChromosome1. new2 := self clone: aChromosome2. - + 2 to: new1 size do: [ :i | (randomNumberGenerator next < 0.5) ifTrue: [ new1 at: i put: (aChromosome2 at: i). new2 at: i put: (aChromosome1 at: i) ] ]. - + ^ Array with: new1 with: new2 ] @@ -89,26 +89,25 @@ PMAnotherChromosomeManager >> eirCrossover: aChromosome1 and: aChromosome2 [ "the Extended Intermediate Recombination 0.5 operator, slightly changed to make it more similar to linecrossover (distribution is more centered around Chromosome1, which is better than C2)" | randomNumbers new1 new2 dif | dif := aChromosome2 - aChromosome1. - + dif norm = 0 ifTrue: [ ^ { self mutate: aChromosome2 . self mutate: aChromosome1 } ]. - + randomNumbers := (1 to: aChromosome1 size) collect: [ :i | randomNumberGenerator nextBetween: -0.5 and: 1.5 ]. - + new1 := aChromosome1 + (randomNumbers * dif). - + randomNumbers := (1 to: aChromosome1 size) collect: [ :i | randomNumberGenerator nextBetween: -0.5 and: 0.5 ]. - + new2 := aChromosome1 + (randomNumbers * dif). - - ^ { new1 . new2 } + ^ { new1 . new2 } ] { #category : #initialization } -PMAnotherChromosomeManager >> initialize [ +PMAnotherChromosomeManager >> initialize [ super initialize . populationSize :=100. hammersley :=true. @@ -117,14 +116,12 @@ rateOfLC:=0.29. rateOfMutation :=0.4. rateOfCrossover :=0.15. Primes ifNil:[Primes :=Integer primesUpTo: 500]. "sufficient for up to 95 dimensions (parameters)" - - ] { #category : #information } -PMAnotherChromosomeManager >> isFullyPopulated [ +PMAnotherChromosomeManager >> isFullyPopulated [ population ifNil: [^false]. -^super isFullyPopulated +^super isFullyPopulated ] { #category : #operation } @@ -144,29 +141,29 @@ PMAnotherChromosomeManager >> lineCrossOver: aChromosome1 and: aChromosome2 [ PMAnotherChromosomeManager >> mutate: aVector [ "BGA mutation" | isMutated threshold new index | - + isMutated := false. threshold := 1 / aVector size asFloat. new := aVector copy. - + 1 to: aVector size do: [ :i | randomNumberGenerator next < threshold ifTrue: [ isMutated := true. - new at: i put: (new at: i) + + new at: i put: (new at: i) + ((randomNumberGenerator next < 0.5 ifTrue: [ 0.5 ] ifFalse:[ -0.5 ]) * (self randomRangeAt: i)) ] ]. - + isMutated ifFalse: [ index := randomNumberGenerator nextIntegerBetween: 1 and: aVector size. - new at: index put: (new at: index) + + new at: index put: (new at: index) + ((randomNumberGenerator next < 0.5 ifTrue: [ 0.5 ] ifFalse:[ -0.5 ]) * (self randomRangeAt: index)) ]. - + ^ new ] { #category : #accessing } -PMAnotherChromosomeManager >> populationSize [ +PMAnotherChromosomeManager >> populationSize [ "AnotherGeneticOptimizer needs these data" -^populationSize +^populationSize ] { #category : #printing } @@ -181,27 +178,27 @@ PMAnotherChromosomeManager >> printOn: aStream [ nextPutAll: ' CORate: ';print: rateOfCrossover ; nextPutAll: ' LCRate: ';print: rateOfLC ; nextPutAll: ' EIRRate: ';print: rateOfEir; - nextPut: $) . + nextPut: $) ] { #category : #operation } -PMAnotherChromosomeManager >> process: aChromosome1 and: aChromosome2 [ +PMAnotherChromosomeManager >> process: aChromosome1 and: aChromosome2 [ | roll | roll := randomNumberGenerator next. - roll < rateOfCrossover + roll < rateOfCrossover ifTrue: [population addAll: (self crossover: aChromosome1 and: aChromosome2)] - ifFalse: - [roll < (rateOfCrossover + rateOfMutation) - ifTrue: + ifFalse: + [roll < (rateOfCrossover + rateOfMutation) + ifTrue: [population add: (self mutate: aChromosome1); add: (self mutate: aChromosome2)] - ifFalse: - [roll < (rateOfCrossover + rateOfMutation+rateOfEir) - ifTrue: + ifFalse: + [roll < (rateOfCrossover + rateOfMutation+rateOfEir) + ifTrue: [population addAll: (self eirCrossover: aChromosome1 and: aChromosome2)] - ifFalse: [roll < (rateOfCrossover + rateOfMutation+rateOfEir+rateOfLC) - ifTrue: + ifFalse: [roll < (rateOfCrossover + rateOfMutation+rateOfEir+rateOfLC) + ifTrue: [population addAll: (self lineCrossOver: aChromosome1 and: aChromosome2)] ifFalse: [population add: (self clone: aChromosome1); @@ -223,25 +220,25 @@ population := population collect: [:aChr| aChr *range +origin ] { #category : #accessing } PMAnotherChromosomeManager >> range [ "AnotherGeneticOptimizer needs these data" -^range +^range ] { #category : #initialization } -PMAnotherChromosomeManager >> rateOfCrossover: aNumber [ +PMAnotherChromosomeManager >> rateOfCrossover: aNumber [ self testRate: aNumber oldRate: rateOfCrossover name: 'rateOfCrossover'. rateOfCrossover := aNumber ] { #category : #initialization } -PMAnotherChromosomeManager >> rateOfEir: aNumber [ +PMAnotherChromosomeManager >> rateOfEir: aNumber [ self testRate: aNumber oldRate: rateOfEir name: 'rateOfEir'. rateOfEir := aNumber ] { #category : #initialization } -PMAnotherChromosomeManager >> rateOfLC: aNumber [ +PMAnotherChromosomeManager >> rateOfLC: aNumber [ self testRate: aNumber oldRate: rateOfLC name: 'rateOfLC'. rateOfLC := aNumber @@ -263,7 +260,7 @@ PMAnotherChromosomeManager >> smallDistribution [ PMAnotherChromosomeManager >> testRate:aFloat oldRate: asecondFloat name:aString [ (aFloat between: 0 and: 1) ifFalse: [(DomainError new)from:0;to:1;messageText: 'Value outside [0 , 1]';signalIn: thisContext sender]. (rateOfCrossover + rateOfMutation + rateOfLC + rateOfEir + aFloat - asecondFloat)>1.000000000000001 "for Float inaccuracies" - ifTrue: [Warning signal:'All rates together are higher than 1, if ' , aString, ' is set to ',aFloat asString ]. + ifTrue: [Warning signal:'All rates together are higher than 1, if ' , aString, ' is set to ',aFloat asString ] ] { #category : #initialization } diff --git a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st index fefe31be6..2e28abb6f 100644 --- a/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st +++ b/src/Math-FunctionFit/PMAnotherGeneticOptimizer.class.st @@ -14,7 +14,7 @@ Class { 'whateverHistory', 'originalFunction' ], - #category : 'Math-FunctionFit' + #category : #'Math-FunctionFit' } { #category : #information } @@ -30,48 +30,46 @@ m :=PMAnotherChromosomeManager new. m populationSize: 50. o chromosomeManager:m. o maximumIterations: 170. -(anotherArray - anArray allSatisfy: [:each| each >0]) ifFalse: +(anotherArray - anArray allSatisfy: [:each| each >0]) ifFalse: [^DomainError signal: 'maximum values should be greater than minimum values']. m origin: anArray. m range: (anotherArray - anArray). ^o - ] { #category : #transformation } PMAnotherGeneticOptimizer >> add: aMinimizingPoint [ -^bestPoints add: aMinimizingPoint +^bestPoints add: aMinimizingPoint ] { #category : #transformation } PMAnotherGeneticOptimizer >> addPointAt: aVector [ -"makes room if necessary and adds point only, -if there is already enough room or the bestPoints get better with the new point" +"makes room if necessary and adds point only, +if there is already enough room or the bestPoints get better with the new point" |p| p:=optimizingPointClass vector: aVector function: functionBlock. ((p value isInfinite)or:[p value isNaN]) ifTrue:[^self]. (bestPoints size >= chromosomeManager populationSize) - ifTrue: [(p betterThan: bestPoints last ) ifTrue: + ifTrue: [(p betterThan: bestPoints last ) ifTrue: [removeLast ifTrue: [bestPoints removeLast] ifFalse: [self removeNearestTo: p]. - self add: p] ] - ifFalse: [self add: p]. + self add: p] ] + ifFalse: [self add: p] ] { #category : #information } -PMAnotherGeneticOptimizer >> bestValueHistory [ -^bestValueHistory +PMAnotherGeneticOptimizer >> bestValueHistory [ +^bestValueHistory ] { #category : #accessing } PMAnotherGeneticOptimizer >> calcStatistics:aBoolean [ "calc the best and the worst function return history. default is false." -statistics :=aBoolean +statistics :=aBoolean ] { #category : #accessing } PMAnotherGeneticOptimizer >> chromosomeManager [ -^chromosomeManager - +^chromosomeManager ] { #category : #operation } @@ -87,11 +85,11 @@ PMAnotherGeneticOptimizer >> collectPoints [ ] { #category : #information } -PMAnotherGeneticOptimizer >> computePrecision: whateverData [ "can be changed to check how the ga behaves" +PMAnotherGeneticOptimizer >> computePrecision: whateverData [ "can be changed to check how the ga behaves" statistics ifTrue: [bestValueHistory add: bestPoints first value. whateverHistory add: whateverData . - worstValueHistory add: bestPoints last value]. + worstValueHistory add: bestPoints last value]. ^steadyState ifTrue: [bestPoints last value - bestPoints first value] ifFalse: [1] ] @@ -112,32 +110,31 @@ PMAnotherGeneticOptimizer >> findNearestTo: anOptimizingPointClass [ |max dist| max:=Array with: bestPoints size with: Float infinity. (bestPoints size to: 2 by: -1) - do: [:index |(anOptimizingPointClass better: (bestPoints at: index) ) ifTrue: + do: [:index |(anOptimizingPointClass better: (bestPoints at: index) ) ifTrue: [dist:=(anOptimizingPointClass position - (bestPoints at: index) position / chromosomeManager range)abs sum. dist=0 ifTrue:[^index ]. - (dist < max second) ifTrue: [max at: 1 put: index. max at: 2 put: dist]] ifFalse: + (dist < max second) ifTrue: [max at: 1 put: index. max at: 2 put: dist]] ifFalse: [ ^max first]] . - ^max first. + ^max first ] { #category : #initialization } -PMAnotherGeneticOptimizer >> initialize [ +PMAnotherGeneticOptimizer >> initialize [ super initialize . rangeScale :=true. steadyState :=true. removeLast:=false. -statistics :=false. +statistics :=false ] { #category : #operation } PMAnotherGeneticOptimizer >> initializeIterations [ - bestPoints size>=chromosomeManager populationSize + 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. - + whateverHistory:=OrderedCollection new ] { #category : #operation } @@ -210,7 +207,7 @@ PMAnotherGeneticOptimizer >> processRandomParents: aNumberArray [ pos2 := self randomIndex: aNumberArray. pos1 > pos2 ifTrue: [c := pos1. pos1 := pos2. pos2 := c]. chromosomeManager process: ( bestPoints at: pos1) position - and: ( bestPoints at: pos2) position. + and: ( bestPoints at: pos2) position ] { #category : #operation } @@ -219,32 +216,31 @@ PMAnotherGeneticOptimizer >> rangeScale [ | size best| size:=bestPoints size -1. best := 0.0 . -^(size to: 1 by: (-1)) collect: [:i | best := 2 * i / (size * (size + 1)) + best]. - +^(size to: 1 by: (-1)) collect: [:i | best := 2 * i / (size * (size + 1)) + best] ] { #category : #accessing } PMAnotherGeneticOptimizer >> rangeScale: aBoolean [ "if rangeScale is false the old method of selecting an individual proportionally to its fitness is used, if it is true a constant selection pressure is used. default is true. " -rangeScale :=aBoolean +rangeScale :=aBoolean ] { #category : #accessing } PMAnotherGeneticOptimizer >> removeLast: aBoolean [ "if steadyState is true, then either the worst individual (removeLast:true) is deleted, or the most similar to the new individual (removeLast:false) is deleted, to make room for the new one. default is false, since this keeps diversity high. But it is a bit slow" -removeLast :=aBoolean . +removeLast :=aBoolean ] { #category : #transformation } PMAnotherGeneticOptimizer >> removeNearestTo: anOptimizingPointClass [ -bestPoints removeAt: (self findNearestTo: anOptimizingPointClass). +bestPoints removeAt: (self findNearestTo: anOptimizingPointClass) ] { #category : #operation } -PMAnotherGeneticOptimizer >> resetBestPoints [ +PMAnotherGeneticOptimizer >> resetBestPoints [ "for repeated evaluating with different starting populations" bestPoints := SortedCollection sortBlock: [ :a :b | a betterThan: b]. -result :=nil. +result :=nil ] { #category : #initialization } @@ -253,22 +249,21 @@ PMAnotherGeneticOptimizer >> setFunction: aBlock [ ifFalse:[ self error: 'Function block must implement the method value:']. originalFunction :=aBlock . "necessary for subclass; do not delete that nonsense!" functionBlock := aBlock. - self resetBestPoints. - + self resetBestPoints ] { #category : #accessing } PMAnotherGeneticOptimizer >> steadyState: aBoolean [ "if steadyState is false, the old method of making room for new individuals after one iteration and just keeping the best so far is used. If it is true (the default), then everything is kept and only offspring that are better than the worst so far are put into the population." -steadyState :=aBoolean . +steadyState :=aBoolean ] { #category : #information } -PMAnotherGeneticOptimizer >> whateverHistory [ -^whateverHistory +PMAnotherGeneticOptimizer >> whateverHistory [ +^whateverHistory ] { #category : #information } -PMAnotherGeneticOptimizer >> worstValueHistory [ -^worstValueHistory +PMAnotherGeneticOptimizer >> worstValueHistory [ +^worstValueHistory ] diff --git a/src/Math-FunctionFit/PMDataHolder.class.st b/src/Math-FunctionFit/PMDataHolder.class.st index 3d7899d38..2ad18edc7 100644 --- a/src/Math-FunctionFit/PMDataHolder.class.st +++ b/src/Math-FunctionFit/PMDataHolder.class.st @@ -5,12 +5,12 @@ Class { #name : #PMDataHolder, #superclass : #Array, #type : #variable, - #category : 'Math-FunctionFit' + #category : #'Math-FunctionFit' } { #category : #iterators } PMDataHolder >> pointsAndErrorsDo: aBlock [ "uses an unweighted approach; the weighted one does not make sense here and is dangerous, if done too naively, eg because of negative or infinite weights" self do: - [ :each | aBlock value: (PMWeightedPoint point: each)]. + [ :each | aBlock value: (PMWeightedPoint point: each)] ] diff --git a/src/Math-FunctionFit/PMErrorAsParameterFunction.class.st b/src/Math-FunctionFit/PMErrorAsParameterFunction.class.st index 4433b1bc4..1b2087201 100644 --- a/src/Math-FunctionFit/PMErrorAsParameterFunction.class.st +++ b/src/Math-FunctionFit/PMErrorAsParameterFunction.class.st @@ -4,12 +4,12 @@ ErrorAsParameterFunction is used internally by ErrorMinimizer. it is essentially Class { #name : #PMErrorAsParameterFunction, #superclass : #PMSimpleParameterFunction, - #category : 'Math-FunctionFit' + #category : #'Math-FunctionFit' } { #category : #accessing } PMErrorAsParameterFunction >> changeParametersBy: aVector [ -varArray :=varArray + aVector . +varArray :=varArray + aVector ] { #category : #initialization } @@ -24,7 +24,7 @@ size :=size +steps //2. size := size min: steps. steps :=d size //size -1. steps > maxFunction [ { #category : #accessing } PMErrorAsParameterFunction >> parameters [ -^varArray +^varArray ] { #category : #accessing } PMErrorAsParameterFunction >> parameters: indexableCollection [ -^varArray :=indexableCollection copy. - +^varArray :=indexableCollection copy ] { #category : #printing } PMErrorAsParameterFunction >> printOn: aStream [ + aStream nextPutAll: 'an '; nextPutAll: self class name; nextPutAll: '( function: '; - print: (function ifNil: [ nil ] ifNotNil: [ :f | f first ]); + print: (function ifNotNil: [ :f | f first ]); nextPutAll: ' maxFunction: '; print: self maxFunction. - varArray - ifNotNil: [ aStream - nextPutAll: ' parameters: '; - print: self parameters ]. + varArray ifNotNil: [ + aStream + nextPutAll: ' parameters: '; + print: self parameters ]. aStream nextPut: $) ] { #category : #evaluating } PMErrorAsParameterFunction >> value: aNumber [ "aNumber chooses the data partition. it can run from 1 to maxFunction." -^(function at: aNumber) value: varArray +^(function at: aNumber) value: varArray ] diff --git a/src/Math-FunctionFit/PMErrorMinimizer.class.st b/src/Math-FunctionFit/PMErrorMinimizer.class.st index 13b6c0328..9b60de6af 100644 --- a/src/Math-FunctionFit/PMErrorMinimizer.class.st +++ b/src/Math-FunctionFit/PMErrorMinimizer.class.st @@ -11,14 +11,14 @@ fit parameters. --> #(2.0 0.39999999999903596) Class { #name : #PMErrorMinimizer, #superclass : #PMFunctionFit, - #category : 'Math-FunctionFit' + #category : #'Math-FunctionFit' } { #category : #creation } -PMErrorMinimizer class >> function: anErrorOfParameterFunction [ +PMErrorMinimizer class >> function: anErrorOfParameterFunction [ |f d| f := PMErrorAsParameterFunction function: anErrorOfParameterFunction. -d :=( 1 to:( f maxFunction ))collect: [:i| i@0]. +d :=( 1 to:( f maxFunction ))collect: [:i| i@0]. ^self new initialize: d data: f ] @@ -28,7 +28,7 @@ PMErrorMinimizer class >> function: aBlock data: aCollection [ ] { #category : #accessing } -PMErrorMinimizer >> maxFunction [ +PMErrorMinimizer >> maxFunction [ "The number of data partitions used." ^dataHolder size ] diff --git a/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st b/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st index 81f654b4f..f318dcf20 100644 --- a/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st +++ b/src/Math-FunctionFit/PMErrorOfParameterFunction.class.st @@ -14,23 +14,23 @@ Class { 'qPosition', 'relative' ], - #category : 'Math-FunctionFit' + #category : #'Math-FunctionFit' } { #category : #'instance creation' } PMErrorOfParameterFunction class >> function: aBlock data: aCollectionOfPoints [ -^self new function: aBlock; data: aCollectionOfPoints; yourself +^self new function: aBlock; data: aCollectionOfPoints; yourself ] { #category : #accessing } PMErrorOfParameterFunction >> data [ -^data +^data ] { #category : #accessing } -PMErrorOfParameterFunction >> data: aCollectionOfPoints [ +PMErrorOfParameterFunction >> data: aCollectionOfPoints [ "a collection of points x@f(x)" -(aCollectionOfPoints isCollection and: [aCollectionOfPoints allSatisfy: [:aPoint| aPoint isPoint]]) ifFalse: +(aCollectionOfPoints isCollection and: [aCollectionOfPoints allSatisfy: [:aPoint| aPoint isPoint]]) ifFalse: [self error: 'data must be a Collection of Points']. aCollectionOfPoints ifEmpty: [CollectionIsEmpty signalWith: aCollectionOfPoints]. data := aCollectionOfPoints . @@ -45,7 +45,7 @@ PMErrorOfParameterFunction >> errorCollection: parameters [ |y y1| parameters withIndexDo: [ :p :i | varArray at: i + 1 put: p ]. ^data - collect: [ :point | + collect: [ :point | | err| varArray at: 1 put: point x. y := point y. @@ -55,26 +55,25 @@ PMErrorOfParameterFunction >> errorCollection: parameters [ ifTrue: [ err := ((y1 = 0)or:[y=0]) ifTrue: [ (y=y1) ifTrue: [0] ifFalse: [1]] - ifFalse: [ errorType = #squared + ifFalse: [ errorType = #squared ifTrue: [ err squared / y1 abs + (err squared /y abs) / 2] "this looks even more stupid than the rest of the 'relative ifTrue:' code, but it is necessary to do it this way because of the possible bias" - ifFalse: [(err / y)abs +(err /y1)abs /2 ] ] ] + ifFalse: [(err / y)abs +(err /y1)abs /2 ] ] ] ifFalse:[ errorType = #squared ifTrue: [ err squared ] - ifFalse: [ err abs ] ]]. - + ifFalse: [ err abs ] ]] ] { #category : #accessing } PMErrorOfParameterFunction >> errorType [ -^errorType +^errorType ] { #category : #accessing } PMErrorOfParameterFunction >> errorType: aSymbol [ "valid errorTypes are: #squared, #abs, #insensitive, #quartile, #median. Default is #squared" -(aSymbol isSymbol and:[#(#squared #abs #insensitive #quartile #median) includes: aSymbol]) ifFalse: +(aSymbol isSymbol and:[#(#squared #abs #insensitive #quartile #median) includes: aSymbol]) ifFalse: [^MessageNotUnderstood signal: 'errorType must be one of the following Symbols: #squared, #abs, #insensitive, #quartile, #median']. -(#(#quartile #insensitive) includes: aSymbol)ifFalse: [self quartile: 1/2]. "reset quartile to default, if it is not used" +(#(#quartile #insensitive) includes: aSymbol)ifFalse: [self quartile: 1/2]. "reset quartile to default, if it is not used" aSymbol =#median ifTrue: [^errorType :=#quartile] . ^errorType :=aSymbol ] @@ -85,39 +84,39 @@ PMErrorOfParameterFunction >> function [ ] { #category : #accessing } -PMErrorOfParameterFunction >> function: aBlock [ +PMErrorOfParameterFunction >> function: aBlock [ function :=aBlock . -varArray :=Array new: aBlock numArgs. +varArray :=Array new: aBlock numArgs ] { #category : #initialization } -PMErrorOfParameterFunction >> initialize [ +PMErrorOfParameterFunction >> initialize [ super initialize . relative :=false. errorType :=#squared. -quartile:= 1/2. +quartile:= 1/2 ] { #category : #accessing } PMErrorOfParameterFunction >> parameterNames [ -^(function argumentNames collect:[:s| s asString ])allButFirst +^(function argumentNames collect:[:s| s asString ])allButFirst ] { #category : #accessing } -PMErrorOfParameterFunction >> parameterSize [ +PMErrorOfParameterFunction >> parameterSize [ ^varArray size -1 ] { #category : #printing } PMErrorOfParameterFunction >> printOn: aStream [ - super printOn: aStream. - aStream + super printOn: aStream. + aStream nextPutAll: '( function: '; print: function; nextPutAll: ' relativeError: '; print: relative; nextPutAll: ' errorType: '; print: errorType. (#(#quartile #insensitive) includes: errorType)ifTrue:[ aStream nextPutAll: ' withQuartile: '; print: quartile]. - aStream nextPut: $). + aStream nextPut: $). ] { #category : #accessing } @@ -130,7 +129,7 @@ PMErrorOfParameterFunction >> quartile: aFloat [ "quartile: is used by errortypes #quartile and #insensitive." aFloat >1 | (aFloat <0) ifTrue:[^DomainError signal:'quartile must be between 0 and 1']. data ifNotNil: [qPosition :=(data size -1.00001 * aFloat )rounded+1]. "-1.00001 because x.5 is rounded up to x+1 and pharos median rounds the position down" -^quartile := aFloat . +^quartile := aFloat ] { #category : #evaluating } @@ -141,13 +140,12 @@ e:=self value: parameters . (#(#insensitive #quartile) includes: errorType) ifFalse: [e :=e / data size] . errorType = #squared ifTrue: [e := e sqrt] . "if relativeError=true this is not really correct at the moment because of the way value: is calculated, but value: cant be changed! if anything, the calc here could be changed." ^e - ] { #category : #accessing } PMErrorOfParameterFunction >> relativeError: aBoolean [ " default is false" -^relative :=aBoolean +^relative :=aBoolean ] { #category : #evaluating } @@ -158,9 +156,9 @@ PMErrorOfParameterFunction >> value: parameters [ e := self errorCollection: parameters . errorType = #quartile ifTrue: [ ^ e asSortedCollection at: qPosition ] - ifFalse: [ + ifFalse: [ errorType = #insensitive - ifTrue: [ + ifTrue: [ e := e asSortedCollection copyFrom: 1 to: (qPosition + 1 min: e size). e := e asOrderedCollection reverse withIndexCollect: [ :v :i | v / (2 raisedToInteger: i) ] ] ]. ^ e sum diff --git a/src/Math-FunctionFit/PMFunctionFit.class.st b/src/Math-FunctionFit/PMFunctionFit.class.st index 6025f74ef..a271ef4ac 100644 --- a/src/Math-FunctionFit/PMFunctionFit.class.st +++ b/src/Math-FunctionFit/PMFunctionFit.class.st @@ -13,17 +13,17 @@ Class { } { #category : #creation } -PMFunctionFit class >> function: aBlock data: aDataHolder [ +PMFunctionFit class >> function: aBlock data: aDataHolder [ ^super points: aDataHolder function: (PMSimpleParameterFunction function: aBlock) ] { #category : #creation } -PMFunctionFit class >> histogram: aHistogram distributionClass: aProbabilityDensityFunctionClass [ +PMFunctionFit class >> histogram: aHistogram distributionClass: aProbabilityDensityFunctionClass [ ^self shouldNotImplement ] { #category : #creation } -PMFunctionFit class >> points: aDataHolder function: aBlock [ +PMFunctionFit class >> points: aDataHolder function: aBlock [ ^self shouldNotImplement ] @@ -38,7 +38,7 @@ PMFunctionFit >> accumulate: aWeightedPoint [ 1 to: g size do: [ :k | ( equations at: k) accumulate: g * ( ( g at: k) * aWeightedPoint weight). - ]. + ] ] { #category : #operation } @@ -52,12 +52,12 @@ PMFunctionFit >> computeChiSquare [ chiSquare := 0. degreeOfFreedom := self numberOfFreeParameters negated. dataHolder pointsAndErrorsDo: - [ :each | |y| + [ :each | |y| y :=result value: each xValue . (y closeTo: 0) ifFalse: [chiSquare := (each yValue - y) squared / y abs +chiSquare . degreeOfFreedom := degreeOfFreedom + 1]. - ]. + ] ] { #category : #initialization } @@ -72,15 +72,15 @@ PMFunctionFit >> initialize: aDataHolder data: aParametricFunction [ ] { #category : #information } -PMFunctionFit >> parameters [ -^result parameters +PMFunctionFit >> parameters [ +^result parameters ] { #category : #initialization } PMFunctionFit >> parameters: indexableCollection [ - indexableCollection do: [ :e | - (e closeTo: 0.0) ifTrue: [ + indexableCollection do: [ :e | + (e closeTo: 0.0) ifTrue: [ self error: 'parameters shouldnt be set to practically zero' ] ]. result parameters: indexableCollection. self finalizeIterations @@ -88,8 +88,8 @@ PMFunctionFit >> parameters: indexableCollection [ { #category : #printing } PMFunctionFit >> printOn: aStream [ - super printOn: aStream. + super printOn: aStream. aStream nextPutAll: ' for '. result printOn: aStream . - aStream nextPutAll: ' with data of size: '; print: dataHolder size. + aStream nextPutAll: ' with data of size: '; print: dataHolder size ] diff --git a/src/Math-FunctionFit/PMGAAccuracy.class.st b/src/Math-FunctionFit/PMGAAccuracy.class.st index da27f5bc1..d19eed1bb 100644 --- a/src/Math-FunctionFit/PMGAAccuracy.class.st +++ b/src/Math-FunctionFit/PMGAAccuracy.class.st @@ -7,19 +7,19 @@ Class { #instVars : [ 'fast' ], - #category : 'Math-FunctionFit' + #category : #'Math-FunctionFit' } { #category : #tests } PMGAAccuracy >> checkDamavandi [ | g origin range optimizer | - g := [:x| |x1 x2| - x1:=x at:1. + g := [:x| |x1 x2| + x1:=x at:1. x2:=x at:2. ( 1 - ( ( ((x1 - 2)* Float pi)sin * ((x2 - 2) * Float pi)sin /(Float pi squared *(x1 - 2)*(x2 - 2)) )abs raisedToInteger: 5)) *(2 + (x1 - 7) squared + (2 * (x2 -7)squared)) ]. origin := #(0 0 ). range :=#( 14 14 ). - optimizer:= PMAnotherGeneticOptimizer function: g minimumValues: origin maximumValues: range. + optimizer:= PMAnotherGeneticOptimizer function: g minimumValues: origin maximumValues: range. optimizer chromosomeManager populationSize: 570. self setManager: optimizer chromosomeManager with: self parameter. ^g value: optimizer evaluate @@ -29,18 +29,18 @@ PMGAAccuracy >> checkDamavandi [ PMGAAccuracy >> checkDeVilliersGlasser2 [ | ti yi g origin range optimizer | ti := [ :x | (x - 1) / 10 ]. - yi := [ :i | + yi := [ :i | 53.81 * (1.27 raisedTo: (ti value: i)) * (3.012 * (ti value: i) + (2.13 * (ti value: i)) sin) tanh * (0.507 exp * (ti value: i)) cos ]. - g := [ :x | + g := [ :x | | xc | xc := x - collect: [ :i | + collect: [ :i | i < 0 ifTrue: [ i negated ] ifFalse: [ i ] ]. ((1 to: 24) - collect: [ :i | + collect: [ :i | (((xc at: 2) raisedTo: (ti value: i)) * (xc at: 1) * ((xc at: 3) * (ti value: i) + ((xc at: 4) * (ti value: i)) sin) tanh * ((xc at: 5) exp * (ti value: i)) cos - (yi value: i)) squared ]) sum ]. @@ -57,7 +57,7 @@ PMGAAccuracy >> checkDeVilliersGlasser2 [ { #category : #tests } PMGAAccuracy >> checkF1 [ | f origin optimizer | - f := [ :x | + f := [ :x | | v | v := x asPMVector. v * v ]. @@ -65,7 +65,7 @@ PMGAAccuracy >> checkF1 [ optimizer := PMAnotherGeneticOptimizer function: f minimumValues: origin maximumValues: origin negated. self setManager: optimizer chromosomeManager with: self parameter. fast - ifTrue: [ + ifTrue: [ optimizer chromosomeManager populationSize: 50. optimizer maximumIterations: 50 ]. ^ f value: optimizer evaluate @@ -76,12 +76,12 @@ PMGAAccuracy >> checkF2 [ | g origin optimizer r | g := [ :x | (x overlappingPairsCollect: [ :f :s | (s - f squared) squared * 100 + (1 - f) squared ]) sum ]. r := #(2 3 4) - collect: [ :i | + collect: [ :i | origin := Array new: i withAll: -2.048. optimizer := PMAnotherGeneticOptimizer function: g minimumValues: origin maximumValues: origin negated. self setManager: optimizer chromosomeManager with: self parameter. fast - ifTrue: [ + ifTrue: [ optimizer chromosomeManager populationSize: 60. optimizer maximumIterations: 70 ]. g value: optimizer evaluate ]. @@ -96,10 +96,10 @@ PMGAAccuracy >> checkF3 [ optimizer := PMAnotherGeneticOptimizer function: g minimumValues: origin maximumValues: origin negated. self setManager: optimizer chromosomeManager with: self parameter. fast - ifTrue: [ + ifTrue: [ optimizer chromosomeManager populationSize: 20. optimizer maximumIterations: 70 ] - ifFalse: [ + ifFalse: [ optimizer chromosomeManager populationSize: 30. optimizer maximumIterations: 90 ]. ^ g value: optimizer evaluate @@ -108,14 +108,14 @@ PMGAAccuracy >> checkF3 [ { #category : #tests } PMGAAccuracy >> checkF5 [ | g origin optimizer | - g := [ :x | + g := [ :x | | x1 x2 | x1 := x at: 1. x2 := x at: 2. 1 / (((-2 to: 2) - collect: [ :i | + collect: [ :i | ((-2 to: 2) collect: [ :j | 1 / ((i + 2) * 5 + j + 3 + (x1 - (16 * j) raisedToInteger: 6) + (x2 - (16 * i) raisedToInteger: 6)) ]) sum ]) sum + 0.002) ]. @@ -148,10 +148,10 @@ PMGAAccuracy >> fast [ { #category : #accessing } PMGAAccuracy >> fast: aBoolean [ "default is false" - fast := aBoolean + fast := aBoolean ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMGAAccuracy >> initialize [ super initialize. fast :=false. @@ -161,12 +161,12 @@ PMGAAccuracy >> initialize [ { #category : #initialization } PMGAAccuracy >> initializeDamavandi [ - self result: 0. + self result: 0 ] { #category : #initialization } PMGAAccuracy >> initializeDeVilliersGlasser2 [ - self result: 0. + self result: 0 ] { #category : #initialization } @@ -177,7 +177,7 @@ PMGAAccuracy >> initializeF1 [ { #category : #initialization } PMGAAccuracy >> initializeF2 [ - self result: #(0 0 0). + self result: #(0 0 0) ] { #category : #initialization } @@ -200,19 +200,19 @@ PMGAAccuracy >> initializeGriewank [ PMGAAccuracy >> runFast [ "fast is an euphemism here, but at least its fast to type" fast := true. - ^ self run: #('F1' 'F2' 'F3' 'F5' 'Griewank'). + ^ self run: #('F1' 'F2' 'F3' 'F5' 'Griewank') ] { #category : #running } PMGAAccuracy >> setManager:aManager with: rates [ "set everything to zero first, so that you dont get warnings" - aManager - rateOfMutation: 0; - rateOfCrossover: 0; + aManager + rateOfMutation: 0; + rateOfCrossover: 0; rateOfLC: 0; rateOfEir: 0; - rateOfMutation: rates first; - rateOfCrossover: (rates at:2); + rateOfMutation: rates first; + rateOfCrossover: (rates at:2); rateOfLC: (rates at:3); - rateOfEir: (rates at:4). + rateOfEir: (rates at:4). ] diff --git a/src/Math-FunctionFit/PMGeneralFunctionFit.class.st b/src/Math-FunctionFit/PMGeneralFunctionFit.class.st index 15791cd8a..586011d56 100644 --- a/src/Math-FunctionFit/PMGeneralFunctionFit.class.st +++ b/src/Math-FunctionFit/PMGeneralFunctionFit.class.st @@ -23,25 +23,25 @@ Class { } { #category : #creation } -PMGeneralFunctionFit class >> function: aBlock data: aCollectionOfPoints minimumValues: anArray maximumValues: anotherArray [ -(aBlock isBlock and:[aBlock numArgs > 1]) ifFalse: +PMGeneralFunctionFit class >> function: aBlock data: aCollectionOfPoints minimumValues: anArray maximumValues: anotherArray [ +(aBlock isBlock and:[aBlock numArgs > 1]) ifFalse: [^self error: 'aBlock must be a Block with one independent variable and at least one parameter' ]. -^self new - function: aBlock; - data: (aCollectionOfPoints as: PMDataHolder); +^self new + function: aBlock; + data: (aCollectionOfPoints as: PMDataHolder); minValues: anArray maxValues: anotherArray; - yourself + yourself ] { #category : #util } PMGeneralFunctionFit class >> range: anArray size: anInteger type: string [ -^anArray isNumber - ifTrue: [Array new: anInteger withAll: anArray ] - ifFalse: [anArray isCollection - ifTrue: [anArray size=anInteger +^anArray isNumber + ifTrue: [Array new: anInteger withAll: anArray ] + ifFalse: [anArray isCollection + ifTrue: [anArray size=anInteger ifTrue: [anArray] - ifFalse: [self error: 'minimum or maximum values dont have correct sizes'] ] - ifFalse: [self error: (string, ' values is no collection or number')]]. + ifFalse: [self error: 'minimum or maximum values dont have correct sizes'] ] + ifFalse: [self error: (string, ' values is no collection or number')]] ] { #category : #accessing } @@ -50,13 +50,12 @@ PMGeneralFunctionFit >> data: aCollectionOfPoints [ self resetResult . data :=aCollectionOfPoints. dataTruncated:=false. -^errorFunction data: aCollectionOfPoints . +^errorFunction data: aCollectionOfPoints ] { #category : #accessing } PMGeneralFunctionFit >> dataTruncated [ ^dataTruncated - ] { #category : #accessing } @@ -64,14 +63,12 @@ PMGeneralFunctionFit >> error [ "returns the sqrt of the mean of the sum of squared errors, or the mean abs error, or the quartile error, or the insensitive error" result ifNil: [^nil]. ^self error: result - ] { #category : #accessing } PMGeneralFunctionFit >> error: parameters [ "returns the error for any parameter array; for example if you want to compare the error of the result with the error of the 'real' parameters" -^errorFunction realValue: parameters . - +^errorFunction realValue: parameters ] { #category : #accessing } @@ -90,32 +87,32 @@ PMGeneralFunctionFit >> errorType [ PMGeneralFunctionFit >> errorType: aSymbol [ "defines what kind of fitting should be used. valid errorTypes are: #squared, #abs, #insensitive, #quartile, #median. Default is #squared" self resetResult. -^errorFunction errorType: aSymbol +^errorFunction errorType: aSymbol ] { #category : #operation } -PMGeneralFunctionFit >> evaluate [ +PMGeneralFunctionFit >> evaluate [ |ff| ff :=PMErrorMinimizer function: errorFunction. -firstResult :=[ff evaluate .ff parameters] +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 +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']. +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 +^result ] { #category : #operation } @@ -148,8 +145,7 @@ n:=0. ifTrue: [v ifTrue: [self inform: 'found quartile: ' , max asString ].true] ifFalse:[false] . ] whileTrue. verbose :=v. -^self evaluate - +^self evaluate ] { #category : #accessing } @@ -164,7 +160,7 @@ f :=errorFunction function . PMGeneralFunctionFit >> function: aBlock [ "sets the function to be fitted. the first value has to be the independent variable, further values are the parameters to be fitted. only one independent variable is allowed (if you have several independent vars or eg a function of a vector, that returns another vector, have a look at the 'spiral' example)." self resetResult. -errorFunction function: aBlock . +errorFunction function: aBlock ] { #category : #initialization } @@ -177,35 +173,35 @@ go :=PMAnotherGeneticOptimizer minimizingFunction: errorFunction . go chromosomeManager: manager. go maximumIterations: 170. self errorType: #squared. -verbose:=false. -dataTruncated :=false. +verbose:=false. +dataTruncated :=false ] { #category : #accessing } -PMGeneralFunctionFit >> manager [ +PMGeneralFunctionFit >> manager [ "if you want to change parameters of AnotherChromosomeManager, that are not directly available in GeneralFunctionFit" -^manager +^manager ] { #category : #accessing } PMGeneralFunctionFit >> maximumIterations: anInteger [ "default is 170." go maximumIterations: anInteger. -^anInteger +^anInteger ] { #category : #accessing } -PMGeneralFunctionFit >> minValues: anArray maxValues: anotherArray [ +PMGeneralFunctionFit >> minValues: anArray maxValues: anotherArray [ "instead of an array one can also use a number, an array will then be filled with this number. eg one can use 0 instead of the tiresome #(0 0 0 0). minValues and maxValues need not be absolutely correct. also results outside of this range, but nearby, will often be found." |array1 array2 aSize| aSize := errorFunction function numArgs-1. -array1 := self class range: anArray size: aSize type: 'minimum'. -array2 :=self class range: anotherArray size: aSize type: 'maximum'. -(array2 - array1 allSatisfy: [:each| each >0]) ifFalse: +array1 := self class range: anArray size: aSize type: 'minimum'. +array2 :=self class range: anotherArray size: aSize type: 'maximum'. +(array2 - array1 allSatisfy: [:each| each >0]) ifFalse: [^DomainError signal: 'maximum values should be greater than minimum values']. self resetResult. manager origin: array1. -manager range: (array2 - array1). +manager range: (array2 - array1) ] { #category : #accessing } @@ -219,13 +215,13 @@ PMGeneralFunctionFit >> populationSize: anInteger [ " if you have a lot of parameters (essentially beginning with 3 parameters), you may want to enlarge the populationsize. default is only 50. eg for 3 parameters, you might want set this to 300" self resetResult. manager populationSize: anInteger . -^anInteger +^anInteger ] { #category : #accessing } -PMGeneralFunctionFit >> precision [ +PMGeneralFunctionFit >> precision [ "not really useful to look at, you might better look at #error" -^go precision +^go precision ] { #category : #printing } @@ -237,47 +233,46 @@ PMGeneralFunctionFit >> printOn: aStream [ print: go; nextPutAll: ' with data of size: '; print: data size . - dataTruncated ifTrue: + dataTruncated ifTrue: [aStream nextPutAll: ' truncated to: '; print: self optimizer functionBlock data size] . - aStream nextPut: $). + aStream nextPut: $) ] { #category : #accessing } PMGeneralFunctionFit >> quartile [ -^errorFunction quartile. +^errorFunction quartile ] { #category : #accessing } PMGeneralFunctionFit >> quartile: aFloat [ "quartile: is used by errortypes #quartile and #insensitive. if you set quartile to 1, it does not make much sense to use #insensitive, since #insensitive is much slower than #quartile and calculating the tube radius is not quite correct for #insensitive in this special case (it will leave out one datapoint )." self resetResult. -^errorFunction quartile: aFloat. +^errorFunction quartile: aFloat ] { #category : #accessing } PMGeneralFunctionFit >> relativeError: aBoolean [ "by default false" self resetResult . -^errorFunction relativeError: aBoolean . +^errorFunction relativeError: aBoolean ] { #category : #operation } PMGeneralFunctionFit >> resetBestPoints [ "for repeated evaluating with different starting populations" -self resetResult . - +self resetResult ] { #category : #operation } PMGeneralFunctionFit >> resetData [ -self data: data. +self data: data ] { #category : #private } PMGeneralFunctionFit >> resetResult [ result :=nil. firstResult :=nil. -go resetBestPoints . +go resetBestPoints ] { #category : #accessing } @@ -290,7 +285,7 @@ result ifNil: [self evaluate ]. { #category : #accessing } PMGeneralFunctionFit >> secondaryResult [ "not really necessary" -^firstResult +^firstResult ] { #category : #operation } @@ -303,12 +298,11 @@ ei:=(ei sort:[:a :b|a first> verbose: aBoolean [ " by default false. if set it to true, you will get some tiresome messages" -verbose :=aBoolean +verbose :=aBoolean ] diff --git a/src/Math-FunctionFit/PMSimpleParameterFunction.class.st b/src/Math-FunctionFit/PMSimpleParameterFunction.class.st index 643228f58..297334a83 100644 --- a/src/Math-FunctionFit/PMSimpleParameterFunction.class.st +++ b/src/Math-FunctionFit/PMSimpleParameterFunction.class.st @@ -9,7 +9,7 @@ Class { 'function', 'varArray' ], - #category : 'Math-FunctionFit' + #category : #'Math-FunctionFit' } { #category : #'instance creation' } @@ -19,13 +19,12 @@ PMSimpleParameterFunction class >> function: aBlock [ { #category : #'instance creation' } PMSimpleParameterFunction class >> function: aBlock parameters: anArray [ -^self new function: aBlock; parameters: anArray; yourself +^self new function: aBlock; parameters: anArray; yourself ] { #category : #accessing } PMSimpleParameterFunction >> changeParametersBy: aVector [ 2 to: (usedVars+1) do:[:n| varArray at: n put: ((varArray at: n)+ ( aVector at: n-1)).] - ] { #category : #initialization } @@ -34,46 +33,43 @@ PMSimpleParameterFunction >> function: aBlock [ function:=aBlock. usedVars :=aBlock numArgs . self initializeVarArray: 2. -usedVars :=usedVars -1. - +usedVars :=usedVars -1 ] { #category : #initialization } PMSimpleParameterFunction >> initializeVarArray: aStart [ varArray :=Array new: usedVars withAll: 0.937. -(1 + aStart) to: (usedVars min: (aStart +4)) do:[:i| varArray at: i put: ( #(0.929 0.919 0.911 0.907) at: (i - aStart ) )]. +(1 + aStart) to: (usedVars min: (aStart +4)) do:[:i| varArray at: i put: ( #(0.929 0.919 0.911 0.907) at: (i - aStart ) )] ] { #category : #accessing } PMSimpleParameterFunction >> parameterNames [ -^(function argumentNames collect:[:s| s asString ])allButFirst +^(function argumentNames collect:[:s| s asString ])allButFirst ] { #category : #accessing } PMSimpleParameterFunction >> parameterSize [ -^usedVars +^usedVars ] { #category : #accessing } PMSimpleParameterFunction >> parameters [ ^varArray allButFirst - ] { #category : #accessing } PMSimpleParameterFunction >> parameters: indexableCollection [ 1 to: usedVars do:[:n| varArray at: n+1 put: ( indexableCollection at: n)]. -^indexableCollection - +^indexableCollection ] { #category : #printing } PMSimpleParameterFunction >> printOn: aStream [ - super printOn: aStream. + super printOn: aStream. aStream nextPutAll: '( '; print: function . - varArray ifNotNil:[ self parameterNames with: self parameters do: + varArray ifNotNil:[ self parameterNames with: self parameters do: [:n :p|aStream nextPutAll: ' '; nextPutAll: n; nextPutAll:': ';print: p. ]] . - aStream nextPut: $). + aStream nextPut: $). ] { #category : #evaluating } diff --git a/src/Math-Helpers/PMFloatingPointMachine.class.st b/src/Math-Helpers/PMFloatingPointMachine.class.st index 5f0f53ab0..e1bd2453f 100644 --- a/src/Math-Helpers/PMFloatingPointMachine.class.st +++ b/src/Math-Helpers/PMFloatingPointMachine.class.st @@ -62,7 +62,7 @@ PMFloatingPointMachine >> computeLargestNumber [ { #category : #information } PMFloatingPointMachine >> computeMachinePrecision [ - + | one zero inverseRadix tmp | one := 1.0. zero := 0.0. @@ -75,7 +75,7 @@ PMFloatingPointMachine >> computeMachinePrecision [ { #category : #information } PMFloatingPointMachine >> computeNegativeMachinePrecision [ - + | one zero floatingRadix inverseRadix tmp | one := 1.0. zero := 0.0. @@ -89,7 +89,7 @@ PMFloatingPointMachine >> computeNegativeMachinePrecision [ { #category : #information } PMFloatingPointMachine >> computeRadix [ - + | one zero a b tmp1 tmp2| one := 1.0. zero := 0.0. @@ -107,7 +107,7 @@ PMFloatingPointMachine >> computeRadix [ { #category : #information } PMFloatingPointMachine >> computeSmallestNumber [ - + | one floatingRadix inverseRadix fullMantissaNumber | one := 1 asFloat. floatingRadix := self radix asFloat. @@ -125,49 +125,43 @@ PMFloatingPointMachine >> computeSmallestNumber [ { #category : #information } PMFloatingPointMachine >> defaultNumericalPrecision [ - defaultNumericalPrecision isNil - ifTrue: [ defaultNumericalPrecision := self machinePrecision sqrt]. - ^defaultNumericalPrecision + defaultNumericalPrecision ifNil: [ defaultNumericalPrecision := self machinePrecision sqrt ]. + ^ defaultNumericalPrecision ] { #category : #information } PMFloatingPointMachine >> largestExponentArgument [ - - largestExponentArgument isNil - ifTrue: [ largestExponentArgument := self largestNumber ln]. - ^largestExponentArgument + + largestExponentArgument ifNil: [ largestExponentArgument := self largestNumber ln ]. + ^ largestExponentArgument ] { #category : #information } PMFloatingPointMachine >> largestNumber [ - - largestNumber isNil - ifTrue: [ self computeLargestNumber]. - ^largestNumber + + largestNumber ifNil: [ self computeLargestNumber ]. + ^ largestNumber ] { #category : #information } PMFloatingPointMachine >> machinePrecision [ - - machinePrecision isNil - ifTrue: [ self computeMachinePrecision]. - ^machinePrecision + + machinePrecision ifNil: [ self computeMachinePrecision ]. + ^ machinePrecision ] { #category : #information } PMFloatingPointMachine >> negativeMachinePrecision [ - - negativeMachinePrecision isNil - ifTrue: [ self computeNegativeMachinePrecision]. - ^negativeMachinePrecision + + negativeMachinePrecision ifNil: [ self computeNegativeMachinePrecision ]. + ^ negativeMachinePrecision ] { #category : #information } PMFloatingPointMachine >> radix [ - - radix isNil - ifTrue: [ self computeRadix]. - ^radix + + radix ifNil: [ self computeRadix ]. + ^ radix ] { #category : #display } @@ -191,16 +185,14 @@ PMFloatingPointMachine >> showParameters [ { #category : #information } PMFloatingPointMachine >> smallNumber [ - - smallNumber isNil - ifTrue: [ smallNumber := self smallestNumber sqrt]. - ^smallNumber + + smallNumber ifNil: [ smallNumber := self smallestNumber sqrt ]. + ^ smallNumber ] { #category : #information } PMFloatingPointMachine >> smallestNumber [ - - smallestNumber isNil - ifTrue: [ self computeSmallestNumber]. - ^smallestNumber + + smallestNumber ifNil: [ self computeSmallestNumber ]. + ^ smallestNumber ] diff --git a/src/Math-Helpers/PMWeightedPoint.class.st b/src/Math-Helpers/PMWeightedPoint.class.st index a6826b440..87b519df1 100644 --- a/src/Math-Helpers/PMWeightedPoint.class.st +++ b/src/Math-Helpers/PMWeightedPoint.class.st @@ -15,13 +15,13 @@ Class { { #category : #creation } PMWeightedPoint class >> point: aPoint [ - + ^ self new initialize: aPoint weight: 1 ] { #category : #creation } PMWeightedPoint class >> point: aNumber count: anInteger [ - + ^ self point: aNumber @ anInteger weight: @@ -32,13 +32,13 @@ PMWeightedPoint class >> point: aNumber count: anInteger [ { #category : #creation } PMWeightedPoint class >> point: aPoint error: aNumber [ - + ^ self new initialize: aPoint error: aNumber ] { #category : #creation } PMWeightedPoint class >> point: aPoint weight: aNumber [ - + ^ self basicNew initialize: aPoint weight: aNumber ] @@ -57,8 +57,7 @@ PMWeightedPoint >> chi2Contribution: aFunction [ { #category : #accessing } PMWeightedPoint >> error [ - error isNil - ifTrue: [ error := 1 / weight sqrt ]. + error ifNil: [ error := 1 / weight sqrt ]. ^ error ] diff --git a/src/Math-Helpers/SequenceableCollection.extension.st b/src/Math-Helpers/SequenceableCollection.extension.st index a864f2c8a..f29e5490b 100644 --- a/src/Math-Helpers/SequenceableCollection.extension.st +++ b/src/Math-Helpers/SequenceableCollection.extension.st @@ -11,7 +11,7 @@ SequenceableCollection >> closeTo: aSequenceableCollection [ { #category : #'*Math-Helpers' } SequenceableCollection >> equalsTo: aSequenceableCollection [ - + self deprecated: 'Use closeTo: instead' transformWith: '`@rec equalsTo: `@arg' -> '`@rec closeTo: `@arg'. diff --git a/src/Math-KDTree/PMIndexedKDTree.class.st b/src/Math-KDTree/PMIndexedKDTree.class.st index a1c5da9e6..7fe69aa0b 100644 --- a/src/Math-KDTree/PMIndexedKDTree.class.st +++ b/src/Math-KDTree/PMIndexedKDTree.class.st @@ -13,19 +13,19 @@ Class { { #category : #'instance creation' } PMIndexedKDTree class >> withAll: aCollectionOfCollections [ "make a KDTree from a SequenceableCollection of SequenceableCollections ,which is an ordered Collection of points in a n-dimensional space. the nearest neighbour search then returns the indices of the neighbours" -^super withAll: (aCollectionOfCollections withIndexCollect: [:v :i| Array with: i with: v ]). +^super withAll: (aCollectionOfCollections withIndexCollect: [:v :i| Array with: i with: v ]). ] { #category : #private } PMIndexedKDTree >> add: aDistance to: aNNStore [ -aNNStore add: (Array with: aDistance with: (Array with: index with: value)) . +aNNStore add: (Array with: aDistance with: (Array with: index with: value)) ] { #category : #private } -PMIndexedKDTree >> adjustValue [ +PMIndexedKDTree >> adjustValue [ -index :=value first. -value :=value at: 2. +index :=value first. +value :=value at: 2 ] { #category : #evaluating } @@ -34,10 +34,10 @@ PMIndexedKDTree >> nnSearch: aSequenceableCollection i: anInt [ |n| n :=PMNNStore new: anInt . self nnSearch: aSequenceableCollection asFloatArray near: n . -^anInt =1 ifTrue: [n data first first ] ifFalse: [n completeData collect: [:i | Array with: (i at:2) first with: i first] ] +^anInt =1 ifTrue: [n data first first ] ifFalse: [n completeData collect: [:i | Array with: (i at:2) first with: i first] ] ] { #category : #private } PMIndexedKDTree >> sort: aSequenceableCollection [ -^ aSequenceableCollection sort: [:a :b| ((a at: 2) at: dim) < ((b at: 2) at: dim)] +^ aSequenceableCollection sort: [:a :b| ((a at: 2) at: dim) < ((b at: 2) at: dim)] ] diff --git a/src/Math-KDTree/PMKDTree.class.st b/src/Math-KDTree/PMKDTree.class.st index 072f9d5dc..c35adb6b2 100644 --- a/src/Math-KDTree/PMKDTree.class.st +++ b/src/Math-KDTree/PMKDTree.class.st @@ -17,20 +17,20 @@ Class { PMKDTree class >> withAll: aCollectionOfCollections [ "make a KDTree from a Collection of SequenceableCollections ,which is a Collection of points in a n-dimensional space" (aCollectionOfCollections allSatisfy: [:c|c isCollection ])ifFalse: "isSequenceable does not work here in a simple way" - [self error: 'KDTree withAll: expects a collection of collections']. + [self error: 'KDTree withAll: expects a collection of collections']. aCollectionOfCollections first ifEmpty: [self error: 'KDTree withAll: error' ]. -^self new addData: aCollectionOfCollections asOrderedCollection at:1. +^self new addData: aCollectionOfCollections asOrderedCollection at:1. ] { #category : #private } PMKDTree >> add: aDistance to: aNNStore [ -aNNStore add: (Array with: aDistance with: value) . +aNNStore add: (Array with: aDistance with: value) ] { #category : #initialize } PMKDTree >> addData: aSequenceableCollection at: dimension [ |sorted cut nextDimension| -dim :=dimension . +dim :=dimension . aSequenceableCollection size =1 ifTrue: [value :=aSequenceableCollection first . self adjustValue . ^self ]. sorted :=self sort: aSequenceableCollection . cut :=sorted size + 1// 2. @@ -38,13 +38,12 @@ value :=sorted at: cut . self adjustValue . nextDimension :=dimension \\(value size) +1. cut >1 ifTrue: [left :=self class new addData: (sorted copyFrom: 1 to: cut -1 ) at: nextDimension]. -right :=self class new addData: (sorted copyFrom: cut +1 to: sorted size) at: nextDimension. +right :=self class new addData: (sorted copyFrom: cut +1 to: sorted size) at: nextDimension ] { #category : #private } PMKDTree >> adjustValue [ "necessary for IndexedKDTree " - ] { #category : #accessing } @@ -64,7 +63,7 @@ PMKDTree >> nnSearch: aSequenceableCollection i: anInt [ n :=PMNNStore new: anInt . self nnSearch: aSequenceableCollection asFloatArray near: n . n :=n data . -^anInt =1 ifTrue: [n first ] ifFalse: [n] +^anInt =1 ifTrue: [n first ] ifFalse: [n] ] { #category : #private } @@ -90,12 +89,12 @@ PMKDTree >> printOn: aStream [ print: value ; nextPutAll: ' left: '; print: left ; - nextPutAll: ' right: '; + nextPutAll: ' right: '; print: right ; - nextPut: $) . + nextPut: $) ] { #category : #private } PMKDTree >> sort: aSequenceableCollection [ -^ aSequenceableCollection sort: [:a :b| (a at: dim) < (b at: dim)] +^ aSequenceableCollection sort: [:a :b| (a at: dim) < (b at: dim)] ] diff --git a/src/Math-KDTree/PMNNStore.class.st b/src/Math-KDTree/PMNNStore.class.st index 22da54fbe..f656e920c 100644 --- a/src/Math-KDTree/PMNNStore.class.st +++ b/src/Math-KDTree/PMNNStore.class.st @@ -16,41 +16,40 @@ Class { { #category : #'instance creation' } PMNNStore class >> new: anInt [ -^((super new: anInt) atAllPut: (Array with: Float infinity with: nil))initialize +^((super new: anInt) atAllPut: (Array with: Float infinity with: nil))initialize ] { #category : #'instance creation' } PMNNStore class >> newFrom: aCollectionWithSortingIndex [ "example: ( NNStore newFrom:#(#(3 1.0) #(0 '2')) ) data. #('2' 1.0)" -^((super newFrom: aCollectionWithSortingIndex )lastUsedIndex: aCollectionWithSortingIndex size )sort +^((super newFrom: aCollectionWithSortingIndex )lastUsedIndex: aCollectionWithSortingIndex size )sort ] { #category : #'instance creation' } PMNNStore class >> withAll: aCollection [ -"this is the peferable form of instance creation for subclasses since freeIndex is correctly initialized this way. then 'sortFor:' must be overwritten and called at least once (!); an example is StupidNN. the other possibility is to use 'new:' and to fill NNStore subclass with 'add:' . the advantage is, that NNStore has not to be filled completely this way and the sorting logic can be applied outside of the subclass without sortFor: (see also comment on add:). +"this is the peferable form of instance creation for subclasses since freeIndex is correctly initialized this way. then 'sortFor:' must be overwritten and called at least once (!); an example is StupidNN. the other possibility is to use 'new:' and to fill NNStore subclass with 'add:' . the advantage is, that NNStore has not to be filled completely this way and the sorting logic can be applied outside of the subclass without sortFor: (see also comment on add:). you cant enter the sorting index with the method withAll: . if you want to do that, use 'newFrom:' instead" -^(super withAll: (aCollection collect: [:coll| Array with: nil with: coll]))lastUsedIndex: aCollection size +^(super withAll: (aCollection collect: [:coll| Array with: nil with: coll]))lastUsedIndex: aCollection size ] { #category : #comparing } PMNNStore >> = aNNStore [ -^(self == aNNStore) or: +^(self == aNNStore) or: [ (self species =aNNStore species ) and: [(maxDistance =aNNStore maxDistance)and: - [(self size=aNNStore size) and: + [(self size=aNNStore size) and: [self completeData =aNNStore completeData] ] ] ] - ] { #category : #adding } PMNNStore >> add: distAndNeighbour [ "distAndNeighbour is a SequenceableCollection of the sorting index and the data value. dist, the sorting index, has to be a number. distAndNeighbour will only be added if dist is as good or better (smaller) than maxDistance. if NNStore is full, further data will be added at the last position and the last data, which must be worse than distAndNeighbour, will be overwritten." - (maxDistance > distAndNeighbour first) ifFalse: [^self]. + (maxDistance > distAndNeighbour first) ifFalse: [^self]. self isFull ifFalse: [lastUsedIndex :=lastUsedIndex +1] . self at: lastUsedIndex put: distAndNeighbour. - self isFull ifTrue: [ self sort ]. + self isFull ifTrue: [ self sort ] ] { #category : #accessing } @@ -59,69 +58,69 @@ PMNNStore >> completeData [ |ar | ar :=(Array new:lastUsedIndex) replaceFrom: 1 to: lastUsedIndex with: self startingAt: 1 . ^self isFull ifTrue: [ar] ifFalse: [ar sort: [: a :b| a first < b first ] ] - ] { #category : #copying } PMNNStore >> copyEmpty [ - ^ self species new: lastUsedIndex + ^ self species new: lastUsedIndex ] { #category : #accessing } PMNNStore >> data [ "return the sorted data" -^self completeData collect: [:e|e at:2] +^self completeData collect: [:e|e at:2] ] { #category : #comparing } PMNNStore >> hash [ -^self class hash bitXor: (self size hash bitXor:(maxDistance hash bitXor: self completeData hash)) +^self class hash bitXor: (self size hash bitXor:(maxDistance hash bitXor: self completeData hash)) ] { #category : #initialization } -PMNNStore >> initialize [ -"can also be used for resetting as eg in testEqual2" -lastUsedIndex :=0. -maxDistance := ((self size = 0) ifTrue: [ 0.0 - Float infinity ]ifFalse: [ Float infinity ]). "(self size = 0) ifTrue: is necessary here, ifEmpty wouldnt work" +PMNNStore >> initialize [ + "can also be used for resetting as eg in testEqual2" + super initialize. + lastUsedIndex := 0. + maxDistance := self size = 0 + ifTrue: [ 0.0 - Float infinity ] + ifFalse: [ Float infinity ] "(self size = 0) ifTrue: is necessary here, ifEmpty wouldnt work" ] { #category : #testing } -PMNNStore >> isEmpty [ +PMNNStore >> isEmpty [ ^lastUsedIndex =0 ] { #category : #testing } PMNNStore >> isFull [ -^lastUsedIndex =self size +^lastUsedIndex =self size ] { #category : #private } PMNNStore >> lastUsedIndex: anInt [ "method is only necessary for correct instance creation. not directly usable for deleting data!" -lastUsedIndex :=anInt . +lastUsedIndex :=anInt ] { #category : #accessing } -PMNNStore >> maxDistance [ +PMNNStore >> maxDistance [ "the maximum sorting index, if NNStore is full; if not then Infinity" -^maxDistance +^maxDistance ] { #category : #copying } -PMNNStore >> postCopy [ +PMNNStore >> postCopy [ super postCopy . lastUsedIndex :=lastUsedIndex copy. -maxDistance :=maxDistance copy. - - +maxDistance :=maxDistance copy ] { #category : #sorting } PMNNStore >> sort [ self ifEmpty: [^self]. self sort: [:a :b| a first < b first ] . - maxDistance := self last first . + maxDistance := self last first ] { #category : #sorting } @@ -134,5 +133,5 @@ self sort. " "sortFor: should not be called before the NNStore is full!" self do:[:e|e at: 1 put: (e at: 2) ]. -self sort . +self sort ] diff --git a/src/Math-KDTree/PMStupidNN.class.st b/src/Math-KDTree/PMStupidNN.class.st index 27a25a4fc..2430eef84 100644 --- a/src/Math-KDTree/PMStupidNN.class.st +++ b/src/Math-KDTree/PMStupidNN.class.st @@ -15,8 +15,7 @@ PMStupidNN >> nnSearch: aCollection i:anInt [ self sortFor: aCollection asFloatArray. d :=self data . anInt =1 ifTrue:[^d first ]. -^d size >anInt ifTrue: [d copyFrom: 1 to: anInt]ifFalse: [d] - +^d size >anInt ifTrue: [d copyFrom: 1 to: anInt]ifFalse: [d] ] { #category : #sorting } @@ -24,5 +23,5 @@ PMStupidNN >> sortFor: aCollection [ "sort nearest neighbours of aCollection " |i| self do:[:e| i :=aCollection -(e at:2) . e at: 1 put: (i*i)sum ]; - sort . + sort ] diff --git a/src/Math-Number-Extensions/Float.extension.st b/src/Math-Number-Extensions/Float.extension.st index 4c083c3a2..ec80f6f6b 100644 --- a/src/Math-Number-Extensions/Float.extension.st +++ b/src/Math-Number-Extensions/Float.extension.st @@ -5,10 +5,10 @@ Float >> arCosh [ "Answer receiver's area hyperbolic cosine. That is the inverse function of cosh." - self < 1 - ifTrue: + self < 1 + ifTrue: [^DomainError signal: 'Receiver must be greater or equal to 1']. - ^self + 1 = self + ^self + 1 = self ifTrue: [self abs ln + 2 ln] ifFalse: [((self squared - 1) sqrt + self) ln] ] @@ -18,8 +18,8 @@ Float >> arSinh [ "Answer receiver's area hyperbolic sine. That is the inverse function of sinh." - self = 0.0 ifTrue: [^self]. "Handle negativeZero" - ^self + 1 = self + self = 0.0 ifTrue: [^self]. "Handle negativeZero" + ^self + 1 = self ifTrue: [(self abs ln + 2 ln) * self sign] ifFalse: [((self squared + 1) sqrt + self) ln] ] @@ -31,8 +31,8 @@ Float >> arTanh [ self = 0.0 ifTrue: [^self]. "Handle negativeZero" self abs = 1 ifTrue: [^self copySignTo: Float infinity]. - self abs > 1 - ifTrue: + self abs > 1 + ifTrue: [^DomainError signal: 'Receiver must be between -1.0 and 1.0']. ^((1 + self) / (1 - self)) ln / 2 ] @@ -40,7 +40,7 @@ Float >> arTanh [ { #category : #'*Math-Number-Extensions-mathematical functions' } Float >> cosh [ "Answer receivers hyperbolic cosine." - + | ex | ex := self exp. ^(ex + ex reciprocal) / 2 @@ -49,7 +49,7 @@ Float >> cosh [ { #category : #'*Math-Number-Extensions-mathematical functions' } Float >> sinh [ "Answer receivers hyperbolic sine" - + | ex | ex := self exp. ^(ex - ex reciprocal) / 2 diff --git a/src/Math-Number-Extensions/Number.extension.st b/src/Math-Number-Extensions/Number.extension.st index 807111187..42ac26bec 100644 --- a/src/Math-Number-Extensions/Number.extension.st +++ b/src/Math-Number-Extensions/Number.extension.st @@ -27,14 +27,14 @@ Number >> arTanh [ { #category : #'*Math-Number-Extensions-mathematical functions' } Number >> cosh [ "Answer receivers hyperbolic cosine." - + ^self asFloat cosh ] { #category : #'*Math-Number-Extensions-mathematical functions' } Number >> sinc [ "Answer receivers cardinal sine." - + ^ self isZero ifTrue: [self class one] ifFalse: [self sin / self] @@ -43,13 +43,13 @@ Number >> sinc [ { #category : #'*Math-Number-Extensions-mathematical functions' } Number >> sinh [ "Answer receivers hyperbolic sine" - + ^self asFloat sinh ] { #category : #'*Math-Number-Extensions-mathematical functions' } Number >> tanh [ "Answer receivers hyperbolic tangent" - + ^self asFloat tanh ] diff --git a/src/Math-Numerical/Integer.extension.st b/src/Math-Numerical/Integer.extension.st index 2b51a4f72..4802f6ca6 100644 --- a/src/Math-Numerical/Integer.extension.st +++ b/src/Math-Numerical/Integer.extension.st @@ -4,20 +4,20 @@ Extension { #name : #Integer } Integer >> gamma [ self > 0 ifFalse: [^ self error: 'Attempt to compute the Gamma function of a non-positive integer']. - ^ (self - 1) factorial. + ^ (self - 1) factorial ] { #category : #'*Math-Numerical' } Integer >> inverseBinomialCoefficient [ - " Reverse binomial coefficient. Answer a with all n and k such that n take: k = self. Elements in the answered Collection should be read as paired. Each pair represents (n,k) in the binomial coefficient formula. + " Reverse binomial coefficient. Answer a with all n and k such that n take: k = self. Elements in the answered Collection should be read as paired. Each pair represents (n,k) in the binomial coefficient formula. See https://math.stackexchange.com/a/103385/205 for details. " | k | [ self > 1 ] assert. k := 0. - ^ Array streamContents: [ :stream | - [ true ] whileTrue: [ + ^ Array streamContents: [ :stream | + [ true ] whileTrue: [ | nmin nmax choose | k := k + 1. 2 * k + 1 * self <= (4 ** k) ifTrue: [ ^ stream contents ]. @@ -25,13 +25,13 @@ Integer >> inverseBinomialCoefficient [ nmax := nmin + k + 1. nmin := nmin max: 2 * k. choose := nmin asInteger numberOfCombinationsTaken: k. - nmin to: nmax do: [ :n | - choose = self ifTrue: [ - stream nextPutAll: { + nmin to: nmax do: [ :n | + choose = self ifTrue: [ + stream nextPutAll: { n asInteger. k asInteger }. - k < (n - k) ifTrue: [ - stream nextPutAll: { + k < (n - k) ifTrue: [ + stream nextPutAll: { n asInteger. (n - k) asInteger } ] ]. choose := choose * (n + 1). diff --git a/src/Math-Numerical/Number.extension.st b/src/Math-Numerical/Number.extension.st index 52141b859..f981417c1 100644 --- a/src/Math-Numerical/Number.extension.st +++ b/src/Math-Numerical/Number.extension.st @@ -19,11 +19,11 @@ Number >> dividingPolynomial: aPolynomial [ { #category : #'*Math-Numerical' } Number >> equalsTo: aNumber [ - + self deprecated: 'Use closeTo: instead' transformWith: '`@rec equalsTo: `@arg' -> '`@rec closeTo: `@arg'. - + ^ self closeTo: aNumber ] diff --git a/src/Math-Numerical/PMBisectionZeroFinder.class.st b/src/Math-Numerical/PMBisectionZeroFinder.class.st index acd8dfbff..cc8afbad1 100644 --- a/src/Math-Numerical/PMBisectionZeroFinder.class.st +++ b/src/Math-Numerical/PMBisectionZeroFinder.class.st @@ -13,11 +13,10 @@ Class { { #category : #operation } PMBisectionZeroFinder >> computeInitialValues [ - "Private" - positiveX isNil - ifTrue: [ self error: 'No positive value supplied']. - negativeX isNil - ifTrue: [ self error: 'No negative value supplied'] + "Private" + + positiveX ifNil: [ self error: 'No positive value supplied' ]. + negativeX ifNil: [ self error: 'No negative value supplied' ] ] { #category : #operation } @@ -35,7 +34,7 @@ PMBisectionZeroFinder >> findNegativeXFrom: aNumber1 range: aNumber2 [ | random n | n := 0. random := Random new. - + [ negativeX := random next * aNumber2 + aNumber1. ( functionBlock value: negativeX) < 0 ] whileFalse: [ n := n + 0.1. @@ -49,7 +48,7 @@ PMBisectionZeroFinder >> findPositiveXFrom: aNumber1 range: aNumber2 [ | n random | n := 0. random := Random new. - + [ positiveX := random next * aNumber2 + aNumber1. ( functionBlock value: positiveX) > 0 ] whileFalse: [ n := n + 1. diff --git a/src/Math-Numerical/PMBulirschStoerInterpolator.class.st b/src/Math-Numerical/PMBulirschStoerInterpolator.class.st index 62bd3455c..e365ce30d 100644 --- a/src/Math-Numerical/PMBulirschStoerInterpolator.class.st +++ b/src/Math-Numerical/PMBulirschStoerInterpolator.class.st @@ -12,6 +12,6 @@ PMBulirschStoerInterpolator >> computeDifference: aNumber at: anInteger1 order: / ( ( self xPointAt: ( anInteger1 + anInteger2)) - aNumber). diff := ( ( leftErrors at: ( anInteger1 + 1)) - ( rightErrors at: anInteger1)) / ( ratio - ( leftErrors at: ( anInteger1 + 1))). - rightErrors at: anInteger1 put: ( leftErrors at: ( anInteger1 + 1)) * diff. - leftErrors at: anInteger1 put: ratio * diff. + rightErrors at: anInteger1 put: ( leftErrors at: ( anInteger1 + 1)) * diff. + leftErrors at: anInteger1 put: ratio * diff ] diff --git a/src/Math-Numerical/PMCDFNewtonZeroFinder.class.st b/src/Math-Numerical/PMCDFNewtonZeroFinder.class.st index 85050894a..10871e8b8 100644 --- a/src/Math-Numerical/PMCDFNewtonZeroFinder.class.st +++ b/src/Math-Numerical/PMCDFNewtonZeroFinder.class.st @@ -14,7 +14,7 @@ Class { PMCDFNewtonZeroFinder >> computeInitialValues [ "super computeInitialValues." "the original testing there is skipped for speed reasons, not because of the error,that is produced here, which is completely eliminated" - old:=result-1.0. + old:=result-1.0 ] { #category : #operation } @@ -23,7 +23,7 @@ PMCDFNewtonZeroFinder >> evaluateIteration [ | delta new | delta :=( functionBlock value: result) / (derivativeBlock value: result). new := result - delta. - old=old ifTrue: [new:=old+result /2.0]]. [0.0 = (derivativeBlock value: new )] whileTrue: [new:=new +result /2.0]. @@ -33,7 +33,7 @@ PMCDFNewtonZeroFinder >> evaluateIteration [ ] { #category : #initialization } -PMCDFNewtonZeroFinder >> setDerivative: aBlock [ +PMCDFNewtonZeroFinder >> setDerivative: aBlock [ "the original testing is skipped for speed reasons, not because of the error (which is largely eliminated anyway)." derivativeBlock := aBlock diff --git a/src/Math-Numerical/PMCovarianceAccumulator.class.st b/src/Math-Numerical/PMCovarianceAccumulator.class.st index 905e1b5d3..d3340b9db 100644 --- a/src/Math-Numerical/PMCovarianceAccumulator.class.st +++ b/src/Math-Numerical/PMCovarianceAccumulator.class.st @@ -25,7 +25,7 @@ PMCovarianceAccumulator >> accumulate: anArray [ [ :m | ( covariance at: n) at: m put: ( count1 * ( delta at: n) * ( delta at: m) + ( r * ( ( covariance at: n) at: m))). ]. - ]. + ] ] { #category : #information } diff --git a/src/Math-Numerical/PMDecimalFloatingNumber.class.st b/src/Math-Numerical/PMDecimalFloatingNumber.class.st index d5d5cfafd..e97aa1430 100644 --- a/src/Math-Numerical/PMDecimalFloatingNumber.class.st +++ b/src/Math-Numerical/PMDecimalFloatingNumber.class.st @@ -38,8 +38,7 @@ PMDecimalFloatingNumber class >> defaultDigits: anInteger [ PMDecimalFloatingNumber class >> digits [ "Private" - Digits isNil - ifTrue: [ Digits := self defaultDigits ]. + Digits ifNil: [ Digits := self defaultDigits ]. ^ Digits ] diff --git a/src/Math-Numerical/PMGeneticOptimizer.class.st b/src/Math-Numerical/PMGeneticOptimizer.class.st index d7f6d1b5e..cb231c38d 100644 --- a/src/Math-Numerical/PMGeneticOptimizer.class.st +++ b/src/Math-Numerical/PMGeneticOptimizer.class.st @@ -20,11 +20,11 @@ PMGeneticOptimizer class >> defaultPrecision [ ] { #category : #transformation } -PMGeneticOptimizer >> addPointAt: aNumber [ +PMGeneticOptimizer >> addPointAt: aNumber [ "necessary since nan's and infinites can throw off calculations. and calculations become a tiny bit more efficient" | p | p:=optimizingPointClass vector: aNumber function: functionBlock. - ((p value isInfinite)or:[p value isNaN]) ifFalse: [bestPoints add: p]. + ((p value isInfinite)or:[p value isNaN]) ifFalse: [bestPoints add: p] ] { #category : #initialization } @@ -37,10 +37,10 @@ PMGeneticOptimizer >> collectPoints [ "Private" | bestPoint | - bestPoints isEmpty ifFalse: [bestPoint := bestPoints first]. + bestPoints ifNotEmpty: [ bestPoint := bestPoints first ]. bestPoints removeAll. - chromosomeManager population do: [:each | self addPointAt: each]. - bestPoint ifNotNil: [:b|bestPoints add: b]. + chromosomeManager population do: [ :each | self addPointAt: each ]. + bestPoint ifNotNil: [ :b | bestPoints add: b ]. result := bestPoints first position ] @@ -81,7 +81,7 @@ PMGeneticOptimizer >> randomIndex: aNumberArray [ random := Random new. x := random next. n := 1. - aNumberArray do: + aNumberArray do: [ :each | x < each ifTrue: [ ^n]. @@ -92,20 +92,24 @@ PMGeneticOptimizer >> randomIndex: aNumberArray [ { #category : #information } PMGeneticOptimizer >> randomScale [ - "Private" - "changes take care of divide by zero error" - | norm fBest fWorst answer| + "Private" + + "changes take care of divide by zero error" + + | norm fBest fWorst answer | fBest := bestPoints first value. fWorst := bestPoints last value. - norm :=fBest - fWorst. - norm =0 ifTrue: [ - norm:= 1 / bestPoints size. - answer := bestPoints collect: [:each| norm] ] ifFalse: [ - norm := 1 / norm. - answer := bestPoints collect: [ :each | (each value - fWorst) * norm] ]. - norm := 1 / ( answer inject: 0 into: [ :sum :each | each + sum]). + norm := fBest - fWorst. + answer := norm = 0 + ifTrue: [ + norm := 1 / bestPoints size. + bestPoints collect: [ :each | norm ] ] + ifFalse: [ + norm := 1 / norm. + bestPoints collect: [ :each | each value - fWorst * norm ] ]. + norm := 1 / (answer inject: 0 into: [ :sum :each | each + sum ]). fBest := 0. - ^answer collect: [ :each | fBest := each * norm + fBest. fBest] - - + ^ answer collect: [ :each | + fBest := each * norm + fBest. + fBest ] ] diff --git a/src/Math-Numerical/PMHillClimbingOptimizer.class.st b/src/Math-Numerical/PMHillClimbingOptimizer.class.st index 42ad642bf..c1c14120f 100644 --- a/src/Math-Numerical/PMHillClimbingOptimizer.class.st +++ b/src/Math-Numerical/PMHillClimbingOptimizer.class.st @@ -17,7 +17,7 @@ Class { { #category : #examples } PMHillClimbingOptimizer class >> exampleFindOptimumOnVectorFunction [ | fBlock educatedGuess hillClimber result | - fBlock := [ :v | + fBlock := [ :v | | x y | x := v at: 1. y := v at: 2. @@ -41,7 +41,7 @@ PMHillClimbingOptimizer >> computeInitialValues [ at: n put: 1; yourself); yourself - ]. + ] ] { #category : #operation } @@ -64,11 +64,10 @@ PMHillClimbingOptimizer >> evaluateIteration [ { #category : #operation } PMHillClimbingOptimizer >> finalizeIterations [ - ] { #category : #operation } -PMHillClimbingOptimizer >> minimizeDirection: aVectorFunction [ +PMHillClimbingOptimizer >> minimizeDirection: aVectorFunction [ ^unidimensionalFinder reset; setFunction: aVectorFunction; @@ -79,7 +78,7 @@ PMHillClimbingOptimizer >> minimizeDirection: aVectorFunction [ ] { #category : #operation } -PMHillClimbingOptimizer >> minimizeDirection: aVectorFunction from: aVector [ +PMHillClimbingOptimizer >> minimizeDirection: aVectorFunction from: aVector [ ^aVectorFunction origin: aVector; @@ -92,7 +91,7 @@ PMHillClimbingOptimizer >> shiftDirections [ firstDirection := bestPoints first direction. bestPoints inject: nil - into: [ :prev :each | + into: [ :prev :each | position ifNil: [ position := each origin ] ifNotNil: [ prev direction: each direction ]. diff --git a/src/Math-Numerical/PMLagrangeInterpolator.class.st b/src/Math-Numerical/PMLagrangeInterpolator.class.st index 50a640065..ec9b2bb69 100644 --- a/src/Math-Numerical/PMLagrangeInterpolator.class.st +++ b/src/Math-Numerical/PMLagrangeInterpolator.class.st @@ -35,7 +35,9 @@ PMLagrangeInterpolator >> defaultSamplePoints [ { #category : #initialization } PMLagrangeInterpolator >> initialize [ - ^self initialize: self defaultSamplePoints + super initialize. + + ^ self initialize: self defaultSamplePoints ] { #category : #initialization } diff --git a/src/Math-Numerical/PMLanczosFormula.class.st b/src/Math-Numerical/PMLanczosFormula.class.st index b1fbaf6e9..dabca3041 100644 --- a/src/Math-Numerical/PMLanczosFormula.class.st +++ b/src/Math-Numerical/PMLanczosFormula.class.st @@ -25,17 +25,17 @@ Class { { #category : #creation } PMLanczosFormula class >> new [ - "Answer a unique instance. Create it if it does not exist." - UniqueInstance isNil - ifTrue: [ UniqueInstance := super new. - UniqueInstance initialize. - ]. - ^UniqueInstance + "Answer a unique instance. Create it if it does not exist." + + UniqueInstance ifNil: [ + UniqueInstance := super new. + UniqueInstance initialize ]. + ^ UniqueInstance ] { #category : #'instance creation' } PMLanczosFormula class >> reset [ - UniqueInstance := nil. + UniqueInstance := nil ] { #category : #information } @@ -47,8 +47,10 @@ PMLanczosFormula >> gamma: aNumber [ PMLanczosFormula >> initialize [ "Private" + super initialize. + sqrt2Pi := (Float pi * 2) sqrt. - coefficients := #(76.18009172947146 -86.50532032941677 24.01409824083091 -1.231739572450155 0.1208650973866179e-2 -0.5395239384953e-5) + coefficients := #( 76.18009172947146 -86.50532032941677 24.01409824083091 -1.231739572450155 0.1208650973866179e-2 -0.5395239384953e-5 ) ] { #category : #information } @@ -73,7 +75,7 @@ PMLanczosFormula >> series: aNumber [ term := aNumber. ^ coefficients inject: 1.000000000190015 - into: [ :sum :each | + into: [ :sum :each | term := term + 1. each / term + sum ] ] diff --git a/src/Math-Numerical/PMLeastSquareFit.class.st b/src/Math-Numerical/PMLeastSquareFit.class.st index f2caaced2..b93c48b9e 100644 --- a/src/Math-Numerical/PMLeastSquareFit.class.st +++ b/src/Math-Numerical/PMLeastSquareFit.class.st @@ -13,7 +13,7 @@ Class { } { #category : #creation } -PMLeastSquareFit class >> histogram: aHistogram distributionClass: aProbabilityDensityFunctionClass [ +PMLeastSquareFit class >> histogram: aHistogram distributionClass: aProbabilityDensityFunctionClass [ ^self points: aHistogram function: (PMScaledProbabilityDensityFunction histogram: aHistogram distributionClass: aProbabilityDensityFunctionClass) @@ -21,9 +21,8 @@ PMLeastSquareFit class >> histogram: aHistogram distributionClass: aProbabilityD { #category : #creation } PMLeastSquareFit class >> points: aDataHolder function: aParametricFunction [ - ^aParametricFunction isNil - ifTrue: [nil] - ifFalse: [self new initialize: aDataHolder data: aParametricFunction] + + ^ aParametricFunction ifNotNil: [ self new initialize: aDataHolder data: aParametricFunction ] ] { #category : #operation } @@ -48,9 +47,9 @@ PMLeastSquareFit >> accumulateEquationSystem [ { #category : #information } PMLeastSquareFit >> chiSquare [ - chiSquare isNil - ifTrue: [ self computeChiSquare]. - ^chiSquare + + chiSquare ifNil: [ self computeChiSquare ]. + ^ chiSquare ] { #category : #operation } @@ -69,7 +68,7 @@ PMLeastSquareFit >> computeChiSquare [ [ :each | chiSquare := ( each chi2Contribution: result) + chiSquare. degreeOfFreedom := degreeOfFreedom + 1. - ]. + ] ] { #category : #operation } @@ -77,7 +76,7 @@ PMLeastSquareFit >> computeEquationSystem [ "Private" constants atAllPut: 0. equations do: [ :each | each atAllPut: 0]. - self accumulateEquationSystem. + self accumulateEquationSystem ] { #category : #information } @@ -87,9 +86,9 @@ PMLeastSquareFit >> confidenceLevel [ { #category : #information } PMLeastSquareFit >> degreeOfFreedom [ - degreeOfFreedom isNil - ifTrue: [ self computeChiSquare]. - ^degreeOfFreedom + + degreeOfFreedom ifNil: [ self computeChiSquare ]. + ^ degreeOfFreedom ] { #category : #information } @@ -107,7 +106,7 @@ PMLeastSquareFit >> evaluateIteration [ changes := self computeChanges. result changeParametersBy: changes. maxChange := 0. - result parameters with: changes do: + result parameters with: changes do: [ :r :d | maxChange := ( d / r) abs max: maxChange]. ^maxChange ] @@ -140,8 +139,8 @@ PMLeastSquareFit >> initializeIterations [ constants := (PMVector new: n) atAllPut: 0; yourself. - equations := (1 to: n) collect: - [:k | + equations := (1 to: n) collect: + [:k | (PMVector new: n) atAllPut: 0; yourself] diff --git a/src/Math-Numerical/PMLeastSquares.class.st b/src/Math-Numerical/PMLeastSquares.class.st index 8dfdd9503..18762417d 100644 --- a/src/Math-Numerical/PMLeastSquares.class.st +++ b/src/Math-Numerical/PMLeastSquares.class.st @@ -21,7 +21,7 @@ PMLeastSquares >> pseudoinverseOfDiagonal: aMatrix [ diagonalSize := aMatrix numberOfRows min: aMatrix numberOfColumns. "Inverting the elements on the main diaginal" - 1 to: diagonalSize do: [ :i | + 1 to: diagonalSize do: [ :i | pseudoinverse at: i at: i put: ((aMatrix at: i at: i) = 0 ifTrue: [ 0 ] ifFalse: [ 1 / (aMatrix at: i at: i) ]) ]. @@ -33,7 +33,7 @@ PMLeastSquares >> solveMatrixA: aMatrix matrixB: aMatrixOrVector [ "If b is a vector: x' = minimize || b - Ax || - + If B is a matrix: X' = minimize || B - AX ||" diff --git a/src/Math-Numerical/PMLineSearch.class.st b/src/Math-Numerical/PMLineSearch.class.st index 6ad44638e..c44a3e66e 100644 --- a/src/Math-Numerical/PMLineSearch.class.st +++ b/src/Math-Numerical/PMLineSearch.class.st @@ -45,7 +45,7 @@ Class { { #category : #'instance creation' } PMLineSearch class >> function: aBlock valueAtZero: valueAtZero derivativeAtZero: derivativeAtZero valueAtOne: valueAtOne [ ^ self new - setFunction: aBlock; setValueAtZero: valueAtZero derivativeAtZero: derivativeAtZero valueAtOne: valueAtOne; + setFunction: aBlock; setValueAtZero: valueAtZero derivativeAtZero: derivativeAtZero valueAtOne: valueAtOne; yourself ] @@ -71,7 +71,7 @@ PMLineSearch >> computeInitialValues [ extendedResult at: 3 put: 0.0. extendedResult at: 4 put: (boundaryValues at: 1). useCubicApproximation := false. - result := 1.0. + result := 1.0 ] { #category : #operation } @@ -98,7 +98,7 @@ PMLineSearch >> evaluateIteration [ nextX := dg0 negated * 0.5 / (g1 - g0 - dg0) max: 0.1. useCubicApproximation := true ] ifTrue: [ - gamma := [ :n | + gamma := [ :n | ((extendedResult at: (n+2)) - dg0 * (extendedResult at: n) - g0) / deltaX ]. tmp1 := (gamma value: 1) / x1 squared. tmp2 := (gamma value: 2) / x2 squared. @@ -106,7 +106,7 @@ PMLineSearch >> evaluateIteration [ b := x1 * tmp2 - x2 * tmp1. nextX := (b negated + (b squared - (3.0 * a * dg0) sqrt)) / (3.0 * a) min: 0.5 *x1 max: 0.1 * x1. nextX < failingMin ifTrue: [ self error: 'next x is too small: cannot minimize' ] ]. - self updateResult: nextX. + self updateResult: nextX ] { #category : #accessing } @@ -121,7 +121,7 @@ PMLineSearch >> failingMin: newFailingMin [ failingMin := newFailingMin ] -{ #category : #'as yet unclassified' } +{ #category : #testing } PMLineSearch >> hasConverged [ "Customized convergence test: minimize the function as g(x)<=g(0)+alpha*g'(0)" | g0 dg0 gNew | @@ -160,5 +160,4 @@ PMLineSearch >> updateResult: nextX [ extendedResult at: 1 put: nextX. extendedResult at: 2 put: (functionBlock value: nextX). result := nextX - ] diff --git a/src/Math-Numerical/PMLinearRegression.class.st b/src/Math-Numerical/PMLinearRegression.class.st index f8e9e3977..28c992935 100644 --- a/src/Math-Numerical/PMLinearRegression.class.st +++ b/src/Math-Numerical/PMLinearRegression.class.st @@ -24,11 +24,11 @@ PMLinearRegression class >> new [ { #category : #transformation } PMLinearRegression >> add: aPoint [ "Accumulate aPoint into of the receiver." - self add: aPoint weight: 1. + self add: aPoint weight: 1 ] { #category : #transformation } -PMLinearRegression >> add: aPoint weight: aNumber [ +PMLinearRegression >> add: aPoint weight: aNumber [ "Accumulate aPoint into of the receiver." sum1 := sum1 + aNumber. @@ -70,16 +70,16 @@ PMLinearRegression >> computeResults [ xyNorm := sumXY * sum1 - (sumX * sumY). slope := xyNorm / xNorm. intercept := (sumXX * sumY - (sumXY * sumX)) / xNorm. - correlationCoefficient := xyNorm + correlationCoefficient := xyNorm / (xNorm * (sumYY * sum1 - (sumY * sumY))) sqrt ] { #category : #information } PMLinearRegression >> correlationCoefficient [ - "Answers the correlation coefficient of the receiver." - correlationCoefficient isNil - ifTrue: [ self computeResults]. - ^correlationCoefficient + "Answers the correlation coefficient of the receiver." + + correlationCoefficient ifNil: [ self computeResults ]. + ^ correlationCoefficient ] { #category : #information } @@ -108,14 +108,14 @@ PMLinearRegression >> errorOnSlope [ { #category : #information } PMLinearRegression >> intercept [ - "Answers the intercept of the receiver." - intercept isNil - ifTrue: [ self computeResults]. - ^intercept + "Answers the intercept of the receiver." + + intercept ifNil: [ self computeResults ]. + ^ intercept ] { #category : #transformation } -PMLinearRegression >> remove: aPoint [ +PMLinearRegression >> remove: aPoint [ "Remove aPoint which was accumulated into of the receiver." sum1 := sum1 - 1. @@ -150,10 +150,10 @@ PMLinearRegression >> resetResults [ { #category : #information } PMLinearRegression >> slope [ - "Answers the slope of the receiver." - slope isNil - ifTrue: [ self computeResults]. - ^slope + "Answers the slope of the receiver." + + slope ifNil: [ self computeResults ]. + ^ slope ] { #category : #information } diff --git a/src/Math-Numerical/PMMaximumLikelihoodHistogramFit.class.st b/src/Math-Numerical/PMMaximumLikelihoodHistogramFit.class.st index fb067f9b8..1ff39ad0f 100644 --- a/src/Math-Numerical/PMMaximumLikelihoodHistogramFit.class.st +++ b/src/Math-Numerical/PMMaximumLikelihoodHistogramFit.class.st @@ -39,15 +39,15 @@ PMMaximumLikelihoodHistogramFit >> computeNormalization [ | numerator denominator temp | numerator := 0. denominator := 0. - dataHolder pointsAndErrorsDo: - [:each | + dataHolder pointsAndErrorsDo: + [:each | temp := result value: each xValue. - temp = 0 - ifFalse: + temp = 0 + ifFalse: [numerator := numerator + (each yValue squared / temp). denominator := denominator + temp]]. count := ( numerator / denominator) sqrt. - countVariance := numerator / ( 4 * count). + countVariance := numerator / ( 4 * count) ] { #category : #operation } @@ -94,7 +94,7 @@ PMMaximumLikelihoodHistogramFit >> numberOfParameters [ ] { #category : #information } -PMMaximumLikelihoodHistogramFit >> valueAndError: aNumber [ +PMMaximumLikelihoodHistogramFit >> valueAndError: aNumber [ | valueGradient gradient gVar | valueGradient := result valueAndGradient: aNumber. diff --git a/src/Math-Numerical/PMMinimizingPoint.class.st b/src/Math-Numerical/PMMinimizingPoint.class.st index 53db5f82e..010a0cc4f 100644 --- a/src/Math-Numerical/PMMinimizingPoint.class.st +++ b/src/Math-Numerical/PMMinimizingPoint.class.st @@ -14,7 +14,7 @@ PMMinimizingPoint class >> new: aVector value: aNumber [ ] { #category : #creation } -PMMinimizingPoint class >> vector: aVector function: aFunction [ +PMMinimizingPoint class >> vector: aVector function: aFunction [ ^self new: aVector value: (aFunction value: aVector) ] @@ -41,7 +41,7 @@ PMMinimizingPoint >> position [ ] { #category : #display } -PMMinimizingPoint >> printOn: aStream [ +PMMinimizingPoint >> printOn: aStream [ position printOn: aStream. aStream nextPut: $:; @@ -56,10 +56,10 @@ PMMinimizingPoint >> value [ { #category : #initialization } PMMinimizingPoint >> value: aNumber [ - value := aNumber. + value := aNumber ] { #category : #initialization } -PMMinimizingPoint >> vector: aVector [ +PMMinimizingPoint >> vector: aVector [ position := aVector ] diff --git a/src/Math-Numerical/PMMultiVariableGeneralOptimizer.class.st b/src/Math-Numerical/PMMultiVariableGeneralOptimizer.class.st index 2a7fee842..25402fb2b 100644 --- a/src/Math-Numerical/PMMultiVariableGeneralOptimizer.class.st +++ b/src/Math-Numerical/PMMultiVariableGeneralOptimizer.class.st @@ -6,8 +6,8 @@ Class { { #category : #operation } PMMultiVariableGeneralOptimizer >> computeInitialValues [ - self range notNil - ifTrue: [ self performGeneticOptimization]. + + self range ifNotNil: [ self performGeneticOptimization ]. self performSimplexOptimization ] @@ -33,7 +33,7 @@ PMMultiVariableGeneralOptimizer >> origin [ { #category : #initialization } PMMultiVariableGeneralOptimizer >> origin: anArrayOrVector [ - result := anArrayOrVector. + result := anArrayOrVector ] { #category : #operation } @@ -44,7 +44,7 @@ PMMultiVariableGeneralOptimizer >> performGeneticOptimization [ manager := PMVectorChromosomeManager new: 100 mutation: 0.1 crossover: 0.1. manager origin: self origin asPMVector; range: self range asPMVector. optimizer chromosomeManager: manager. - result := optimizer evaluate. + result := optimizer evaluate ] { #category : #operation } diff --git a/src/Math-Numerical/PMNevilleInterpolator.class.st b/src/Math-Numerical/PMNevilleInterpolator.class.st index e182725c2..ca3a02250 100644 --- a/src/Math-Numerical/PMNevilleInterpolator.class.st +++ b/src/Math-Numerical/PMNevilleInterpolator.class.st @@ -10,24 +10,24 @@ Class { { #category : #private } PMNevilleInterpolator >> computeDifference: aNumber at: anInteger1 order: anInteger2 [ - + | leftDist rightDist ratio | leftDist := ( self xPointAt: anInteger1) - aNumber. rightDist := ( self xPointAt: ( anInteger1 + anInteger2)) - aNumber. ratio := ( ( leftErrors at: ( anInteger1 + 1)) - ( rightErrors at: anInteger1)) / ( leftDist - rightDist). leftErrors at: anInteger1 put: ratio * leftDist. - rightErrors at: anInteger1 put: ratio * rightDist. + rightErrors at: anInteger1 put: ratio * rightDist ] { #category : #information } PMNevilleInterpolator >> defaultSamplePoints [ - + ^SortedCollection sortBlock: [ :a :b | a x < b x] ] { #category : #initialization } PMNevilleInterpolator >> initialize [ - + super initialize. leftErrors := Array new. rightErrors := Array new diff --git a/src/Math-Numerical/PMNewtonInterpolator.class.st b/src/Math-Numerical/PMNewtonInterpolator.class.st index 7ecf8cf46..fe8830691 100644 --- a/src/Math-Numerical/PMNewtonInterpolator.class.st +++ b/src/Math-Numerical/PMNewtonInterpolator.class.st @@ -35,27 +35,26 @@ PMNewtonInterpolator >> computeCoefficients [ do: [ :k | k1 := k - 1. kn := k - n. - coefficients at: k put: ( (( coefficients at: k) - ( coefficients at: k1)) + coefficients at: k put: ( (( coefficients at: k) - ( coefficients at: k1)) / ((self xPointAt: k) - (self xPointAt: kn))). ]. - ]. + ] ] { #category : #transformation } PMNewtonInterpolator >> resetCoefficients [ "Private - Reset the coefficients of the receiver to force a new computation." - coefficients := nil. + coefficients := nil ] { #category : #information } PMNewtonInterpolator >> value: aNumber [ "Compute the value of the Lagrange interpolation polynomial on the receiver's points at aNumber." + | answer size | - coefficients isNil - ifTrue: [ self computeCoefficients]. + coefficients ifNil: [ self computeCoefficients ]. size := coefficients size. answer := coefficients at: size. - (size - 1) to: 1 by: -1 - do: [ :n | answer := answer * ( aNumber - (self xPointAt: n)) + ( coefficients at: n)]. - ^answer + size - 1 to: 1 by: -1 do: [ :n | answer := answer * (aNumber - (self xPointAt: n)) + (coefficients at: n) ]. + ^ answer ] diff --git a/src/Math-Numerical/PMNewtonZeroFinder.class.st b/src/Math-Numerical/PMNewtonZeroFinder.class.st index ac518705d..a253bdd38 100644 --- a/src/Math-Numerical/PMNewtonZeroFinder.class.st +++ b/src/Math-Numerical/PMNewtonZeroFinder.class.st @@ -44,22 +44,22 @@ PMNewtonZeroFinder >> computeInitialValues [ "Private - If no derivative has been defined, take an ad-hoc definition. If no initial value has been defined, take 0 as the starting point (for lack of anything better)." | n random | - + result ifNil: [ result := 0]. derivativeBlock ifNil: [ derivativeBlock := self defaultDerivativeBlock]. - + n := 0. random := Random new. - + [ (derivativeBlock value: result) closeTo: 0] whileTrue: [ n := n + 1. - + n > maximumIterations ifTrue: [ self error: 'Function''s derivative seems to be zero everywhere' ]. - + result := random next + result ]. - - newFunctionValue := functionBlock value: result. + + newFunctionValue := functionBlock value: result ] { #category : #information } @@ -84,16 +84,15 @@ PMNewtonZeroFinder >> evaluateIteration [ searchStep := coefficient * searchStep. result := result + searchStep. ^ self relativePrecision: (searchStep abs max: newFunctionValue abs) - ] { #category : #initialization } PMNewtonZeroFinder >> initialValue: aNumber [ "Defines the initial value for the iterations." - result := aNumber. + result := aNumber ] -{ #category : #'as yet unclassified' } +{ #category : #initialization } PMNewtonZeroFinder >> initialize [ "Initialize lineSearchFunction and lineSearch: it depends on other variables only indirectly, can be initialized once at the begining" @@ -107,25 +106,25 @@ PMNewtonZeroFinder >> initialize [ ] { #category : #initialization } -PMNewtonZeroFinder >> setDerivative: aBlock [ +PMNewtonZeroFinder >> setDerivative: aBlock [ "Defines the derivative of the function for which zeroes will be found. Tests if provided block indeed implements the derivative of the function" | x random | - + (aBlock respondsTo: #value:) ifFalse: [ self error: 'Derivative block must implement the method value:' ]. - + random := Random new. - + x := result ifNil: [ random next ] ifNotNil: [ result + random next ]. - + ((aBlock value: x) closeTo: (self defaultDerivativeBlock value: x) precision: 1.0e-4) ifFalse: [ self error: 'Supplied derivative is not correct' ]. - + derivativeBlock := aBlock ] @@ -133,5 +132,5 @@ PMNewtonZeroFinder >> setDerivative: aBlock [ PMNewtonZeroFinder >> setFunction: aBlock [ "Sets the function block (delegates to superclass). Resets the derivative" super setFunction: aBlock. - derivativeBlock := nil. + derivativeBlock := nil ] diff --git a/src/Math-Numerical/PMOneVariableFunctionOptimizer.class.st b/src/Math-Numerical/PMOneVariableFunctionOptimizer.class.st index b5982e190..c4a4644a1 100644 --- a/src/Math-Numerical/PMOneVariableFunctionOptimizer.class.st +++ b/src/Math-Numerical/PMOneVariableFunctionOptimizer.class.st @@ -17,8 +17,8 @@ PMOneVariableFunctionOptimizer class >> defaultPrecision [ PMOneVariableFunctionOptimizer class >> goldenSection [ "Private" - GoldenSection isNil ifTrue: [GoldenSection := (3 - 5 sqrt) / 2]. - ^GoldenSection + GoldenSection ifNil: [ GoldenSection := 3 - 5 sqrt / 2 ]. + ^ GoldenSection ] { #category : #operation } @@ -72,7 +72,7 @@ PMOneVariableFunctionOptimizer >> indexOfOuterPoint [ ifTrue: [ ^n]. superior := true. ]. - ]. + ] ] { #category : #information } diff --git a/src/Math-Numerical/PMOptimizingBracketFinder.class.st b/src/Math-Numerical/PMOptimizingBracketFinder.class.st index d5e2a45cc..6ceb5fe4a 100644 --- a/src/Math-Numerical/PMOptimizingBracketFinder.class.st +++ b/src/Math-Numerical/PMOptimizingBracketFinder.class.st @@ -14,7 +14,7 @@ PMOptimizingBracketFinder class >> initialPoints: aSortedCollection function: aF PMOptimizingBracketFinder >> computeInitialValues [ | random | random := Random new. - + [ bestPoints size < 2 ] whileTrue: [ self addPointAt: random next ] ] diff --git a/src/Math-Numerical/PMPointSeries.class.st b/src/Math-Numerical/PMPointSeries.class.st index 482188389..5bd3dec83 100644 --- a/src/Math-Numerical/PMPointSeries.class.st +++ b/src/Math-Numerical/PMPointSeries.class.st @@ -48,11 +48,13 @@ PMPointSeries >> firstPoint [ ^self at: 1 ] -{ #category : #'public methods' } +{ #category : #initialization } PMPointSeries >> initialize [ "Create the point collection" + + super initialize. points := SortedCollection sortBlock: self sortBlock. - ^self + ^ self ] { #category : #'public methods' } @@ -62,7 +64,8 @@ PMPointSeries >> isEmpty [ { #category : #'public methods' } PMPointSeries >> notEmpty [ - ^points notEmpty + + ^ points isNotEmpty ] { #category : #'public methods' } @@ -73,19 +76,19 @@ PMPointSeries >> pointCollection [ { #category : #'public methods' } PMPointSeries >> pointsDo: aBlock [ - points do: aBlock. + points do: aBlock ] { #category : #privateMethods } PMPointSeries >> primitiveAdd: aPoint [ "Private - Add a point to the receiver" - points add: aPoint. + points add: aPoint ] { #category : #privateMethods } PMPointSeries >> primitiveRemove: aPoint [ "Private - Removes a point from the receiver" - points remove: aPoint. + points remove: aPoint ] { #category : #'public methods' } diff --git a/src/Math-Numerical/PMProjectedOneVariableFunction.class.st b/src/Math-Numerical/PMProjectedOneVariableFunction.class.st index fd22a81dc..0db5dba2f 100644 --- a/src/Math-Numerical/PMProjectedOneVariableFunction.class.st +++ b/src/Math-Numerical/PMProjectedOneVariableFunction.class.st @@ -22,19 +22,19 @@ PMProjectedOneVariableFunction >> argumentWith: aNumber [ { #category : #transformation } PMProjectedOneVariableFunction >> bumpIndex [ - index isNil - ifTrue: [ index := 1] - ifFalse:[ index := index + 1. - index > argument size - ifTrue: [ index := 1]. - ]. + + index + ifNil: [ index := 1 ] + ifNotNil: [ + index := index + 1. + index > argument size ifTrue: [ index := 1 ] ] ] { #category : #information } PMProjectedOneVariableFunction >> index [ - index isNil - ifTrue: [ index := 1]. - ^index + + index ifNil: [ index := 1 ]. + ^ index ] { #category : #initialization } @@ -45,12 +45,12 @@ PMProjectedOneVariableFunction >> initialize: aFunction [ { #category : #initialization } PMProjectedOneVariableFunction >> setArgument: anArrayOrVector [ - argument := anArrayOrVector copy. + argument := anArrayOrVector copy ] { #category : #initialization } PMProjectedOneVariableFunction >> setIndex: anInteger [ - index := anInteger. + index := anInteger ] { #category : #information } diff --git a/src/Math-Numerical/PMScaledProbabilityDensityFunction.class.st b/src/Math-Numerical/PMScaledProbabilityDensityFunction.class.st index 9dba69d0a..06b9cb508 100644 --- a/src/Math-Numerical/PMScaledProbabilityDensityFunction.class.st +++ b/src/Math-Numerical/PMScaledProbabilityDensityFunction.class.st @@ -10,29 +10,27 @@ Class { } { #category : #creation } -PMScaledProbabilityDensityFunction class >> histogram: aHistogram against: aProbabilityDensityFunction [ +PMScaledProbabilityDensityFunction class >> histogram: aHistogram against: aProbabilityDensityFunction [ "Create a new instance of the receiver with given probability density function and histogram." - ^self new + ^self new initialize: aProbabilityDensityFunction binWidth: aHistogram binWidth count: aHistogram totalCount ] { #category : #creation } -PMScaledProbabilityDensityFunction class >> histogram: aHistogram distributionClass: aProbabilityDensityFunctionClass [ +PMScaledProbabilityDensityFunction class >> histogram: aHistogram distributionClass: aProbabilityDensityFunctionClass [ "Create a new instance of the receiver with given probability density function and histogram." | dp | - ^(dp := aProbabilityDensityFunctionClass fromHistogram: aHistogram) isNil - ifTrue: [nil] - ifFalse: [self histogram: aHistogram against: dp] + ^ (dp := aProbabilityDensityFunctionClass fromHistogram: aHistogram) ifNotNil: [ self histogram: aHistogram against: dp ] ] { #category : #transformation } PMScaledProbabilityDensityFunction >> changeParametersBy: aVector [ "Modify the parameters of the receiver by aVector" count := count + aVector last. - probabilityDensityFunction changeParametersBy: aVector. + probabilityDensityFunction changeParametersBy: aVector ] { #category : #information } @@ -41,7 +39,7 @@ PMScaledProbabilityDensityFunction >> distributionFunction [ ] { #category : #initialization } -PMScaledProbabilityDensityFunction >> initialize: aProbabilityDensityFunction binWidth: aNumber count: anInteger [ +PMScaledProbabilityDensityFunction >> initialize: aProbabilityDensityFunction binWidth: aNumber count: anInteger [ "Private" probabilityDensityFunction := aProbabilityDensityFunction. @@ -60,12 +58,12 @@ PMScaledProbabilityDensityFunction >> printOn: aStream [ super printOn: aStream. aStream nextPut: $[; nextPutAll: probabilityDensityFunction class distributionName; - nextPut: $]. + nextPut: $] ] { #category : #transformation } PMScaledProbabilityDensityFunction >> setCount: aNumber [ - count := aNumber. + count := aNumber ] { #category : #information } @@ -75,7 +73,7 @@ PMScaledProbabilityDensityFunction >> value: aNumber [ ] { #category : #information } -PMScaledProbabilityDensityFunction >> valueAndGradient: aNumber [ +PMScaledProbabilityDensityFunction >> valueAndGradient: aNumber [ "Answers an Array containing the value of the receiver at aNumber and the gradient of the receiver's respective to the receiver's parameters evaluated at aNumber." diff --git a/src/Math-Numerical/PMSimplexOptimizer.class.st b/src/Math-Numerical/PMSimplexOptimizer.class.st index f1ebe50f8..5e62cd7ac 100644 --- a/src/Math-Numerical/PMSimplexOptimizer.class.st +++ b/src/Math-Numerical/PMSimplexOptimizer.class.st @@ -18,25 +18,25 @@ PMSimplexOptimizer >> buildInitialSimplex [ "Private" | projectedFunction finder partialResult | - projectedFunction := PMProjectedOneVariableFunction + projectedFunction := PMProjectedOneVariableFunction function: functionBlock. finder := PMOneVariableFunctionOptimizer forOptimizer: self. finder setFunction: projectedFunction. - [bestPoints size < (result size + 1)] whileTrue: + [bestPoints size < (result size + 1)] whileTrue: [projectedFunction setArgument: result; bumpIndex. partialResult := finder reset; evaluate. - bestPoints add: (optimizingPointClass + bestPoints add: (optimizingPointClass vector: (projectedFunction argumentWith: partialResult) function: functionBlock)] ] { #category : #initialization } PMSimplexOptimizer >> computeInitialValues [ - bestPoints + bestPoints add: (optimizingPointClass vector: result function: functionBlock). self buildInitialSimplex. worstVector := bestPoints removeLast position @@ -66,10 +66,10 @@ PMSimplexOptimizer >> contract [ ] { #category : #operation } -PMSimplexOptimizer >> contract: aVector around: bestVector [ +PMSimplexOptimizer >> contract: aVector around: bestVector [ "Private" - bestPoints + bestPoints add: (optimizingPointClass vector: bestVector * 0.5 + (aVector * 0.5) function: functionBlock) ] @@ -83,14 +83,14 @@ PMSimplexOptimizer >> evaluateIteration [ into: [:sum :each | each position + sum]) * (1 / bestPoints size). newPoint := optimizingPointClass vector: 2 * centerOfGravity - worstVector function: functionBlock. - (newPoint betterThan: bestPoints first) - ifTrue: - [nextPoint := optimizingPointClass + (newPoint betterThan: bestPoints first) + ifTrue: + [nextPoint := optimizingPointClass vector: newPoint position * 2 - centerOfGravity function: functionBlock. (nextPoint betterThan: newPoint) ifTrue: [newPoint := nextPoint]] - ifFalse: - [newPoint := optimizingPointClass + ifFalse: + [newPoint := optimizingPointClass vector: centerOfGravity * 0.666667 + (worstVector * 0.333333) function: functionBlock. (newPoint betterThan: bestPoints first) ifFalse: [^self contract]]. @@ -103,6 +103,6 @@ PMSimplexOptimizer >> evaluateIteration [ { #category : #display } PMSimplexOptimizer >> printOn: aStream [ super printOn: aStream. - aStream cr. + aStream cr. worstVector printOn: aStream ] diff --git a/src/Math-Numerical/PMSplineInterpolator.class.st b/src/Math-Numerical/PMSplineInterpolator.class.st index bd4498c8c..04785401d 100644 --- a/src/Math-Numerical/PMSplineInterpolator.class.st +++ b/src/Math-Numerical/PMSplineInterpolator.class.st @@ -15,52 +15,38 @@ PMSplineInterpolator >> computeSecondDerivatives [ size := pointCollection size. coefficients := Array new: size. u := Array new: size - 1. - startPointDerivative isNil - ifTrue: - [coefficients at: 1 put: 0. - u at: 1 put: 0] - ifFalse: - [coefficients at: 1 put: -1 / 2. - s := 1 / (( self xPointAt: 2) - ( self xPointAt: 1)). - u at: 1 - put: 3 * s - * (s * (( self yPointAt: size) - ( self yPointAt: size - 1)) - - startPointDerivative)]. - 2 to: size - 1 - do: - [:n | - dx := (self xPointAt: n) - (self xPointAt: ( n - 1)). - inv2dx := 1 / (( self xPointAt: n + 1) - (self xPointAt: n - 1)). - s := dx * inv2dx. - w := 1 / (s * (coefficients at: n - 1) + 2). - coefficients at: n put: (s - 1) * w. - u at: n - put: (((( self yPointAt: n + 1) - ( self yPointAt: n)) - / (( self xPointAt: n + 1) - ( self xPointAt: n)) - - ((( self yPointAt: n) - ( self yPointAt: n - 1)) / dx)) * 6 - * inv2dx - ((u at: n - 1) * s)) - * w]. - endPointDerivative isNil - ifTrue: [coefficients at: size put: 0] - ifFalse: - [w := 1 / 2. - s := 1 / ((self xPointAt: size) - (self xPointAt: ( size - 1))). - u at: 1 - put: 3 * s * (endPointDerivative - - (s * (self yPointAt: size) - (self yPointAt: size - 1))). - coefficients at: size - put: s - (w * (u at: size - 1) / ((coefficients at: size - 1) * w + 1))]. - size - 1 to: 1 - by: -1 - do: - [:n | - coefficients at: n - put: (coefficients at: n) * (coefficients at: n + 1) + (u at: n)] + startPointDerivative + ifNil: [ + coefficients at: 1 put: 0. + u at: 1 put: 0 ] + ifNotNil: [ + coefficients at: 1 put: -1 / 2. + s := 1 / ((self xPointAt: 2) - (self xPointAt: 1)). + u at: 1 put: 3 * s * (s * ((self yPointAt: size) - (self yPointAt: size - 1)) - startPointDerivative) ]. + 2 to: size - 1 do: [ :n | + dx := (self xPointAt: n) - (self xPointAt: n - 1). + inv2dx := 1 / ((self xPointAt: n + 1) - (self xPointAt: n - 1)). + s := dx * inv2dx. + w := 1 / (s * (coefficients at: n - 1) + 2). + coefficients at: n put: s - 1 * w. + u + at: n + put: + (self yPointAt: n + 1) - (self yPointAt: n) / ((self xPointAt: n + 1) - (self xPointAt: n)) - ((self yPointAt: n) - (self yPointAt: n - 1) / dx) * 6 + * inv2dx - ((u at: n - 1) * s) * w ]. + endPointDerivative + ifNil: [ coefficients at: size put: 0 ] + ifNotNil: [ + w := 1 / 2. + s := 1 / ((self xPointAt: size) - (self xPointAt: size - 1)). + u at: 1 put: 3 * s * (endPointDerivative - (s * (self yPointAt: size) - (self yPointAt: size - 1))). + coefficients at: size put: s - (w * (u at: size - 1) / ((coefficients at: size - 1) * w + 1)) ]. + size - 1 to: 1 by: -1 do: [ :n | coefficients at: n put: (coefficients at: n) * (coefficients at: n + 1) + (u at: n) ] ] { #category : #information } PMSplineInterpolator >> defaultSamplePoints [ - + ^SortedCollection sortBlock: [ :a :b | a x < b x] ] @@ -68,13 +54,13 @@ PMSplineInterpolator >> defaultSamplePoints [ PMSplineInterpolator >> endPointDerivative: aNumber [ "Defines the end point derivatives." endPointDerivative := aNumber. - self resetCoefficients. + self resetCoefficients ] { #category : #information } PMSplineInterpolator >> resetEndPointDerivatives [ "Set the end point derivatives to undefined." - self setEndPointDerivatives: ( Array new: 2). + self setEndPointDerivatives: ( Array new: 2) ] { #category : #information } @@ -82,32 +68,32 @@ PMSplineInterpolator >> setEndPointDerivatives: anArray [ "Defines the end point derivatives." startPointDerivative := anArray at: 1. endPointDerivative := anArray at: 2. - self resetCoefficients. + self resetCoefficients ] { #category : #information } PMSplineInterpolator >> startPointDerivative: aNumber [ "Defines the end point derivatives." startPointDerivative := aNumber. - self resetCoefficients. + self resetCoefficients ] { #category : #information } -PMSplineInterpolator >> value: aNumber [ +PMSplineInterpolator >> value: aNumber [ "Computes the value of a cubic spline interpolation over the points of the receiver." | n1 n2 n step a b | - coefficients isNil ifTrue: [self computeSecondDerivatives]. + coefficients ifNil: [ self computeSecondDerivatives ]. n2 := pointCollection size. n1 := 1. - [n2 - n1 > 1] whileTrue: - [n := (n1 + n2) // 2. - (self xPointAt: n) > aNumber ifTrue: [n2 := n] ifFalse: [n1 := n]]. + [ n2 - n1 > 1 ] whileTrue: [ + n := n1 + n2 // 2. + (self xPointAt: n) > aNumber + ifTrue: [ n2 := n ] + ifFalse: [ n1 := n ] ]. step := (self xPointAt: n2) - (self xPointAt: n1). - a := ((self xPointAt: n2) - aNumber) / step. - b := (aNumber - (self xPointAt: n1)) / step. - ^a * (self yPointAt: n1) + (b * (self yPointAt: n2)) - + ((a * (a squared - 1) * (coefficients at: n1) - + (b * (b squared - 1) * (coefficients at: n2))) * step squared - / 6) + a := (self xPointAt: n2) - aNumber / step. + b := aNumber - (self xPointAt: n1) / step. + ^ a * (self yPointAt: n1) + (b * (self yPointAt: n2)) + + (a * (a squared - 1) * (coefficients at: n1) + (b * (b squared - 1) * (coefficients at: n2)) * step squared / 6) ] diff --git a/src/Math-Numerical/PMVectorProjectedFunction.class.st b/src/Math-Numerical/PMVectorProjectedFunction.class.st index bd632efcf..8f0cf6794 100644 --- a/src/Math-Numerical/PMVectorProjectedFunction.class.st +++ b/src/Math-Numerical/PMVectorProjectedFunction.class.st @@ -17,7 +17,7 @@ PMVectorProjectedFunction >> direction [ { #category : #initialization } PMVectorProjectedFunction >> direction: aVector [ - index := aVector. + index := aVector ] { #category : #information } @@ -27,7 +27,7 @@ PMVectorProjectedFunction >> origin [ { #category : #initialization } PMVectorProjectedFunction >> origin: aVector [ - argument := aVector. + argument := aVector ] { #category : #display } @@ -35,5 +35,5 @@ PMVectorProjectedFunction >> printOn: aStream [ self origin printOn: aStream. aStream nextPutAll: ' ('. self direction printOn: aStream. - aStream nextPut: $). + aStream nextPut: $) ] diff --git a/src/Math-ODE/PMAB2Solver.class.st b/src/Math-ODE/PMAB2Solver.class.st index 03b9f322c..b91212ac5 100644 --- a/src/Math-ODE/PMAB2Solver.class.st +++ b/src/Math-ODE/PMAB2Solver.class.st @@ -8,27 +8,27 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAB2Solver class >> firstStepperClass [ ^ PMMidpointStepper ] -{ #category : #'as yet unclassified' } +{ #category : #private } PMAB2Solver class >> stepperClass [ ^ PMAB2Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAB2Solver >> firstStepStartTime: t [ - state := stepper doStep: state time: t stepSize: self dt. + state := stepper doStep: state time: t stepSize: self dt. self announceState: state time: t + self dt. lastTime := t + self dt. ^ state ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAB2Solver >> firstStepperClass [ - ^ self class firstStepperClass + ^ self class firstStepperClass ] { #category : #solving } @@ -36,38 +36,38 @@ PMAB2Solver >> lastStepPrevState: prevState endTime: endTime [ "catch partial or full step at end" (lastTime closeTo: endTime ) ifFalse: - [state := stepper - lastStep: state + [state := stepper + lastStep: state prevState: prevState - time: lastTime + time: lastTime stepSize: endTime - lastTime deltaT: dt. - self announceState: state time: endTime]. + self announceState: state time: endTime]. ^ state ] { #category : #'as yet unclassified' } PMAB2Solver >> mainStepsPrevState: prevState startTime: initialTime endTime: endTime [ |previousState| - previousState := prevState. + previousState := prevState. "don't go to end time to avoid overrunning" (initialTime to: endTime - self dt by: self dt) do: [:time | | tempState| tempState := state. state := stepper - doStep: state + doStep: state prevState: previousState - time: time + time: time stepSize: self dt. previousState := tempState. "announce step results" self announceState: state time: time + self dt. lastTime := time + self dt]. - + ^ Array with: previousState with: state ] -{ #category : #'as yet unclassified' } +{ #category : #solving } PMAB2Solver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime [ |prevState statesPair| self system: aSystem. @@ -77,30 +77,30 @@ PMAB2Solver >> solve: aSystem startState: initialState startTime: initialTime en "announce initial conditions" self announceState: state time: initialTime. - + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ state :=self lastStepState: state endTime: endTime]. - - lastTime+dt<= endTime + + lastTime+dt<= endTime ifTrue:[ prevState:= initialState. - + state := self firstStepStartTime: initialTime. "announce first step" self announceState: state time: (initialTime + dt). - + self stepper: ((self stepperClass) onSystem: self system). - + "step until the end" statesPair := self mainStepsPrevState: prevState startTime: ( initialTime + dt) endTime: endTime. state:=statesPair second. prevState:= statesPair first. - + "sanity check" - self assert: [(lastTime between: initialTime and: endTime) + self assert: [(lastTime between: initialTime and: endTime) or: [lastTime between: endTime and: initialTime]]. - + "take another step if needed" state := self lastStepPrevState: prevState endTime: endTime.]. diff --git a/src/Math-ODE/PMAB2Stepper.class.st b/src/Math-ODE/PMAB2Stepper.class.st index 673e679e4..081fee4da 100644 --- a/src/Math-ODE/PMAB2Stepper.class.st +++ b/src/Math-ODE/PMAB2Stepper.class.st @@ -7,7 +7,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAB2Stepper class >> order [ "AB2 is a second order method." ^ 2 @@ -25,7 +25,7 @@ PMAB2Stepper >> doStep: aState prevState: prevState time: t [ PMAB2Stepper >> doStep: aState prevState: prevState time: t stepSize: timeStep [ self stepSize: timeStep. - ^ self doStep: aState prevState: prevState time: t . + ^ self doStep: aState prevState: prevState time: t ] { #category : #stepping } @@ -41,5 +41,5 @@ PMAB2Stepper >> lastStep: aState prevState: prevState time: t deltaT: incrementO PMAB2Stepper >> lastStep: aState prevState: prevState time: t stepSize: timeStep deltaT: incrementOfTime [ self stepSize: timeStep. - ^ self lastStep: aState prevState: prevState time: t deltaT: incrementOfTime . + ^ self lastStep: aState prevState: prevState time: t deltaT: incrementOfTime ] diff --git a/src/Math-ODE/PMAB3Solver.class.st b/src/Math-ODE/PMAB3Solver.class.st index b8032f514..97a055632 100644 --- a/src/Math-ODE/PMAB3Solver.class.st +++ b/src/Math-ODE/PMAB3Solver.class.st @@ -13,31 +13,31 @@ PMAB3Solver class >> secondStepperClass [ ^ PMAB2Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #private } PMAB3Solver class >> stepperClass [ ^ PMAB3Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAB3Solver >> lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime [ "catch partial or full step at end" (lastTime closeTo: endTime ) ifFalse: - [state := stepper - lastStep: state + [state := stepper + lastStep: state prevState: prevState prevPrevState: prevPrevState - prevPrevTime: lastTime-(2*dt) + prevPrevTime: lastTime-(2*dt) stepSize: endTime - lastTime deltaT: dt. - self announceState: state time: endTime]. + self announceState: state time: endTime]. ^ state ] { #category : #'as yet unclassified' } PMAB3Solver >> mainStepsPrevState: prevState prevPrevState: prevPrevState startTime: initialTime endTime: endTime [ |previousState previousPrevState | - previousState := prevState. + previousState := prevState. previousPrevState:=prevPrevState. "don't go to end time to avoid overrunning" (initialTime to: endTime - (3*self dt) by: self dt) do: @@ -45,19 +45,18 @@ PMAB3Solver >> mainStepsPrevState: prevState prevPrevState: prevPrevState startT tempState1 := state. tempState2:=previousState. state := stepper - doStep: state + doStep: state prevState: previousState prevPrevState: previousPrevState - prevPrevTime: time + prevPrevTime: time stepSize: self dt. - previousPrevState:=tempState2. + previousPrevState:=tempState2. previousState := tempState1. "announce step results" self announceState: state time: time + self dt. lastTime := time + (3*self dt)]. - + ^ Array with: previousPrevState with: previousState - ] { #category : #'as yet unclassified' } @@ -71,10 +70,10 @@ PMAB3Solver >> secondStepPrevState: prevState startTime: t [ { #category : #'as yet unclassified' } PMAB3Solver >> secondStepperClass [ - ^ self class secondStepperClass + ^ self class secondStepperClass ] -{ #category : #'as yet unclassified' } +{ #category : #solving } PMAB3Solver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime [ |prevState prevPrevState statesPair | self system: aSystem. @@ -83,53 +82,53 @@ PMAB3Solver >> solve: aSystem startState: initialState startTime: initialTime en lastTime:=initialTime. "announce initial conditions" self announceState: state time: initialTime. - + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ state :=self lastStepState: state endTime: endTime]. - - lastTime+dt<= endTime + + lastTime+dt<= endTime ifTrue:[ prevState:= initialState. state := self firstStepStartTime: initialTime. "announce first step" - self announceState: state time:lastTime. - + self announceState: state time:lastTime. + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ self stepper: ((self secondStepperClass) onSystem: self system). state :=self lastStepPrevState: prevState endTime: endTime]. - - lastTime+dt<= endTime + + lastTime+dt<= endTime ifTrue:[ prevPrevState := prevState. prevState := state. self stepper: ((self secondStepperClass) onSystem: self system). - state := self secondStepPrevState: prevPrevState startTime: lastTime. + state := self secondStepPrevState: prevPrevState startTime: lastTime. "announce second step" - self announceState: state time: lastTime. - + self announceState: state time: lastTime. + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ self stepper: ((self stepperClass) onSystem: self system). state := self lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime]. - - lastTime+dt<= endTime + + lastTime+dt<= endTime ifTrue:[ self stepper: ((self stepperClass) onSystem: self system). - "step until the end" - + "step until the end" + statesPair := self mainStepsPrevState: prevState prevPrevState: prevPrevState startTime: initialTime endTime: endTime. prevPrevState:=statesPair first. prevState:= statesPair second. - + "sanity check" - self assert: [(lastTime between: initialTime and: endTime) + self assert: [(lastTime between: initialTime and: endTime) or: [lastTime between: endTime and: initialTime]]. - - "take another step if needed" + + "take another step if needed" state := self lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime]]]. - - ^ state + + ^ state ] diff --git a/src/Math-ODE/PMAB3Stepper.class.st b/src/Math-ODE/PMAB3Stepper.class.st index 134019c96..eac0d4fa9 100644 --- a/src/Math-ODE/PMAB3Stepper.class.st +++ b/src/Math-ODE/PMAB3Stepper.class.st @@ -8,7 +8,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAB3Stepper class >> order [ "AB3 is a third order method." ^ 3 @@ -31,7 +31,7 @@ PMAB3Stepper >> doStep: thisState prevState: prevState prevPrevState: prevPrevSt { #category : #stepping } PMAB3Stepper >> doStep: thisState prevState: prevState prevPrevState: prevPrevState prevPrevTime: prevPrevTime stepSize: timeStep [ self stepSize: timeStep. - ^ self doStep: thisState prevState: prevState prevPrevState: prevPrevState prevPrevTime: prevPrevTime . + ^ self doStep: thisState prevState: prevState prevPrevState: prevPrevState prevPrevTime: prevPrevTime ] { #category : #stepping } @@ -52,5 +52,5 @@ PMAB3Stepper >> lastStep: thisState prevState: prevState prevPrevState: prevPrev { #category : #stepping } PMAB3Stepper >> lastStep: thisState prevState: prevState prevPrevState: prevPrevState prevPrevTime: prevPrevTime stepSize: timeStep deltaT: incrementOfTime [ self stepSize: timeStep. - ^ self lastStep: thisState prevState: prevState prevPrevState: prevPrevState prevPrevTime: prevPrevTime deltaT: incrementOfTime . + ^ self lastStep: thisState prevState: prevState prevPrevState: prevPrevState prevPrevTime: prevPrevTime deltaT: incrementOfTime ] diff --git a/src/Math-ODE/PMAB4Solver.class.st b/src/Math-ODE/PMAB4Solver.class.st index 72d1afa12..a397d8a41 100644 --- a/src/Math-ODE/PMAB4Solver.class.st +++ b/src/Math-ODE/PMAB4Solver.class.st @@ -8,7 +8,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #private } PMAB4Solver class >> stepperClass [ ^ PMAB4Stepper ] @@ -18,20 +18,20 @@ PMAB4Solver class >> thirdStepperClass [ ^ PMAB3Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAB4Solver >> lastStepPrevState: prevState prevPrevState: prevPrevState initState:initState endTime: endTime [ "catch partial or full step at end" (lastTime closeTo: endTime ) ifFalse: - [state := stepper - lastStep: state + [state := stepper + lastStep: state secondState: prevState firstState: prevPrevState initState: initState - initTime: lastTime-(3*dt) - deltaT: dt + initTime: lastTime-(3*dt) + deltaT: dt stepSize: endTime - lastTime. - self announceState: state time: endTime]. + self announceState: state time: endTime]. ^ state ] @@ -39,7 +39,7 @@ PMAB4Solver >> lastStepPrevState: prevState prevPrevState: prevPrevState initSta PMAB4Solver >> mainStepsPrevState: prevState prevPrevState: prevPrevState initState: initState startTime: initialTime endTime: endTime [ |previousState previousPrevState initialState | - previousState := prevState. + previousState := prevState. previousPrevState:=prevPrevState. initialState:=initState. "don't go to end time to avoid overrunning" @@ -50,23 +50,23 @@ PMAB4Solver >> mainStepsPrevState: prevState prevPrevState: prevPrevState initSt tempState2:=previousState. tempState3:=previousPrevState. state := stepper - doStep3State: state + doStep3State: state secondState: previousState firstState: previousPrevState - initState: initState - initTime: time + initState: initState + initTime: time stepSize: self dt. initialState:=tempState3. - previousPrevState:=tempState2. + previousPrevState:=tempState2. previousState := tempState1. "announce step results" self announceState: state time: time + self dt. lastTime := time + (4*self dt)]. - + ^ Array with: initialState with: previousPrevState with: previousState ] -{ #category : #'as yet unclassified' } +{ #category : #solving } PMAB4Solver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime [ | prevState prevPrevState statesPair initState | self system: aSystem. @@ -75,66 +75,66 @@ PMAB4Solver >> solve: aSystem startState: initialState startTime: initialTime en lastTime := initialTime. "announce initial conditions" self announceState: state time: initialTime. - + (lastTime + dt > endTime and: lastTime < endTime) ifTrue: [ state := self lastStepState: state endTime: endTime ]. - + lastTime + dt <= endTime - ifTrue: [ + ifTrue: [ prevState := initialState. - state := self firstStepStartTime: initialTime. + state := self firstStepStartTime: initialTime. "announce first step" self announceState: state time: lastTime. - + (lastTime + dt > endTime and: lastTime < endTime) - ifTrue: [ + ifTrue: [ self stepper: (self secondStepperClass onSystem: self system). state := self lastStepPrevState: prevState endTime: endTime ]. - + lastTime + dt <= endTime - ifTrue: [ + ifTrue: [ prevPrevState := prevState. prevState := state. self stepper: (self secondStepperClass onSystem: self system). - state := self secondStepPrevState: prevPrevState startTime: lastTime. + state := self secondStepPrevState: prevPrevState startTime: lastTime. "announce second step" self announceState: state time: lastTime. - + (lastTime + dt > endTime and: lastTime < endTime) ifTrue: [ self stepper: (self thirdStepperClass onSystem: self system). state := self lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime ]. - + lastTime + dt <= endTime - ifTrue: [ + ifTrue: [ self stepper: (self thirdStepperClass onSystem: self system). initState := prevPrevState. prevPrevState := prevState. - prevState := state. + prevState := state. state := self thirdStepPrevState: prevPrevState prevPrevState: initState startTime: lastTime. - + "announce third step" self announceState: state time: lastTime. - + (lastTime + dt > endTime and: lastTime < endTime) - ifTrue: [ - self stepper: (self stepperClass onSystem: self system). + ifTrue: [ + self stepper: (self stepperClass onSystem: self system). state := self lastStepPrevState: prevState prevPrevState: prevPrevState initState: initState endTime: endTime ]. - + lastTime + dt <= endTime - ifTrue: [ - self stepper: (self stepperClass onSystem: self system). + ifTrue: [ + self stepper: (self stepperClass onSystem: self system). "step until the end" - + statesPair := self mainStepsPrevState: prevState prevPrevState: prevPrevState @@ -144,12 +144,12 @@ PMAB4Solver >> solve: aSystem startState: initialState startTime: initialTime en initState:=statesPair first. prevPrevState:=statesPair second. prevState:= statesPair third. - + "sanity check" self - assert: [ (lastTime between: initialTime and: endTime) or: [ lastTime between: endTime and: initialTime ] ]. - - + assert: [ (lastTime between: initialTime and: endTime) or: [ lastTime between: endTime and: initialTime ] ]. + + "take another step if needed" state := self lastStepPrevState: prevState @@ -161,10 +161,10 @@ PMAB4Solver >> solve: aSystem startState: initialState startTime: initialTime en { #category : #'as yet unclassified' } PMAB4Solver >> thirdStepPrevState: prevState prevPrevState: prevPrevState startTime: t [ - state := stepper doStep: state - prevState: prevState - prevPrevState: prevPrevState - prevPrevTime: t-(2*self dt) + state := stepper doStep: state + prevState: prevState + prevPrevState: prevPrevState + prevPrevTime: t-(2*self dt) stepSize: self dt. self announceState: state time: t + self dt. lastTime := t + self dt. @@ -173,5 +173,5 @@ PMAB4Solver >> thirdStepPrevState: prevState prevPrevState: prevPrevState start { #category : #'as yet unclassified' } PMAB4Solver >> thirdStepperClass [ - ^ self class thirdStepperClass + ^ self class thirdStepperClass ] diff --git a/src/Math-ODE/PMAB4Stepper.class.st b/src/Math-ODE/PMAB4Stepper.class.st index d9ea2002d..2ca0537ef 100644 --- a/src/Math-ODE/PMAB4Stepper.class.st +++ b/src/Math-ODE/PMAB4Stepper.class.st @@ -8,7 +8,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAB4Stepper class >> order [ "AB4 is a fourth order method." ^ 4 @@ -32,7 +32,7 @@ PMAB4Stepper >> doStep3State: thirdState secondState: secondState firstState: fi { #category : #stepping } PMAB4Stepper >> doStep3State: thirdState secondState:secondState firstState: firstState initState: initState initTime: initTime stepSize: timeStep [ self stepSize: timeStep. - ^ self doStep3State: thirdState secondState:secondState firstState: firstState initState: initState initTime: initTime . + ^ self doStep3State: thirdState secondState:secondState firstState: firstState initState: initState initTime: initTime ] { #category : #stepping } @@ -57,6 +57,5 @@ PMAB4Stepper >> lastStep: thirdState secondState: secondState firstState: firstS PMAB4Stepper >> lastStep: thirdState secondState:secondState firstState: firstState initState: initState initTime: initTime deltaT: incrementOfTime stepSize: timeStep [ self stepSize: timeStep. - ^ self lastStep: thirdState secondState:secondState firstState: firstState initState: initState initTime: initTime deltaT: incrementOfTime . - + ^ self lastStep: thirdState secondState:secondState firstState: firstState initState: initState initTime: initTime deltaT: incrementOfTime ] diff --git a/src/Math-ODE/PMAM3Solver.class.st b/src/Math-ODE/PMAM3Solver.class.st index 795bff776..cd0ae9aba 100644 --- a/src/Math-ODE/PMAM3Solver.class.st +++ b/src/Math-ODE/PMAM3Solver.class.st @@ -8,54 +8,54 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAM3Solver class >> firstStepperClass [ ^ PMTrapezoidStepper ] -{ #category : #'as yet unclassified' } +{ #category : #private } PMAM3Solver class >> stepperClass [ ^ PMAM3Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAM3Solver >> firstStepStartTime: t [ - state := stepper doStep: state time: t stepSize: self dt. + state := stepper doStep: state time: t stepSize: self dt. self announceState: state time: t + self dt. lastTime := t + self dt. ^ state ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAM3Solver >> firstStepperClass [ ^ self class firstStepperClass ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAM3Solver >> lastStepPrevState: prevState endTime: endTime [ "catch partial or full step at end" (lastTime closeTo: endTime ) ifFalse: - [state := stepper - lastStep: state + [state := stepper + lastStep: state prevState: prevState - time: lastTime + time: lastTime deltaT: dt stepSize: endTime - lastTime. - self announceState: state time: endTime]. + self announceState: state time: endTime]. ^ state ] { #category : #'as yet unclassified' } PMAM3Solver >> mainStepsPrevState: prevState startTime: initialTime endTime: endTime [ |previousState| - previousState := prevState. + previousState := prevState. "don't go to end time to avoid overrunning" (initialTime to: endTime - self dt by: self dt) do: [:time | | tempState| tempState := state. state := stepper - doStep: state + doStep: state prevState: previousState time: time -self dt stepSize: self dt. @@ -63,11 +63,11 @@ PMAM3Solver >> mainStepsPrevState: prevState startTime: initialTime endTime: end "announce step results" self announceState: state time: time + self dt. lastTime := time + self dt]. - + ^ Array with: previousState with: state ] -{ #category : #'as yet unclassified' } +{ #category : #solving } PMAM3Solver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime [ |prevState statesPair| self system: aSystem. @@ -77,28 +77,28 @@ PMAM3Solver >> solve: aSystem startState: initialState startTime: initialTime en "announce initial conditions" self announceState: state time: initialTime. - + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ state :=self lastStepState: state endTime: endTime]. - - lastTime+dt<= endTime - ifTrue:[ + + lastTime+dt<= endTime + ifTrue:[ prevState:= initialState. state := self firstStepStartTime: initialTime. "announce first step" self announceState: state time: initialTime + dt. - + self stepper: ((self stepperClass) onSystem: self system). - + "step until the end" statesPair := self mainStepsPrevState: prevState startTime: lastTime endTime: endTime. - - + + "sanity check" - self assert: [(lastTime between: initialTime and: endTime) + self assert: [(lastTime between: initialTime and: endTime) or: [lastTime between: endTime and: initialTime]]. - + "take another step if needed" prevState:= statesPair first. state := self lastStepPrevState: prevState endTime: endTime.]. diff --git a/src/Math-ODE/PMAM3Stepper.class.st b/src/Math-ODE/PMAM3Stepper.class.st index 306157717..a4c976185 100644 --- a/src/Math-ODE/PMAM3Stepper.class.st +++ b/src/Math-ODE/PMAM3Stepper.class.st @@ -9,7 +9,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAM3Stepper class >> order [ "AM3 is a third order method." ^ 3 diff --git a/src/Math-ODE/PMAM4Solver.class.st b/src/Math-ODE/PMAM4Solver.class.st index 27a88fdf9..203e6b826 100644 --- a/src/Math-ODE/PMAM4Solver.class.st +++ b/src/Math-ODE/PMAM4Solver.class.st @@ -13,48 +13,48 @@ PMAM4Solver class >> secondStepperClass [ ^ PMAM3Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #private } PMAM4Solver class >> stepperClass [ ^ PMAM4Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAM4Solver >> lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime [ "catch partial or full step at end" (lastTime closeTo: endTime ) ifFalse: - [state := stepper - lastStep: state + [state := stepper + lastStep: state prevState: prevState prevPrevState: prevPrevState time: lastTime - deltaT: dt + deltaT: dt stepSize: endTime - lastTime. - self announceState: state time: endTime]. + self announceState: state time: endTime]. ^ state ] { #category : #'as yet unclassified' } PMAM4Solver >> mainStepsPrevState: prevState prevPrevState: prevPrevState startTime: initialTime endTime: endTime [ |previousState previousPrevState | - previousState := prevState. + previousState := prevState. previousPrevState:=prevPrevState. "don't go to end time to avoid overrunning" - (lastTime to: endTime - self dt by: self dt) do: + (lastTime to: endTime - self dt by: self dt) do: [:time | | tempState1 tempState2| tempState1 := state. tempState2:=previousState. state := stepper - doStep: state + doStep: state prevState: previousState prevPrevState: previousPrevState - time: time + time: time stepSize: self dt. - previousPrevState:=tempState2. + previousPrevState:=tempState2. previousState := tempState1. "announce step results" self announceState: state time: time + self dt. - lastTime := time + self dt]. + lastTime := time + self dt]. ^ Array with: previousPrevState with: previousState ] @@ -69,10 +69,10 @@ PMAM4Solver >> secondStepPrevState: prevState startTime: t [ { #category : #'as yet unclassified' } PMAM4Solver >> secondStepperClass [ - ^ self class secondStepperClass + ^ self class secondStepperClass ] -{ #category : #'as yet unclassified' } +{ #category : #solving } PMAM4Solver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime [ |prevState prevPrevState statesPair | self system: aSystem. @@ -81,53 +81,53 @@ PMAM4Solver >> solve: aSystem startState: initialState startTime: initialTime en lastTime:=initialTime. "announce initial conditions" self announceState: state time: initialTime. - + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ state :=self lastStepState: state endTime: endTime]. - - lastTime+dt<= endTime + + lastTime+dt<= endTime ifTrue:[ prevState:= initialState. state := self firstStepStartTime: initialTime. "announce first step" - self announceState: state time:lastTime. - + self announceState: state time:lastTime. + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ self stepper: ((self secondStepperClass) onSystem: self system). state :=self lastStepPrevState: prevState endTime: endTime]. - - lastTime+dt<= endTime + + lastTime+dt<= endTime ifTrue:[ prevPrevState := prevState. prevState := state. self stepper: ((self secondStepperClass) onSystem: self system). - state := self secondStepPrevState: prevPrevState startTime: lastTime. + state := self secondStepPrevState: prevPrevState startTime: lastTime. "announce second step" - self announceState: state time: lastTime. - + self announceState: state time: lastTime. + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ self stepper: ((self stepperClass) onSystem: self system). state := self lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime]. - - lastTime+dt<= endTime + + lastTime+dt<= endTime ifTrue:[ self stepper: ((self stepperClass) onSystem: self system). - "step until the end" - + "step until the end" + statesPair := self mainStepsPrevState: prevState prevPrevState: prevPrevState startTime: initialTime endTime: endTime. prevPrevState:=statesPair first. prevState:= statesPair second. - + "sanity check" - self assert: [(lastTime between: initialTime and: endTime) + self assert: [(lastTime between: initialTime and: endTime) or: [lastTime between: endTime and: initialTime]]. - - "take another step if needed" + + "take another step if needed" state := self lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime]]]. - - ^ state + + ^ state ] diff --git a/src/Math-ODE/PMAM4Stepper.class.st b/src/Math-ODE/PMAM4Stepper.class.st index cb18424e3..5f3fe6e00 100644 --- a/src/Math-ODE/PMAM4Stepper.class.st +++ b/src/Math-ODE/PMAM4Stepper.class.st @@ -9,7 +9,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMAM4Stepper class >> order [ "AM4 is a fourth order method." ^ 4 diff --git a/src/Math-ODE/PMBDF2Solver.class.st b/src/Math-ODE/PMBDF2Solver.class.st index d2b478e40..ae4790c9a 100644 --- a/src/Math-ODE/PMBDF2Solver.class.st +++ b/src/Math-ODE/PMBDF2Solver.class.st @@ -8,41 +8,41 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMBDF2Solver class >> firstStepperClass [ ^ PMImplicitStepper ] -{ #category : #'as yet unclassified' } +{ #category : #private } PMBDF2Solver class >> stepperClass [ ^ PMBDF2Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMBDF2Solver >> firstStepStartTime: t [ - state := stepper doStep: state time: t stepSize: self dt. + state := stepper doStep: state time: t stepSize: self dt. self announceState: state time: t + self dt. lastTime := t + self dt. ^ state ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMBDF2Solver >> firstStepperClass [ ^ self class firstStepperClass ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMBDF2Solver >> lastStepPrevState: prevState endTime: endTime [ "catch partial or full step at end" (lastTime closeTo: endTime ) ifFalse: - [state := stepper - doStep: state + [state := stepper + doStep: state prevState: prevState - time: lastTime + time: lastTime stepSize: endTime - lastTime. - self announceState: state time: endTime]. + self announceState: state time: endTime]. ^ state ] @@ -50,25 +50,25 @@ PMBDF2Solver >> lastStepPrevState: prevState endTime: endTime [ PMBDF2Solver >> mainStepsPrevState: prevState startTime: initialTime endTime: endTime [ |previousState| - previousState := prevState. + previousState := prevState. "don't go to end time to avoid overrunning" (initialTime to: endTime - self dt by: self dt) do: [:time | | tempState| tempState := state. state := stepper - doStep: state + doStep: state prevState: previousState - time: time + time: time stepSize: self dt. previousState := tempState. "announce step results" self announceState: state time: time + self dt. lastTime := time + self dt]. - + ^ Array with: previousState with: state ] -{ #category : #'as yet unclassified' } +{ #category : #solving } PMBDF2Solver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime [ |prevState statesPair| self system: aSystem. @@ -78,29 +78,29 @@ PMBDF2Solver >> solve: aSystem startState: initialState startTime: initialTime e "announce initial conditions" self announceState: state time: initialTime. - + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ state :=self lastStepState: state endTime: endTime]. - - lastTime+dt<= endTime - ifTrue:[ + + lastTime+dt<= endTime + ifTrue:[ prevState:= initialState. state := self firstStepStartTime: initialTime. "announce first step" self announceState: state time: initialTime + dt. - + self stepper: ((self stepperClass) onSystem: self system). - + "step until the end" statesPair := self mainStepsPrevState: prevState startTime: lastTime endTime: endTime. state:=statesPair second. prevState:= statesPair first . - + "sanity check" - self assert: [(lastTime between: initialTime and: endTime) + self assert: [(lastTime between: initialTime and: endTime) or: [lastTime between: endTime and: initialTime]]. - + "take another step if needed" state := self lastStepPrevState: prevState endTime: endTime.]. diff --git a/src/Math-ODE/PMBDF2Stepper.class.st b/src/Math-ODE/PMBDF2Stepper.class.st index 6410dc0d2..c0e6a86a2 100644 --- a/src/Math-ODE/PMBDF2Stepper.class.st +++ b/src/Math-ODE/PMBDF2Stepper.class.st @@ -10,7 +10,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMBDF2Stepper class >> order [ "BDF2 is a second order method." ^ 2 diff --git a/src/Math-ODE/PMBDF3Solver.class.st b/src/Math-ODE/PMBDF3Solver.class.st index 584ff47b6..6ce031cbb 100644 --- a/src/Math-ODE/PMBDF3Solver.class.st +++ b/src/Math-ODE/PMBDF3Solver.class.st @@ -13,47 +13,47 @@ PMBDF3Solver class >> secondStepperClass [ ^ PMBDF2Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #private } PMBDF3Solver class >> stepperClass [ ^ PMBDF3Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMBDF3Solver >> lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime [ "catch partial or full step at end" (lastTime closeTo: endTime ) ifFalse: - [state := stepper - doStep: state + [state := stepper + doStep: state prevState: prevState prevPrevState: prevPrevState time: lastTime stepSize: endTime - lastTime. - self announceState: state time: endTime]. + self announceState: state time: endTime]. ^ state ] { #category : #'as yet unclassified' } PMBDF3Solver >> mainStepsPrevState: prevState prevPrevState: prevPrevState startTime: initialTime endTime: endTime [ |previousState previousPrevState | - previousState := prevState. + previousState := prevState. previousPrevState:=prevPrevState. "don't go to end time to avoid overrunning" - (lastTime to: endTime - self dt by: self dt) do: + (lastTime to: endTime - self dt by: self dt) do: [:time | | tempState1 tempState2| tempState1 := state. tempState2:=previousState. state := stepper - doStep: state + doStep: state prevState: previousState prevPrevState: previousPrevState - time: time + time: time stepSize: self dt. - previousPrevState:=tempState2. + previousPrevState:=tempState2. previousState := tempState1. "announce step results" self announceState: state time: time + self dt. - lastTime := time + self dt]. + lastTime := time + self dt]. ^ Array with: previousPrevState with: previousState ] @@ -68,10 +68,10 @@ PMBDF3Solver >> secondStepPrevState: prevState startTime: t [ { #category : #'as yet unclassified' } PMBDF3Solver >> secondStepperClass [ - ^ self class secondStepperClass + ^ self class secondStepperClass ] -{ #category : #'as yet unclassified' } +{ #category : #solving } PMBDF3Solver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime [ |prevState prevPrevState statesPair | self system: aSystem. @@ -80,53 +80,53 @@ PMBDF3Solver >> solve: aSystem startState: initialState startTime: initialTime e lastTime:=initialTime. "announce initial conditions" self announceState: state time: initialTime. - + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ state :=self lastStepState: state endTime: endTime]. - - lastTime+dt<= endTime + + lastTime+dt<= endTime ifTrue:[ prevState:= initialState. state := self firstStepStartTime: initialTime. "announce first step" - self announceState: state time:lastTime. - + self announceState: state time:lastTime. + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ self stepper: ((self secondStepperClass) onSystem: self system). state :=self lastStepPrevState: prevState endTime: endTime]. - - lastTime+dt<= endTime + + lastTime+dt<= endTime ifTrue:[ prevPrevState := prevState. prevState := state. self stepper: ((self secondStepperClass) onSystem: self system). - state := self secondStepPrevState: prevPrevState startTime: lastTime. + state := self secondStepPrevState: prevPrevState startTime: lastTime. "announce second step" - self announceState: state time: lastTime. - + self announceState: state time: lastTime. + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ self stepper: ((self stepperClass) onSystem: self system). state := self lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime]. - - lastTime+dt<= endTime + + lastTime+dt<= endTime ifTrue:[ self stepper: ((self stepperClass) onSystem: self system). - "step until the end" - + "step until the end" + statesPair := self mainStepsPrevState: prevState prevPrevState: prevPrevState startTime: initialTime endTime: endTime. prevPrevState:=statesPair first. prevState:= statesPair second. - + "sanity check" - self assert: [(lastTime between: initialTime and: endTime) + self assert: [(lastTime between: initialTime and: endTime) or: [lastTime between: endTime and: initialTime]]. - - "take another step if needed" + + "take another step if needed" state := self lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime]]]. - - ^ state + + ^ state ] diff --git a/src/Math-ODE/PMBDF3Stepper.class.st b/src/Math-ODE/PMBDF3Stepper.class.st index cd03d7fcc..20a4d638e 100644 --- a/src/Math-ODE/PMBDF3Stepper.class.st +++ b/src/Math-ODE/PMBDF3Stepper.class.st @@ -10,7 +10,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMBDF3Stepper class >> order [ "BDF3 is a third order method." ^ 3 @@ -31,5 +31,5 @@ PMBDF3Stepper >> doStep: aState prevState: prevState prevPrevState: prevPrevStat { #category : #stepping } PMBDF3Stepper >> doStep: aState prevState: prevState prevPrevState: prevPrevState time: t stepSize: timeStep [ self stepSize: timeStep. - ^ self doStep: aState prevState: prevState prevPrevState: prevPrevState time: t + ^ self doStep: aState prevState: prevState prevPrevState: prevPrevState time: t ] diff --git a/src/Math-ODE/PMBDF4Solver.class.st b/src/Math-ODE/PMBDF4Solver.class.st index f0c302e0d..1cf9553f4 100644 --- a/src/Math-ODE/PMBDF4Solver.class.st +++ b/src/Math-ODE/PMBDF4Solver.class.st @@ -8,7 +8,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #private } PMBDF4Solver class >> stepperClass [ ^ PMBDF4Stepper ] @@ -18,19 +18,19 @@ PMBDF4Solver class >> thirdStepperClass [ ^ PMBDF3Stepper ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMBDF4Solver >> lastStepPrevState: prevState prevPrevState: prevPrevState initState:initState endTime: endTime [ "catch partial or full step at end" (lastTime closeTo: endTime ) ifFalse: - [state := stepper - doStep3State: state + [state := stepper + doStep3State: state secondState: prevState firstState: prevPrevState initState: initState thirdTime: lastTime stepSize: endTime - lastTime. - self announceState: state time: endTime]. + self announceState: state time: endTime]. ^ state ] @@ -38,34 +38,34 @@ PMBDF4Solver >> lastStepPrevState: prevState prevPrevState: prevPrevState initSt PMBDF4Solver >> mainStepsPrevState: prevState prevPrevState: prevPrevState initState: initState startTime: initialTime endTime: endTime [ |previousState previousPrevState initialState | - previousState := prevState. + previousState := prevState. previousPrevState:=prevPrevState. initialState:=initState. "don't go to end time to avoid overrunning" - (lastTime to: endTime - self dt by: self dt) do: + (lastTime to: endTime - self dt by: self dt) do: [:time | | tempState1 tempState2 tempState3| tempState1:=state. tempState2:=previousState. tempState3:=previousPrevState. state := stepper - doStep3State: state + doStep3State: state secondState: previousState firstState: previousPrevState - initState: initialState - thirdTime: time + initState: initialState + thirdTime: time stepSize: self dt. initialState:=tempState3. - previousPrevState:=tempState2. + previousPrevState:=tempState2. previousState := tempState1. "announce step results" self announceState: state time: time + self dt. lastTime := time + self dt]. - + ^ Array with: initialState with: previousPrevState with: previousState ] -{ #category : #'as yet unclassified' } +{ #category : #solving } PMBDF4Solver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime [ | prevState prevPrevState statesPair initState | self system: aSystem. @@ -74,66 +74,66 @@ PMBDF4Solver >> solve: aSystem startState: initialState startTime: initialTime e lastTime := initialTime. "announce initial conditions" self announceState: state time: initialTime. - + (lastTime + dt > endTime and: lastTime < endTime) ifTrue: [ state := self lastStepState: state endTime: endTime ]. - + lastTime + dt <= endTime - ifTrue: [ + ifTrue: [ prevState := initialState. - state := self firstStepStartTime: initialTime. + state := self firstStepStartTime: initialTime. "announce first step" self announceState: state time: lastTime. - + (lastTime + dt > endTime and: lastTime < endTime) - ifTrue: [ + ifTrue: [ self stepper: (self secondStepperClass onSystem: self system). state := self lastStepPrevState: prevState endTime: endTime ]. - + lastTime + dt <= endTime - ifTrue: [ + ifTrue: [ prevPrevState := prevState. prevState := state. self stepper: (self secondStepperClass onSystem: self system). - state := self secondStepPrevState: prevPrevState startTime: lastTime. + state := self secondStepPrevState: prevPrevState startTime: lastTime. "announce second step" self announceState: state time: lastTime. - + (lastTime + dt > endTime and: lastTime < endTime) ifTrue: [ self stepper: (self thirdStepperClass onSystem: self system). state := self lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime ]. - + lastTime + dt <= endTime - ifTrue: [ + ifTrue: [ self stepper: (self thirdStepperClass onSystem: self system). initState := prevPrevState. prevPrevState := prevState. - prevState := state. + prevState := state. state := self thirdStepPrevState: prevPrevState prevPrevState: initState startTime: lastTime. - + "announce third step" self announceState: state time: lastTime. - + (lastTime + dt > endTime and: lastTime < endTime) - ifTrue: [ - self stepper: (self stepperClass onSystem: self system). + ifTrue: [ + self stepper: (self stepperClass onSystem: self system). state := self lastStepPrevState: prevState prevPrevState: prevPrevState initState: initState endTime: endTime ]. - + lastTime + dt <= endTime - ifTrue: [ - self stepper: (self stepperClass onSystem: self system). + ifTrue: [ + self stepper: (self stepperClass onSystem: self system). "step until the end" - + statesPair := self mainStepsPrevState: prevState prevPrevState: prevPrevState @@ -143,13 +143,13 @@ PMBDF4Solver >> solve: aSystem startState: initialState startTime: initialTime e initState := statesPair first. prevPrevState:=statesPair second. prevState:= statesPair third. - - + + "sanity check" self - assert: [ (lastTime between: initialTime and: endTime) or: [ lastTime between: endTime and: initialTime ] ]. - - + assert: [ (lastTime between: initialTime and: endTime) or: [ lastTime between: endTime and: initialTime ] ]. + + "take another step if needed" state := self lastStepPrevState: prevState @@ -161,10 +161,10 @@ PMBDF4Solver >> solve: aSystem startState: initialState startTime: initialTime e { #category : #'as yet unclassified' } PMBDF4Solver >> thirdStepPrevState: prevState prevPrevState: prevPrevState startTime: t [ - state := stepper doStep: state - prevState: prevState - prevPrevState: prevPrevState - time: t + state := stepper doStep: state + prevState: prevState + prevPrevState: prevPrevState + time: t stepSize: self dt. self announceState: state time: t + self dt. lastTime := t + self dt. @@ -173,5 +173,5 @@ PMBDF4Solver >> thirdStepPrevState: prevState prevPrevState: prevPrevState star { #category : #'as yet unclassified' } PMBDF4Solver >> thirdStepperClass [ - ^ self class thirdStepperClass + ^ self class thirdStepperClass ] diff --git a/src/Math-ODE/PMBDF4Stepper.class.st b/src/Math-ODE/PMBDF4Stepper.class.st index 97e96e331..9e288ad62 100644 --- a/src/Math-ODE/PMBDF4Stepper.class.st +++ b/src/Math-ODE/PMBDF4Stepper.class.st @@ -9,7 +9,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMBDF4Stepper class >> order [ "BDF4 is a fourth order method." ^ 4 diff --git a/src/Math-ODE/PMButcherTableauStepper.class.st b/src/Math-ODE/PMButcherTableauStepper.class.st index fbc3986a4..618c363e9 100644 --- a/src/Math-ODE/PMButcherTableauStepper.class.st +++ b/src/Math-ODE/PMButcherTableauStepper.class.st @@ -14,7 +14,7 @@ PMButcherTableauStepper class >> eulerStepper [ | a b | a := PMMatrix rows: #((0)). b := #(1). - ^ self stageWeights: b stageCoefficients: a. + ^ self stageWeights: b stageCoefficients: a ] { #category : #'instance creation' } @@ -22,7 +22,7 @@ PMButcherTableauStepper class >> kuttaThreeEighthsStepper [ | a b | a := PMMatrix rows: #((0 0 0 0) ((1 / 3) 0 0 0) ((-1 / 3 ) 1 0 0) (0 1 -1 1)). b := #((1 / 8) (3 / 8) (3 / 8) (1 / 8)). - ^ self stageWeights: b stageCoefficients: a. + ^ self stageWeights: b stageCoefficients: a ] { #category : #'instance creation' } @@ -30,7 +30,7 @@ PMButcherTableauStepper class >> rungeKuttaStepper [ | a b | a := PMMatrix rows: #((0 0 0 0) (0.5 0 0 0) (0 0.5 0 0) (0 0 1 0)). b := #((1 / 6) (1 / 3) (1 / 3) (1 / 6)). - ^ self stageWeights: b stageCoefficients: a. + ^ self stageWeights: b stageCoefficients: a ] { #category : #'instance creation' } @@ -38,7 +38,7 @@ PMButcherTableauStepper class >> rungeStepper [ | a b | a := PMMatrix rows: #((0 0) (0.5 0)). b := #(0 1). - ^ self stageWeights: b stageCoefficients: a. + ^ self stageWeights: b stageCoefficients: a ] { #category : #'instance creation' } @@ -48,13 +48,13 @@ PMButcherTableauStepper class >> stageWeights: anArray stageCoefficients: aMatri self assert: [anArray sum = 1]. "we can calculate the stage increments from the coefficient matrix" c := Array new: anArray size. - (1 to: c size) do: [:i | + (1 to: c size) do: [:i | c at: i put: ((aMatrix rowAt: i) sum)]. - + ^ self new stageIncrements: c; stageCoefficients: aMatrix; stageWeights: anArray; - yourself. + yourself ] { #category : #stepping } @@ -67,30 +67,31 @@ PMButcherTableauStepper >> doStep: aStateTime stepSize: stepSize [ stages := Array new: stageCount. (1 to: stageCount) do: [:i | | sum | - sum ifNil: [sum := 0]. - (1 to: i - 1) do: + sum ifNil: [sum := 0]. + (1 to: i - 1) do: [:j | sum := sum + ((stages at: j ) * stageCoefficients at: i at: j)]. - stages at: i put: - (system - state: aStateTime state + (dt * sum) + stages at: i put: + (system + state: aStateTime state + (dt * sum) time: aStateTime time + (dt * stageIncrements at: i) )]. - stateDifference := (dt * ((1 to: stageCount) do: [:i | | sum | + stateDifference := (dt * ((1 to: stageCount) do: [:i | | sum | sum ifNil: [sum := 0]. sum := sum + (( stageWeights at: i) * (stages at: i)) ])). - ^ aStateTime state + stateDifference. + ^ aStateTime state + stateDifference ] { #category : #stepping } PMButcherTableauStepper >> doStep: aState time: aTime stepSize: stepSize [ - ^ self doStep: (PMStateTime state: aState time: aTime) stepSize: stepSize. + ^ self doStep: (PMStateTime state: aState time: aTime) stepSize: stepSize ] { #category : #assertion } PMButcherTableauStepper >> isInitialized [ - self assert: [stageCoefficients notNil]. - self assert: [stageIncrements notNil]. - self assert: [stageWeights notNil]. - self assert: [system notNil]. + + self assert: [ stageCoefficients isNotNil ]. + self assert: [ stageIncrements isNotNil ]. + self assert: [ stageWeights isNotNil ]. + self assert: [ system isNotNil ]. ^ self ] @@ -102,7 +103,6 @@ PMButcherTableauStepper >> stageCoefficients [ { #category : #accessing } PMButcherTableauStepper >> stageCoefficients: aMatrix [ stageCoefficients := aMatrix - ] { #category : #accessing } @@ -113,8 +113,6 @@ PMButcherTableauStepper >> stageIncrements [ { #category : #accessing } PMButcherTableauStepper >> stageIncrements: anArray [ stageIncrements := anArray - - ] { #category : #accessing } @@ -125,5 +123,4 @@ PMButcherTableauStepper >> stageWeights [ { #category : #accessing } PMButcherTableauStepper >> stageWeights: anArray [ stageWeights := anArray - ] diff --git a/src/Math-ODE/PMExplicitSolver.class.st b/src/Math-ODE/PMExplicitSolver.class.st index 02b42dff5..9624d4b83 100644 --- a/src/Math-ODE/PMExplicitSolver.class.st +++ b/src/Math-ODE/PMExplicitSolver.class.st @@ -4,9 +4,9 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #private } PMExplicitSolver class >> stepperClass [ - ^ PMExplicitStepper. + ^ PMExplicitStepper ] { #category : #'announcement hooks' } @@ -17,5 +17,5 @@ PMExplicitSolver >> announcementClass [ { #category : #'announcement hooks' } PMExplicitSolver >> announcerClass [ - ^ PMExplicitAnnouncer + ^ PMExplicitAnnouncer ] diff --git a/src/Math-ODE/PMExplicitSolverAnnouncement.class.st b/src/Math-ODE/PMExplicitSolverAnnouncement.class.st index a42dd6199..d17708e94 100644 --- a/src/Math-ODE/PMExplicitSolverAnnouncement.class.st +++ b/src/Math-ODE/PMExplicitSolverAnnouncement.class.st @@ -13,7 +13,7 @@ Class { { #category : #accessing } PMExplicitSolverAnnouncement class >> state: aState time: aTime [ - ^ self new state: aState time: aTime; yourself. + ^ self new state: aState time: aTime; yourself ] { #category : #accessing } @@ -24,7 +24,7 @@ PMExplicitSolverAnnouncement >> state [ { #category : #accessing } PMExplicitSolverAnnouncement >> state: aState time: aTime [ state:= aState. - t := aTime. + t := aTime ] { #category : #accessing } diff --git a/src/Math-ODE/PMExplicitSolverSubscriber.class.st b/src/Math-ODE/PMExplicitSolverSubscriber.class.st index 312590777..580ef5d21 100644 --- a/src/Math-ODE/PMExplicitSolverSubscriber.class.st +++ b/src/Math-ODE/PMExplicitSolverSubscriber.class.st @@ -14,7 +14,7 @@ Class { { #category : #'instance creation' } PMExplicitSolverSubscriber class >> forAnnouncer: anAnnouncer [ - ^ self new forAnnouncer: anAnnouncer. + ^ self new forAnnouncer: anAnnouncer ] { #category : #'instance creation' } @@ -24,7 +24,7 @@ PMExplicitSolverSubscriber class >> forSolver: anODESolver [ { #category : #accessing } PMExplicitSolverSubscriber >> announcers [ - + ^ announcers ] @@ -35,21 +35,21 @@ PMExplicitSolverSubscriber >> block [ { #category : #accessing } PMExplicitSolverSubscriber >> block: aFormatBlock [ - block := aFormatBlock + block := aFormatBlock ] { #category : #accessing } PMExplicitSolverSubscriber >> defaultBlock [ - ^ self subclassResponsibility + ^ self subclassResponsibility ] { #category : #subscription } PMExplicitSolverSubscriber >> forAnnouncer: anAnnouncer [ anAnnouncer when: PMExplicitSolverAnnouncement do: self block. - announcers add: anAnnouncer. + announcers add: anAnnouncer ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMExplicitSolverSubscriber >> initialize [ super initialize. announcers := IdentitySet new. @@ -57,21 +57,20 @@ PMExplicitSolverSubscriber >> initialize [ ^ self ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMExplicitSolverSubscriber >> release [ "stop announcers from sending messages" self unsubscribe. - super release. + super release ] { #category : #subscription } PMExplicitSolverSubscriber >> unsubscribe [ - announcers do: [:ea | self unsubscribe: ea]. - + announcers do: [:ea | self unsubscribe: ea] ] { #category : #subscription } PMExplicitSolverSubscriber >> unsubscribe: anAnnouncer [ anAnnouncer unsubscribe: self. - announcers remove: anAnnouncer ifAbsent: []. + announcers remove: anAnnouncer ifAbsent: [] ] diff --git a/src/Math-ODE/PMExplicitStepper.class.st b/src/Math-ODE/PMExplicitStepper.class.st index f2ebf72b7..eab2efe68 100644 --- a/src/Math-ODE/PMExplicitStepper.class.st +++ b/src/Math-ODE/PMExplicitStepper.class.st @@ -15,7 +15,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMExplicitStepper class >> order [ "the default ExplicitStepper is a Euler Method, order 1" ^ 1 @@ -33,17 +33,17 @@ PMExplicitStepper >> doStep: aState time: t [ { #category : #stepping } PMExplicitStepper >> doStep: aState time: t stepSize: timeStep [ "This method should take one step from inState at time t of size dt, and modify the state, then answer it. The default implementation here is Euler Method. Subclasses should override" - | dxdt | + self stepSize: timeStep. - ^ self doStep: aState time: t. + ^ self doStep: aState time: t ] { #category : #stepping } PMExplicitStepper >> lastStep: aState time: t deltaT: incrementOfTime [ "This method should take one step from inState at time t of size dt, and modify the state, then answer it. The default implementation here is Euler Method. Subclasses should override" - self stepSize isNil ifTrue: [self error: 'step size required by stepper']. - ^ self stepSize * (system state: aState time: t- self stepSize + incrementOfTime) + aState - + + self stepSize ifNil: [ self error: 'step size required by stepper' ]. + ^ self stepSize * (system state: aState time: t - self stepSize + incrementOfTime) + aState ] { #category : #stepping } @@ -51,5 +51,5 @@ PMExplicitStepper >> lastStep: aState time: t stepSize: timeStep deltaT: increme "This method should take one step from inState at time t of size dt, and modify the state, then answer it. The default implementation here is Euler Method. Subclasses should override" | | self stepSize: timeStep. - ^ self lastStep: aState time: t deltaT: incrementOfTime. + ^ self lastStep: aState time: t deltaT: incrementOfTime ] diff --git a/src/Math-ODE/PMHeunStepper.class.st b/src/Math-ODE/PMHeunStepper.class.st index 4849c553f..3bc0c0a5c 100644 --- a/src/Math-ODE/PMHeunStepper.class.st +++ b/src/Math-ODE/PMHeunStepper.class.st @@ -8,7 +8,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMHeunStepper class >> order [ "Heun's method is a second order method." ^ 2 @@ -26,10 +26,3 @@ PMHeunStepper >> doStep: aState time: t [ ^ aState + (self stepSize / 2 * ((system state: aState time: t) + (system state: xi time: ti))) ] - -{ #category : #stepping } -PMHeunStepper >> doStep: aState time: t stepSize: timeStep [ - "This method should take one step from inState at time t of size dt, and modify the state, then answer it. " - self stepSize: timeStep. - ^ self doStep: aState time: t. -] diff --git a/src/Math-ODE/PMImplicitMidpointSolver.class.st b/src/Math-ODE/PMImplicitMidpointSolver.class.st index 86b2dfc72..580685186 100644 --- a/src/Math-ODE/PMImplicitMidpointSolver.class.st +++ b/src/Math-ODE/PMImplicitMidpointSolver.class.st @@ -8,12 +8,12 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #private } PMImplicitMidpointSolver class >> stepperClass [ ^ PMImplicitMidpointStepper ] -{ #category : #'as yet unclassified' } +{ #category : #solving } PMImplicitMidpointSolver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime [ self system: aSystem. @@ -23,16 +23,16 @@ PMImplicitMidpointSolver >> solve: aSystem startState: initialState startTime: i "announce initial conditions" self announceState: state time: initialTime. - - + + "step until the end" state := self mainStepsState: state startTime: initialTime endTime: endTime. - + "sanity check" - self assert: [(lastTime between: initialTime and: endTime) + self assert: [(lastTime between: initialTime and: endTime) or: [lastTime between: endTime and: initialTime]]. - + "take another step if needed" state := self lastStepState: state endTime: endTime. diff --git a/src/Math-ODE/PMImplicitMidpointStepper.class.st b/src/Math-ODE/PMImplicitMidpointStepper.class.st index aa1975a86..dad9efcee 100644 --- a/src/Math-ODE/PMImplicitMidpointStepper.class.st +++ b/src/Math-ODE/PMImplicitMidpointStepper.class.st @@ -8,7 +8,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMImplicitMidpointStepper class >> order [ "Implicit Midpoint is a second order method." ^ 2 @@ -27,10 +27,3 @@ PMImplicitMidpointStepper >> doStep: aState time: t [ xi2 := 1 / 2 * (aState + (system state: xi1 time: ti)). ^ aState + (self stepSize * (system state: xi2 time: ti)) ] - -{ #category : #stepping } -PMImplicitMidpointStepper >> doStep: aState time: t stepSize: timeStep [ - "This method should take one step from inState at time t of size dt, and modify the state, then answer it. " - self stepSize: timeStep. - ^ self doStep: aState time: t. -] diff --git a/src/Math-ODE/PMImplicitSolver.class.st b/src/Math-ODE/PMImplicitSolver.class.st index e0cb8232f..f0ec9d896 100644 --- a/src/Math-ODE/PMImplicitSolver.class.st +++ b/src/Math-ODE/PMImplicitSolver.class.st @@ -4,15 +4,15 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #private } PMImplicitSolver class >> stepperClass [ - ^ PMImplicitStepper. + ^ PMImplicitStepper ] { #category : #'announcement hooks' } PMImplicitSolver >> announcementClass [ - ^ PMImplicitSolverAnnouncement + ^ PMImplicitSolverAnnouncement ] { #category : #'announcement hooks' } diff --git a/src/Math-ODE/PMImplicitSolverAnnouncement.class.st b/src/Math-ODE/PMImplicitSolverAnnouncement.class.st index b6c05223a..69db25146 100644 --- a/src/Math-ODE/PMImplicitSolverAnnouncement.class.st +++ b/src/Math-ODE/PMImplicitSolverAnnouncement.class.st @@ -12,9 +12,9 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMImplicitSolverAnnouncement class >> state: aState time: aTime [ - ^ self new state: aState time: aTime; yourself. + ^ self new state: aState time: aTime; yourself ] { #category : #accessing } @@ -25,7 +25,7 @@ PMImplicitSolverAnnouncement >> state [ { #category : #accessing } PMImplicitSolverAnnouncement >> state: aState time: aTime [ state:= aState. - t := aTime. + t := aTime ] { #category : #accessing } diff --git a/src/Math-ODE/PMImplicitStepper.class.st b/src/Math-ODE/PMImplicitStepper.class.st index c87d9db77..7ed9ab9f2 100644 Binary files a/src/Math-ODE/PMImplicitStepper.class.st and b/src/Math-ODE/PMImplicitStepper.class.st differ diff --git a/src/Math-ODE/PMImplicitSystem.class.st b/src/Math-ODE/PMImplicitSystem.class.st index 2f2b85b17..8a5c1e031 100644 --- a/src/Math-ODE/PMImplicitSystem.class.st +++ b/src/Math-ODE/PMImplicitSystem.class.st @@ -18,5 +18,5 @@ Class { { #category : #hooks } PMImplicitSystem >> jacobianAtX: aState t: aTime [ "calculate and store jacobian at this point df/dx" - self shouldBeImplemented + self shouldBeImplemented ] diff --git a/src/Math-ODE/PMMidpointStepper.class.st b/src/Math-ODE/PMMidpointStepper.class.st index fd918bf78..90afdb1be 100644 --- a/src/Math-ODE/PMMidpointStepper.class.st +++ b/src/Math-ODE/PMMidpointStepper.class.st @@ -33,6 +33,5 @@ PMMidpointStepper >> lastStep: aState time: t stepSize: timeStep deltaT: increme "This method should take one step from inState at time t of size dt, and modify the state, then answer it." self stepSize: timeStep. - ^ self doStep: aState time: t . - + ^ self doStep: aState time: t ] diff --git a/src/Math-ODE/PMODESolver.class.st b/src/Math-ODE/PMODESolver.class.st index c9e1608b9..771f16692 100644 --- a/src/Math-ODE/PMODESolver.class.st +++ b/src/Math-ODE/PMODESolver.class.st @@ -23,7 +23,7 @@ Class { { #category : #'class variables' } PMODESolver class >> stepperClass [ - ^ShouldBeImplemented. + ^ShouldBeImplemented ] { #category : #solving } @@ -33,7 +33,7 @@ PMODESolver >> announceState: aState time: aTime [ { #category : #'announcement hooks' } PMODESolver >> announcementClass [ - ^ self subclassResponsibility + ^ self subclassResponsibility ] { #category : #accessing } @@ -43,7 +43,7 @@ PMODESolver >> announcer [ { #category : #accessing } PMODESolver >> announcer: anAnnouncer [ - announcer := anAnnouncer + announcer := anAnnouncer ] { #category : #'announcement hooks' } @@ -58,15 +58,15 @@ PMODESolver >> dt [ ] { #category : #accessing } -PMODESolver >> dt: aFloat [ +PMODESolver >> dt: aFloat [ dt := aFloat ] -{ #category : #initialize } +{ #category : #initialization } PMODESolver >> initialize [ - + super initialize. - announcer := self announcerClass new. + announcer := self announcerClass new ] { #category : #solving } @@ -74,29 +74,29 @@ PMODESolver >> lastStepState: aState endTime: endTime [ "catch partial or full step at end" (lastTime closeTo: endTime ) ifFalse: - [state := stepper - lastStep: state - time: lastTime + [state := stepper + lastStep: state + time: lastTime stepSize: endTime - lastTime deltaT: dt. - self announceState: state time: endTime]. + self announceState: state time: endTime]. ^ state ] { #category : #solving } PMODESolver >> mainStepsState: aState startTime: initialTime endTime: endTime [ - state := aState. + state := aState. "don't go to end time to avoid overrunning" (initialTime to: endTime - self dt by: self dt) do: - [:time | - state := stepper - doStep: state - time: time + [:time | + state := stepper + doStep: state + time: time stepSize: self dt. "announce step results" self announceState: state time: time + self dt. lastTime := time + self dt]. - + ^ state ] @@ -111,20 +111,20 @@ PMODESolver >> solve: aSystem startState: initialState startTime: initialTime en "announce initial conditions" self announceState: state time: initialTime. - + (lastTime+dt > endTime and: lastTime < endTime) ifTrue:[ state :=self lastStepState: state endTime: endTime]. - - lastTime+dt<= endTime - ifTrue:[ + + lastTime+dt<= endTime + ifTrue:[ "step until the end" state := self mainStepsState: state startTime: initialTime endTime: endTime. - + "sanity check" - self assert: [(lastTime between: initialTime and: endTime) + self assert: [(lastTime between: initialTime and: endTime) or: [lastTime between: endTime and: initialTime]]. - + "take another step if needed" state := self lastStepState: state endTime: endTime.]. @@ -134,13 +134,14 @@ PMODESolver >> solve: aSystem startState: initialState startTime: initialTime en { #category : #solving } PMODESolver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime stepSize: timeStep [ self dt: timeStep. - ^ self solve: aSystem startState: initialState startTime: initialTime endTime: endTime. + ^ self solve: aSystem startState: initialState startTime: initialTime endTime: endTime ] { #category : #accessing } -PMODESolver >> stepper: aStepper [ +PMODESolver >> stepper: aStepper [ + stepper := aStepper. - system notNil ifTrue: [stepper system: system]. + system ifNotNil: [ stepper system: system ] ] { #category : #private } @@ -155,7 +156,8 @@ PMODESolver >> system [ ] { #category : #accessing } -PMODESolver >> system: aSystem [ +PMODESolver >> system: aSystem [ + system := aSystem. - stepper notNil ifTrue: [stepper system: aSystem]. + stepper ifNotNil: [ stepper system: aSystem ] ] diff --git a/src/Math-ODE/PMODESystem.class.st b/src/Math-ODE/PMODESystem.class.st index 2dcba4103..67e4dec9d 100644 --- a/src/Math-ODE/PMODESystem.class.st +++ b/src/Math-ODE/PMODESystem.class.st @@ -10,8 +10,8 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } -PMODESystem class >> block: aBlock [ +{ #category : #accessing } +PMODESystem class >> block: aBlock [ ^ (self new block: aBlock; yourself) ] @@ -29,5 +29,5 @@ PMODESystem >> block: aBlock [ { #category : #evaluation } PMODESystem >> state: aState time: aTime [ - ^ self block value: aState value: aTime + ^ self block value: aState value: aTime ] diff --git a/src/Math-ODE/PMRungeKuttaStepper.class.st b/src/Math-ODE/PMRungeKuttaStepper.class.st index 3948d5ad7..571cd1bca 100644 --- a/src/Math-ODE/PMRungeKuttaStepper.class.st +++ b/src/Math-ODE/PMRungeKuttaStepper.class.st @@ -36,5 +36,5 @@ PMRungeKuttaStepper >> lastStep: aState time: t stepSize: timeStep deltaT: incre "This method should take one step from inState at time t of size dt, and modify the state, then answer it." self stepSize: timeStep. - ^ self doStep: aState time: t + ^ self doStep: aState time: t ] diff --git a/src/Math-ODE/PMStateRecorder.class.st b/src/Math-ODE/PMStateRecorder.class.st index 430b61f4a..49601304a 100644 --- a/src/Math-ODE/PMStateRecorder.class.st +++ b/src/Math-ODE/PMStateRecorder.class.st @@ -49,15 +49,15 @@ PMStateRecorder class >> demo [ { #category : #accessing } PMStateRecorder >> add: aState at: aTime [ - states add: (PMStateTime state: aState time: aTime). + states add: (PMStateTime state: aState time: aTime) ] { #category : #accessing } PMStateRecorder >> defaultBlock [ - ^ [:ann | self add: ann state at: ann time]. + ^ [:ann | self add: ann state at: ann time] ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMStateRecorder >> initialize [ super initialize. states := SortedCollection sortBlock: [:x :y | x time < y time]. diff --git a/src/Math-ODE/PMStateTime.class.st b/src/Math-ODE/PMStateTime.class.st index 5e8fd6684..9c76cda76 100644 --- a/src/Math-ODE/PMStateTime.class.st +++ b/src/Math-ODE/PMStateTime.class.st @@ -15,9 +15,9 @@ Class { { #category : #'instance creation' } PMStateTime class >> state: aState time: aTime [ - ^ self new + ^ self new state: aState; - time: aTime. + time: aTime ] { #category : #printing } @@ -25,8 +25,7 @@ PMStateTime >> printOn: aStream [ "used for inspector. Using the point analogy" state printOn: aStream. aStream nextPut: $@. - time printOn: aStream. - + time printOn: aStream ] { #category : #accessing } diff --git a/src/Math-ODE/PMStepper.class.st b/src/Math-ODE/PMStepper.class.st index 39065083c..bef0a253e 100644 --- a/src/Math-ODE/PMStepper.class.st +++ b/src/Math-ODE/PMStepper.class.st @@ -21,8 +21,8 @@ Class { } { #category : #'instance creation' } -PMStepper class >> onSystem: aSystem [ - ^ self new system: aSystem. +PMStepper class >> onSystem: aSystem [ + ^ self new system: aSystem. ] { #category : #accessing } @@ -34,7 +34,7 @@ PMStepper class >> order [ { #category : #stepping } PMStepper >> doStep: aState time: t stepSize: stepSize [ "This method should take one step from inState at time t of size dt, then answer it" - self subclassResponsibility + self subclassResponsibility ] { #category : #accessing } @@ -49,7 +49,7 @@ PMStepper >> stepSize [ { #category : #accessing } PMStepper >> stepSize: timeStep [ - dt := timeStep. + dt := timeStep ] { #category : #accessing } @@ -59,5 +59,5 @@ PMStepper >> system [ { #category : #accessing } PMStepper >> system: aSystem [ - system := aSystem. + system := aSystem ] diff --git a/src/Math-ODE/PMSymplecticSystem.class.st b/src/Math-ODE/PMSymplecticSystem.class.st index ba07c10a3..3e0b55c4c 100644 --- a/src/Math-ODE/PMSymplecticSystem.class.st +++ b/src/Math-ODE/PMSymplecticSystem.class.st @@ -52,9 +52,9 @@ PMSymplecticSystem >> dqdt: anObject [ ] { #category : #evaluation } -PMSymplecticSystem >> first: pState [ +PMSymplecticSystem >> first: pState [ dqdt := firstBlock value: pState. - ^ dqdt. + ^ dqdt ] { #category : #accessing } @@ -70,7 +70,7 @@ PMSymplecticSystem >> firstBlock: anObject [ { #category : #evaluation } PMSymplecticSystem >> second: qState [ dpdt := secondBlock value: qState. - ^ dpdt. + ^ dpdt ] { #category : #accessing } diff --git a/src/Math-ODE/PMTranscriptRecorder.class.st b/src/Math-ODE/PMTranscriptRecorder.class.st index 118f93b16..cfa70798b 100644 --- a/src/Math-ODE/PMTranscriptRecorder.class.st +++ b/src/Math-ODE/PMTranscriptRecorder.class.st @@ -59,7 +59,6 @@ PMTranscriptRecorder >> defaultBlock [ show: ann state asString ; tab; tab; show: ' time: '; - show: ann time asString; + show: ann time asString; cr ] - ] diff --git a/src/Math-ODE/PMTrapezoidStepper.class.st b/src/Math-ODE/PMTrapezoidStepper.class.st index 6b22cbd13..5072158f2 100644 --- a/src/Math-ODE/PMTrapezoidStepper.class.st +++ b/src/Math-ODE/PMTrapezoidStepper.class.st @@ -10,7 +10,7 @@ Class { #category : #'Math-ODE' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMTrapezoidStepper class >> order [ "Trapezoid is a second order method." ^ 2 @@ -37,7 +37,7 @@ PMTrapezoidStepper >> doStep: aState time: t [ PMTrapezoidStepper >> doStep: aState time: t stepSize: timeStep [ "This method should take one step from inState at time t of size dt, and modify the state, then answer it. " self stepSize: timeStep. - ^ self doStep: aState time: t. + ^ self doStep: aState time: t ] { #category : #stepping } @@ -61,5 +61,5 @@ PMTrapezoidStepper >> lastStep: aState time: t deltaT: incrementOfTime [ PMTrapezoidStepper >> lastStep: aState time: t stepSize: timeStep deltaT: incrementOfTime [ "This method should take one step from inState at time t of size dt, and modify the state, then answer it. " self stepSize: timeStep. - ^ self lastStep: aState time: t deltaT: incrementOfTime. + ^ self lastStep: aState time: t deltaT: incrementOfTime ] diff --git a/src/Math-Permutation/PMPermutation.class.st b/src/Math-Permutation/PMPermutation.class.st index 363755096..5c9ac636c 100644 --- a/src/Math-Permutation/PMPermutation.class.st +++ b/src/Math-Permutation/PMPermutation.class.st @@ -24,35 +24,36 @@ Class { { #category : #accessing } PMPermutation class >> allOfSize: anInteger [ -"generates all permutations of the given size, in other words it produces the symmetric group of degree anInteger. + "generates all permutations of the given size, in other words it produces the symmetric group of degree anInteger. Heap's algorithm, used here, seems to be just a tiny bit faster than using #permutationsDo:" - | result perm c i ci| - anInteger = 0 ifTrue:[^#()]. + + | result perm c i ci | + anInteger = 0 ifTrue: [ ^ #( ) ]. perm := self identity: anInteger. - (result := WriteStream on:(Array new: anInteger factorial)) nextPut: perm copy. + (result := WriteStream on: (Array new: anInteger factorial)) nextPut: perm copy. c := Array new: anInteger withAll: 1. i := 1. - [ i <= anInteger ] - whileTrue: [ - (ci :=(c at: i)) < i - ifTrue: [ - i odd - ifTrue: [ perm swap: 1 with: i ] - ifFalse: [ perm swap: ci with: i ]. - result nextPut: perm copy. - c at: i put: ci + 1. - i := 1 ] - ifFalse: [ c at: i put: 1. i := i + 1 ] ]. + [ i <= anInteger ] whileTrue: [ + i := (ci := c at: i) < i + ifTrue: [ + i odd + ifTrue: [ perm swap: 1 with: i ] + ifFalse: [ perm swap: ci with: i ]. + result nextPut: perm copy. + c at: i put: ci + 1. + 1 ] + ifFalse: [ + c at: i put: 1. + i + 1 ] ]. ^ result contents ] { #category : #'instance creation' } PMPermutation class >> fromCycles: aCollectionofCollections [ + | length | length := aCollectionofCollections flattened. - length := length isEmpty - ifTrue: [ 0 ] - ifFalse: [ length max ]. + length := length ifEmpty: [ 0 ] ifNotEmpty: [ length max ]. ^ self size: length fromCycles: aCollectionofCollections ] @@ -75,7 +76,7 @@ PMPermutation class >> generator: arrayOfPermutations [ { #category : #'instance creation' } PMPermutation class >> identity: size [ -^ super withAll: (1 to: size) +^ super withAll: (1 to: size) ] { #category : #'instance creation' } @@ -115,8 +116,8 @@ PMPermutation class >> randomPermutation: size [ PMPermutation class >> size: anInteger fromCycles: aCollectionofCollections [ | result | result := self identity: anInteger. - aCollectionofCollections do: [ :cycle | - 1 to: cycle size do: [ :i | + aCollectionofCollections do: [ :cycle | + 1 to: cycle size do: [ :i | result at: (cycle at: i) put: (cycle atWrap: i + 1) ] ]. ^ result ] @@ -136,7 +137,7 @@ block:=[:nandk||n k| k:=nandk second. (n=k and:[n isZero]) ifTrue:[1] - ifFalse:[ (n * k) isZero + ifFalse:[ (n * k) isZero ifTrue:[0] ifFalse:[ (block value: (Array with: n-1 with: k-1))+((n-1)*(block value:(Array with: n-1 with: k)))]]]memoized . ^block value: (Array with: anInteger with: anotherInteger) @@ -148,7 +149,7 @@ PMPermutation >> asCycles [ unused := (1 to: self size) asOrderedCollection. result := OrderedCollection new. [ unused isEmpty ] - whileFalse: [ + whileFalse: [ next := start := unused first. cycle := OrderedCollection new. [ cycle add: (unused remove: next). @@ -162,7 +163,7 @@ PMPermutation >> asMatrix [ ^ PMMatrix rows: (self asPMVector - collect: [ :n | + collect: [ :n | (PMVector new: self size) atAllPut: 0; at: n put: 1; @@ -175,7 +176,7 @@ PMPermutation >> discriminant [ ] { #category : #testing } -PMPermutation >> even [ +PMPermutation >> even [ ^self odd not ] @@ -209,16 +210,17 @@ PMPermutation >> isCollection [ { #category : #testing } PMPermutation >> odd [ "using the number of transpositions is faster than using the number of inversions" -^self discriminant odd. +^self discriminant odd ] { #category : #applying } PMPermutation >> permute: aSequentialCollection [ + | s c | - (s := aSequentialCollection size) < self size - ifTrue: [ aSequentialCollection class==self class - ifTrue: [ ^ self permute: (aSequentialCollection extendTo: self size) ] - ifFalse: [ ^ SizeMismatch signal ] ]. + (s := aSequentialCollection size) < self size ifTrue: [ + ^ aSequentialCollection class == self class + ifTrue: [ self permute: (aSequentialCollection extendTo: self size) ] + ifFalse: [ SizeMismatch signal ] ]. c := aSequentialCollection copy. 1 to: self size do: [ :i | c at: i put: (aSequentialCollection at: (self at: i)) ]. ^ c @@ -261,5 +263,5 @@ PMPermutation >> shift: anInteger [ { #category : #private } PMPermutation >> species [ - ^ Array + ^ Array ] diff --git a/src/Math-Physics-Constants/PMConstant.class.st b/src/Math-Physics-Constants/PMConstant.class.st index 53a894f5a..bb3a007ca 100644 --- a/src/Math-Physics-Constants/PMConstant.class.st +++ b/src/Math-Physics-Constants/PMConstant.class.st @@ -103,9 +103,9 @@ PMConstant class >> h [ ^ PlanckConstant ] -{ #category : #'class initialization' } +{ #category : #initialization } PMConstant class >> initialize [ - + AvogadroConstant := 6.022140857e23. BoltzmannConstant := 1.38064852e-23. StefanBoltzmannConstant := 5.670367e-8. @@ -123,7 +123,7 @@ PMConstant class >> initialize [ speedOfLight := 299792458.0. standardAccelerationOfGravity := 9.80665. WienDisplacementLawConstant := 2.8977729e-3. - RydbergConstant := 10973731.568508. + RydbergConstant := 10973731.568508 ] { #category : #constants } diff --git a/src/Math-Polynomials/PMEstimatedPolynomial.class.st b/src/Math-Polynomials/PMEstimatedPolynomial.class.st index 875441c59..e9efc714f 100644 --- a/src/Math-Polynomials/PMEstimatedPolynomial.class.st +++ b/src/Math-Polynomials/PMEstimatedPolynomial.class.st @@ -4,7 +4,7 @@ Class { #instVars : [ 'errorMatrix' ], - #category : 'Math-Polynomials' + #category : #'Math-Polynomials' } { #category : #information } @@ -24,7 +24,7 @@ PMEstimatedPolynomial >> errorMatrix [ { #category : #initialization } PMEstimatedPolynomial >> errorMatrix: aMatrix [ "Defines the error matrix of the receiver." - errorMatrix := aMatrix. + errorMatrix := aMatrix ] { #category : #information } diff --git a/src/Math-Polynomials/PMPolynomial.class.st b/src/Math-Polynomials/PMPolynomial.class.st index 6ce3dafc5..3ba7997de 100644 --- a/src/Math-Polynomials/PMPolynomial.class.st +++ b/src/Math-Polynomials/PMPolynomial.class.st @@ -17,7 +17,7 @@ Class { #instVars : [ 'coefficients' ], - #category : 'Math-Polynomials' + #category : #'Math-Polynomials' } { #category : #creation } @@ -34,7 +34,7 @@ PMPolynomial >> * aNumberOrPolynomial [ { #category : #operation } PMPolynomial >> + aNumberOrPolynomial [ - + ^aNumberOrPolynomial addPolynomial: self ] @@ -46,12 +46,12 @@ PMPolynomial >> - aNumberOrPolynomial [ { #category : #operation } PMPolynomial >> / aNumberOrPolynomial [ - + ^aNumberOrPolynomial dividingPolynomial: self ] { #category : #comparing } -PMPolynomial >> = aNumberOrPolynomial [ +PMPolynomial >> = aNumberOrPolynomial [ ^(aNumberOrPolynomial class = self class) and: [self coefficients = aNumberOrPolynomial coefficients] ] @@ -62,7 +62,7 @@ PMPolynomial >> adaptToNumber: rcvr andSend: selector [ { #category : #'double dispatching' } PMPolynomial >> addNumber: aNumber [ - + | newCoefficients | newCoefficients := coefficients reverse. newCoefficients at: 1 put: newCoefficients first + aNumber. @@ -71,7 +71,7 @@ PMPolynomial >> addNumber: aNumber [ { #category : #'double dispatching' } PMPolynomial >> addPolynomial: aPolynomial [ - + ^self class coefficients: ( ( 0 to: (self degree max: aPolynomial degree)) collect: [ :n | ( aPolynomial at: n) + ( self at: n)]) ] @@ -96,7 +96,7 @@ PMPolynomial >> deflatedAt: aNumber [ remainder := 0. newCoefficients := coefficients collect: [ :each | - next := remainder. + next := remainder. remainder := remainder * aNumber + each. next]. ^self class coefficients: ( newCoefficients copyFrom: 2 to: newCoefficients size) reverse @@ -118,13 +118,13 @@ PMPolynomial >> derivative [ { #category : #'double dispatching' } PMPolynomial >> dividingPolynomial: aPolynomial [ - + ^( self dividingPolynomialWithRemainder: aPolynomial) first ] { #category : #'double dispatching' } PMPolynomial >> dividingPolynomialWithRemainder: aPolynomial [ - + | remainderCoefficients quotientCoefficients n m norm quotientDegree | n := self degree. m := aPolynomial degree. @@ -140,8 +140,8 @@ PMPolynomial >> dividingPolynomialWithRemainder: aPolynomial [ x := ( remainderCoefficients at: n + k + 1) * norm. quotientCoefficients at: (quotientDegree + 1 - k) put: x. (n + k - 1) to: k by: -1 - do: [ :j | - remainderCoefficients at: j + 1 put: + do: [ :j | + remainderCoefficients at: j + 1 put: ( ( remainderCoefficients at: j + 1) - ( x * (self at: j - k))) ]. ]. @@ -164,7 +164,7 @@ PMPolynomial >> initialize [ { #category : #initialization } PMPolynomial >> initialize: anArray [ - + coefficients := anArray. ^self ] @@ -185,28 +185,28 @@ PMPolynomial >> integral: aValue [ { #category : #operation } PMPolynomial >> isZero [ - ^ self coefficients allSatisfy: [:ea | ea = 0]. + ^ self coefficients allSatisfy: [:ea | ea = 0] ] { #category : #operation } PMPolynomial >> negated [ - ^ self * -1. + ^ self * -1 ] { #category : #printing } -PMPolynomial >> printOn: aStream [ +PMPolynomial >> printOn: aStream [ "Append to aStream a written representation of the receiver." | n firstNonZeroCoefficientPrinted | n := 0. firstNonZeroCoefficientPrinted := false. coefficients - reverseDo: - [:each | + reverseDo: + [:each | each = 0 - ifFalse: + ifFalse: [firstNonZeroCoefficientPrinted - ifTrue: + ifTrue: [aStream space. ((each respondsTo: #< ) and: [each < 0]) ifFalse: [aStream nextPut: $+]. aStream space] @@ -214,16 +214,16 @@ PMPolynomial >> printOn: aStream [ (each = 1 and: [n > 0]) ifFalse: [each printOn: aStream]. n > 0 - ifTrue: + ifTrue: [aStream nextPutAll: ' X'. n > 1 - ifTrue: + ifTrue: [aStream nextPut: $^. n printOn: aStream]]]. n := n + 1]. - + "add a quick check, print a zero if the polynomial has all zero coefficients" - firstNonZeroCoefficientPrinted ifFalse: [0 printOn: aStream]. + firstNonZeroCoefficientPrinted ifFalse: [0 printOn: aStream] ] { #category : #operation } @@ -233,7 +233,7 @@ PMPolynomial >> reciprocal [ { #category : #information } PMPolynomial >> roots [ - + ^self roots: PMFloatingPointMachine new defaultNumericalPrecision ] @@ -248,8 +248,8 @@ PMPolynomial >> roots: aNumber [ [ rootFinder setFunction: pol; setDerivative: pol derivative. x := rootFinder evaluate. rootFinder hasConverged - ] whileTrue: [ roots add: x. - pol := pol deflatedAt: x. + ] whileTrue: [ roots add: x. + pol := pol deflatedAt: x. pol degree > 0 ifFalse: [ ^roots]. ]. @@ -264,13 +264,13 @@ PMPolynomial >> subtractToPolynomial: aPolynomial [ { #category : #'double dispatching' } PMPolynomial >> timesNumber: aNumber [ - + ^self class coefficients: ( coefficients reverse collect: [ :each | each * aNumber]) ] { #category : #'double dispatching' } PMPolynomial >> timesPolynomial: aPolynomial [ - + | productCoefficients degree| degree := aPolynomial degree + self degree. productCoefficients := ( degree to: 0 by: -1) diff --git a/src/Math-PrincipalComponentAnalysis/PMDataTransformer.class.st b/src/Math-PrincipalComponentAnalysis/PMDataTransformer.class.st index f3e9b4438..90d715c76 100644 --- a/src/Math-PrincipalComponentAnalysis/PMDataTransformer.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMDataTransformer.class.st @@ -8,12 +8,12 @@ Class { #category : #'Math-PrincipalComponentAnalysis' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMDataTransformer >> fit: aPMMatrix [ ^ self subclassResponsibility ] -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMDataTransformer >> fitAndTransform: aPMMatrix [ ^ (self fit: aPMMatrix) transform: aPMMatrix ] diff --git a/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserJacobiTransformation.class.st b/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserJacobiTransformation.class.st index 76f96958e..aa699459f 100644 --- a/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserJacobiTransformation.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserJacobiTransformation.class.st @@ -20,7 +20,7 @@ Class { { #category : #'instance creation' } PMPrincipalComponentAnalyserJacobiTransformation class >> new: anInteger [ "anInteger is the size of the elements you will accumulate: the elements you want to compare using the component analysis." - ^ self basicNew initialize: anInteger; yourself. + ^ self basicNew initialize: anInteger; yourself ] { #category : #transformation } diff --git a/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserSVD.class.st b/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserSVD.class.st index 01571bbe4..1ec347da3 100644 --- a/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserSVD.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserSVD.class.st @@ -32,7 +32,7 @@ m1 := pca transform: m. d1 := DataFrame fromRows: m1 rows. d1 addColumn: ((DataFrame loadIris) columnsFrom:5 to:5) asArrayOfColumns first named:''. -d1 scatterplotMatrix. +d1 scatterplotMatrix ] { #category : #accessing } @@ -48,12 +48,12 @@ PMPrincipalComponentAnalyserSVD >> fit: aPMMatrix [ PMPrincipalComponentAnalyserSVD >> flipEigenvectorsSign [ "flip eigenvectors sign to enforce deterministic output" "U-based decision like : https://github.com/scikit-learn/scikit-learn/blob/4c65d8e615c9331d37cbb6225c5b67c445a5c959/sklearn/utils/extmath.py#L609" - + | algo | algo := PMSciKitLearnSVDFlipAlgorithm flipU: u andV: v. - - u := algo uFlipped . - v := algo vFlipped . + + u := algo uFlipped . + v := algo vFlipped . ] { #category : #accessing } diff --git a/src/Math-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithm.class.st b/src/Math-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithm.class.st index 1edaf980a..b442cd5e2 100644 --- a/src/Math-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithm.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithm.class.st @@ -28,11 +28,11 @@ PMSciKitLearnSVDFlipAlgorithm >> computeSignsFromU [ | maxAbsCols i maxElements | maxAbsCols := u abs argMaxOnColumns. i := 0. - maxElements := u transpose - rowsCollect: [ :each | + maxElements := u transpose + rowsCollect: [ :each | i := i + 1. each at: (maxAbsCols at: i) ]. - ^ maxElements sign asPMVector + ^ maxElements sign asPMVector ] { #category : #initialization } @@ -40,9 +40,7 @@ PMSciKitLearnSVDFlipAlgorithm >> initializeWithU: uMatrix andV: vMatrix [ "instantiate the algorithm" u := uMatrix . v := vMatrix . - signs := self computeSignsFromU . - - + signs := self computeSignsFromU ] { #category : #accessing } @@ -51,7 +49,7 @@ PMSciKitLearnSVDFlipAlgorithm >> signMatrixForU [ rows: ((1 to: u numberOfRows) inject: OrderedCollection new - into: [ :rows :eachRow | + into: [ :rows :eachRow | rows add: signs; yourself ]) @@ -65,7 +63,7 @@ PMSciKitLearnSVDFlipAlgorithm >> signMatrixForV [ rows: ((1 to: v numberOfRows) inject: OrderedCollection new - into: [ :rows :eachRow | + into: [ :rows :eachRow | rows add: signsForV; yourself ])) transpose @@ -78,10 +76,10 @@ PMSciKitLearnSVDFlipAlgorithm >> signs [ { #category : #accessing } PMSciKitLearnSVDFlipAlgorithm >> uFlipped [ - ^ u hadamardProduct: (self signMatrixForU). + ^ u hadamardProduct: (self signMatrixForU) ] { #category : #accessing } PMSciKitLearnSVDFlipAlgorithm >> vFlipped [ - ^ v hadamardProduct: (self signMatrixForV) . + ^ v hadamardProduct: (self signMatrixForV) ] diff --git a/src/Math-PrincipalComponentAnalysis/PMStandardizationScaler.class.st b/src/Math-PrincipalComponentAnalysis/PMStandardizationScaler.class.st index 78241d614..e4619c715 100644 --- a/src/Math-PrincipalComponentAnalysis/PMStandardizationScaler.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMStandardizationScaler.class.st @@ -7,7 +7,7 @@ Class { #category : #'Math-PrincipalComponentAnalysis' } -{ #category : #'as yet unclassified' } +{ #category : #accessing } PMStandardizationScaler >> fit: aPMMatrix [ "Compute the mean and the scale of a PMMatrix (in order to have a std of 1)" @@ -32,7 +32,7 @@ PMStandardizationScaler >> scale [ { #category : #transforming } PMStandardizationScaler >> transform: aPMMatrix [ "Perform standardization by centering and scaling" - + |mean scale| mean := self mean. scale := self scale. diff --git a/src/Math-Quaternion/Number.extension.st b/src/Math-Quaternion/Number.extension.st index 405621767..116e642b9 100644 --- a/src/Math-Quaternion/Number.extension.st +++ b/src/Math-Quaternion/Number.extension.st @@ -1,14 +1,14 @@ Extension { #name : #Number } { #category : #'*Math-Quaternion' } -Number >> adaptToQuaternion: rcvr andSend: selector [ +Number >> adaptToQuaternion: rcvr andSend: selector [ "If I am involved in arithmetic with a Quaternion, convert me to a Quaternion." ^ rcvr perform: selector with: self asQuaternion ] { #category : #'*Math-Quaternion' } Number >> asQuaternion [ - ^PMQuaternion + ^PMQuaternion qr: self qi: 0 qj: 0 @@ -16,8 +16,8 @@ Number >> asQuaternion [ ] { #category : #'*Math-Quaternion' } -Number >> i: qi j: qj k: qk [ - ^PMQuaternion +Number >> i: qi j: qj k: qk [ + ^PMQuaternion qr: self qi: qi qj: qj @@ -26,7 +26,7 @@ Number >> i: qi j: qj k: qk [ { #category : #'*Math-Quaternion' } Number >> j [ - ^PMQuaternion + ^PMQuaternion qr: 0 qi: 0 qj: self @@ -35,7 +35,7 @@ Number >> j [ { #category : #'*Math-Quaternion' } Number >> k [ - ^PMQuaternion + ^PMQuaternion qr: 0 qi: 0 qj: 0 @@ -44,5 +44,5 @@ Number >> k [ { #category : #'*Math-Quaternion' } Number >> multiplyByQuaternion: quaternion [ - ^ quaternion timesNumber: self. + ^ quaternion timesNumber: self ] diff --git a/src/Math-Quaternion/Object.extension.st b/src/Math-Quaternion/Object.extension.st index deca44132..dd119e2f8 100644 --- a/src/Math-Quaternion/Object.extension.st +++ b/src/Math-Quaternion/Object.extension.st @@ -5,5 +5,4 @@ Object >> isQuaternion [ "Answer true if receiver is a Quaternion. False by default." ^ false - ] diff --git a/src/Math-Quaternion/PMComplexNumber.extension.st b/src/Math-Quaternion/PMComplexNumber.extension.st index 27f584a0d..4aba358a9 100644 --- a/src/Math-Quaternion/PMComplexNumber.extension.st +++ b/src/Math-Quaternion/PMComplexNumber.extension.st @@ -1,7 +1,7 @@ Extension { #name : #PMComplexNumber } { #category : #'*Math-Quaternion' } -PMComplexNumber >> adaptToQuaternion: rcvr andSend: selector [ +PMComplexNumber >> adaptToQuaternion: rcvr andSend: selector [ "If I am involved in arithmetic with a Quaternion, convert me to a Quaternion." ^ rcvr perform: selector with: self asQuaternion ] @@ -19,7 +19,7 @@ PMComplexNumber >> asQuaternion [ PMComplexNumber >> j [ "same as self * 1 j" - ^PMQuaternion + ^PMQuaternion qr: 0 qi: 0 qj: real @@ -30,7 +30,7 @@ PMComplexNumber >> j [ PMComplexNumber >> k [ "same as self * 1 k" - ^PMQuaternion + ^PMQuaternion qr: 0 qi: 0 qj: imaginary negated diff --git a/src/Math-Quaternion/PMQuaternion.class.st b/src/Math-Quaternion/PMQuaternion.class.st index 00f8d1b52..fbf592e95 100644 --- a/src/Math-Quaternion/PMQuaternion.class.st +++ b/src/Math-Quaternion/PMQuaternion.class.st @@ -39,7 +39,7 @@ Class { { #category : #'constants access' } PMQuaternion class >> one [ - ^self + ^self qr: 1 qi: 0 qj: 0 @@ -47,8 +47,8 @@ PMQuaternion class >> one [ ] { #category : #'instance creation' } -PMQuaternion class >> qr: qr qi: qi qj: qj qk: qk [ - ^self basicNew +PMQuaternion class >> qr: qr qi: qi qj: qj qk: qk [ + ^self basicNew qr: qr qi: qi qj: qj @@ -58,19 +58,19 @@ PMQuaternion class >> qr: qr qi: qi qj: qj qk: qk [ { #category : #information } PMQuaternion class >> random [ "Answers a random quaternion with abs at most one." - + | random | random := Random new. - ^ (0.5 - random next) + ^ (0.5 - random next) i: (0.5 - random next) j: (0.5 - random next) - k: (0.5 - random next). + k: (0.5 - random next) ] { #category : #'constants access' } PMQuaternion class >> zero [ - ^self + ^self qr: 0 qi: 0 qj: 0 @@ -83,11 +83,11 @@ PMQuaternion >> * multiplier [ "Answer the result of multiplying self with aQuaternion. Distribute the product (qr + qi i +qj j + qk k)*(tr+ti i + tj j + tk k) with rules i*i=j*j=k*k=-1 and i*j=-k, j*k=-i, k*i=-j" - ^ multiplier multiplyByQuaternion: self. + ^ multiplier multiplyByQuaternion: self ] { #category : #arithmetic } -PMQuaternion >> + aQuaternion [ +PMQuaternion >> + aQuaternion [ ^ aQuaternion isQuaternion ifTrue: [self species qr: qr + aQuaternion qr @@ -98,7 +98,7 @@ PMQuaternion >> + aQuaternion [ ] { #category : #arithmetic } -PMQuaternion >> - aQuaternion [ +PMQuaternion >> - aQuaternion [ ^ aQuaternion isQuaternion ifTrue: [self species qr: qr - aQuaternion qr @@ -114,7 +114,7 @@ PMQuaternion >> / aQuaternion [ ] { #category : #comparing } -PMQuaternion >> = aQuaternion [ +PMQuaternion >> = aQuaternion [ "Answer true if both quaternion are equals. A quaternion might also equal a Complex or a Number or other kind of numbers. Implementation note: only work if Complex Octonion or other kind answer true to isNumber." @@ -135,10 +135,10 @@ PMQuaternion >> abs [ | scale | scale := (qr abs max: qi abs) max: (qj abs max: qk abs). - ^scale isZero + ^scale isZero ifTrue: [scale] - ifFalse: - [(self species + ifFalse: + [(self species qr: qr / scale qi: qi / scale qj: qj / scale @@ -146,25 +146,25 @@ PMQuaternion >> abs [ ] { #category : #converting } -PMQuaternion >> adaptToComplex: rcvr andSend: selector [ +PMQuaternion >> adaptToComplex: rcvr andSend: selector [ "If I am involved in arithmetic with a Complex, convert it to a Quaternion." ^ rcvr asQuaternion perform: selector with: self ] { #category : #converting } -PMQuaternion >> adaptToFloat: rcvr andSend: selector [ +PMQuaternion >> adaptToFloat: rcvr andSend: selector [ "If I am involved in arithmetic with a Float, convert it to a Quaternion." ^ rcvr asQuaternion perform: selector with: self ] { #category : #converting } -PMQuaternion >> adaptToFraction: rcvr andSend: selector [ +PMQuaternion >> adaptToFraction: rcvr andSend: selector [ "If I am involved in arithmetic with a Fraction, convert it to a Quaternion." ^ rcvr asQuaternion perform: selector with: self ] { #category : #converting } -PMQuaternion >> adaptToInteger: rcvr andSend: selector [ +PMQuaternion >> adaptToInteger: rcvr andSend: selector [ "If I am involved in arithmetic with an Integer, convert it to a Quaternion." ^ rcvr asQuaternion perform: selector with: self ] @@ -203,7 +203,7 @@ PMQuaternion >> asQuaternion [ PMQuaternion >> conjugated [ "Return the conjugate of this quaternion number." - ^self species + ^self species qr: qr qi: qi negated qj: qj negated @@ -219,7 +219,7 @@ PMQuaternion >> cos [ w := z isZero ifTrue: [z] ifFalse: [qr sin negated * z sinh / z]. - ^(self species + ^(self species qr: qr cos * z cosh qi: qi * w qj: qj * w @@ -247,7 +247,7 @@ PMQuaternion >> exp [ w := z isZero ifTrue: [z] ifFalse: [z sin / z]. - ^qr exp * (self species + ^qr exp * (self species qr: z cos qi: qi * w qj: qj * w @@ -274,7 +274,7 @@ PMQuaternion >> i [ "Answer the product of the receiver with pure imaginary i. This is the same as self * 1 i" - ^self species + ^self species qr: qi negated qi: qr qj: qk @@ -309,7 +309,7 @@ PMQuaternion >> j [ This is the same as self * 1 j" - ^self species + ^self species qr: qj negated qi: qk negated qj: qr @@ -322,7 +322,7 @@ PMQuaternion >> k [ This is the same as self * 1 k" - ^self species + ^self species qr: qk negated qi: qj qj: qi negated @@ -337,11 +337,11 @@ PMQuaternion >> ln [ | z | z := self unreal abs. ^ z isZero - ifTrue: [ + ifTrue: [ | vectorPart | vectorPart := 0 + (z arcTan: qr) i + qj j + qk k. self abs ln + vectorPart ] - ifFalse: [ + ifFalse: [ | theta vectorPart | theta := (z arcTan: qr) / z. vectorPart := theta * (0 + qi i + qj j + qk k). @@ -373,7 +373,7 @@ PMQuaternion >> multiplyByQuaternion: multiplier [ { #category : #arithmetic } PMQuaternion >> negated [ - ^self species + ^self species qr: qr negated qi: qi negated qj: qj negated @@ -381,7 +381,7 @@ PMQuaternion >> negated [ ] { #category : #printing } -PMQuaternion >> printOn: aStream [ +PMQuaternion >> printOn: aStream [ "Print a representation of the receiver onto aStream" self storeOn: aStream @@ -414,7 +414,7 @@ PMQuaternion >> qr [ ] { #category : #private } -PMQuaternion >> qr: a0 qi: a1 qj: a2 qk: a3 [ +PMQuaternion >> qr: a0 qi: a1 qj: a2 qk: a3 [ qr := a0. qi := a1. qj := a2. @@ -422,24 +422,22 @@ PMQuaternion >> qr: a0 qi: a1 qj: a2 qk: a3 [ ] { #category : #'mathematical functions' } -PMQuaternion >> raisedTo: aNumber [ +PMQuaternion >> raisedTo: aNumber [ "Answer the receiver raised to aNumber." - aNumber isInteger ifTrue: - ["Do the special case of integer power" - ^ self raisedToInteger: aNumber]. - - 0 = aNumber ifTrue: [^ self class one]. "Special case of exponent=0" - 1 = aNumber ifTrue: [^ self]. "Special case of exponent=1" - 0 = self ifTrue: [ "Special case of self = 0" - aNumber < 0 - ifTrue: [^ (ZeroDivide dividend: self) signal] - ifFalse: [^ self]]. - ^ (aNumber * self ln) exp "Otherwise use logarithms" + aNumber isInteger ifTrue: [ "Do the special case of integer power" ^ self raisedToInteger: aNumber ]. + + 0 = aNumber ifTrue: [ ^ self class one ]. "Special case of exponent=0" + 1 = aNumber ifTrue: [ ^ self ]. "Special case of exponent=1" + 0 = self ifTrue: [ "Special case of self = 0" + ^ aNumber < 0 + ifTrue: [ (ZeroDivide dividend: self) signal ] + ifFalse: [ self ] ]. + ^ (aNumber * self ln) exp "Otherwise use logarithms" ] { #category : #'mathematical functions' } -PMQuaternion >> raisedToInteger: operand [ +PMQuaternion >> raisedToInteger: operand [ "Answer the receiver raised to the power operand, an Integer." "implementation note: this code is copied from Number. @@ -455,7 +453,7 @@ PMQuaternion >> raisedToInteger: operand [ count := 1 bitShift: (operand-1) highBit. result := self class one. [count > 0] - whileTrue: + whileTrue: [result := result * result. (operand bitAnd: count) = 0 ifFalse: [result := result * self]. @@ -466,7 +464,7 @@ PMQuaternion >> raisedToInteger: operand [ { #category : #information } PMQuaternion >> random [ "analog to Number>>random. The resulting quaternion will have abs at most that of the receiver" - ^ self class random * self. + ^ self class random * self ] { #category : #accessing } @@ -484,8 +482,8 @@ PMQuaternion >> reciprocal [ | qn qrn qin qjn qkn qn2 | qn := (qr abs max: qi abs) max: (qj abs max: qk abs). - qn isZero - ifTrue: + qn isZero + ifTrue: [^ZeroDivide signal: 'Cannot take reciprocal of null quaternion']. qrn := qr / qn. qin := qi / qn. @@ -516,7 +514,7 @@ PMQuaternion >> sin [ w := z isZero ifTrue: [z] ifFalse: [qr cos * z sinh / z]. - ^(self species + ^(self species qr: qr sin * z cosh qi: qi * w qj: qj * w @@ -541,7 +539,7 @@ PMQuaternion >> squaredNorm [ ] { #category : #printing } -PMQuaternion >> storeOn: aStream [ +PMQuaternion >> storeOn: aStream [ "Store a representation of the receiver onto aStream that can be interpreted. Two possible forms are: a + b i + c j + d k @@ -606,7 +604,7 @@ PMQuaternion >> timesComplexNumber: complexNumber [ { #category : #arithmetic } PMQuaternion >> timesNumber: multiplier [ - ^ self class qr: (qr * multiplier) qi: (qi * multiplier) qj: (qj * multiplier) qk: (qk * multiplier). + ^ self class qr: (qr * multiplier) qi: (qi * multiplier) qj: (qj * multiplier) qk: (qk * multiplier) ] { #category : #'double dispatch' } @@ -618,7 +616,7 @@ PMQuaternion >> timesPolynomial: aPolynomial [ PMQuaternion >> unreal [ "answer the unreal part of the receiver" - ^self species + ^self species qr: 0 qi: qi qj: qj diff --git a/src/Math-Quaternion/PMVector.extension.st b/src/Math-Quaternion/PMVector.extension.st index b446e6dee..cc10b83b7 100644 --- a/src/Math-Quaternion/PMVector.extension.st +++ b/src/Math-Quaternion/PMVector.extension.st @@ -8,5 +8,5 @@ PMVector >> adaptToQuaternion: aQuaternion andSend: aByteSymbol [ { #category : #'*Math-Quaternion' } PMVector >> multiplyByQuaternion: quaternion [ - ^ self * quaternion. + ^ self * quaternion ] diff --git a/src/Math-StatisticalMoments/PMFastStatisticalMoments.class.st b/src/Math-StatisticalMoments/PMFastStatisticalMoments.class.st index 1b1697faf..7d8d75300 100644 --- a/src/Math-StatisticalMoments/PMFastStatisticalMoments.class.st +++ b/src/Math-StatisticalMoments/PMFastStatisticalMoments.class.st @@ -1,16 +1,16 @@ Class { #name : #PMFastStatisticalMoments, #superclass : #PMStatisticalMoments, - #category : 'Math-StatisticalMoments' + #category : #'Math-StatisticalMoments' } { #category : #transformation } -PMFastStatisticalMoments >> accumulate: aNumber [ +PMFastStatisticalMoments >> accumulate: aNumber [ | var | var := 1. 1 to: moments size - do: - [:n | + do: + [:n | moments at: n put: (moments at: n) + var. var := var * aNumber] ] @@ -51,7 +51,7 @@ PMFastStatisticalMoments >> skewness [ x1 := (moments at: 2) / n. x2 := (moments at: 3) / n. x3 := (moments at: 4) / n. - ^(x3 - (3 * x1 * x2) + (2 * x1 * x1 * x1)) * n * n + ^(x3 - (3 * x1 * x2) + (2 * x1 * x1 * x1)) * n * n / (stdev squared * stdev * (n - 1) * (n - 2)) ] diff --git a/src/Math-StatisticalMoments/PMFixedStatisticalMoments.class.st b/src/Math-StatisticalMoments/PMFixedStatisticalMoments.class.st index 81e72b206..5fce63f67 100644 --- a/src/Math-StatisticalMoments/PMFixedStatisticalMoments.class.st +++ b/src/Math-StatisticalMoments/PMFixedStatisticalMoments.class.st @@ -1,7 +1,7 @@ Class { #name : #PMFixedStatisticalMoments, #superclass : #PMStatisticalMoments, - #category : 'Math-StatisticalMoments' + #category : #'Math-StatisticalMoments' } { #category : #creation } @@ -15,7 +15,7 @@ PMFixedStatisticalMoments class >> new: anInteger [ ] { #category : #transformation } -PMFixedStatisticalMoments >> accumulate: aNumber [ +PMFixedStatisticalMoments >> accumulate: aNumber [ | correction n n1 c2 c3 | n := moments at: 1. n1 := n + 1. @@ -24,12 +24,12 @@ PMFixedStatisticalMoments >> accumulate: aNumber [ c3 := c2 * correction. moments at: 5 - put: ((moments at: 5) + ((moments at: 4) * correction * 4) - + ((moments at: 3) * c2 * 6) + (c2 squared * (n squared * n + 1))) + put: ((moments at: 5) + ((moments at: 4) * correction * 4) + + ((moments at: 3) * c2 * 6) + (c2 squared * (n squared * n + 1))) * n / n1; at: 4 - put: ((moments at: 4) + ((moments at: 3) * correction * 3) - + (c3 * (1 - n squared))) * n + put: ((moments at: 4) + ((moments at: 3) * correction * 3) + + (c3 * (1 - n squared))) * n / n1; at: 3 put: ((moments at: 3) + (c2 * (1 + n))) * n / n1; at: 2 put: (moments at: 2) - correction; diff --git a/src/Math-StatisticalMoments/PMHistogram.class.st b/src/Math-StatisticalMoments/PMHistogram.class.st index 49898d963..2fc33c9fc 100644 --- a/src/Math-StatisticalMoments/PMHistogram.class.st +++ b/src/Math-StatisticalMoments/PMHistogram.class.st @@ -22,7 +22,7 @@ Class { 'cacheSize', 'desiredNumberOfBins' ], - #category : 'Math-StatisticalMoments' + #category : #'Math-StatisticalMoments' } { #category : #information } @@ -70,7 +70,7 @@ PMHistogram >> accumulate: aNumber [ ifTrue: [ ^ self accumulateInCache: aNumber ]. bin := self binIndex: aNumber. (bin between: 1 and: contents size) - ifTrue: [ + ifTrue: [ contents at: bin put: (contents at: bin) + 1. moments accumulate: aNumber ] ifFalse: [ self processOverflows: bin for: aNumber ] @@ -93,7 +93,7 @@ PMHistogram >> adjustDimensionUpTo: aNumber [ | maximum | binWidth := self roundToScale: (aNumber - minimum) / desiredNumberOfBins. minimum := (minimum / binWidth) floor * binWidth. - maximum := (aNumber / binWidth) asFloat successor ceiling * binWidth. + maximum := (aNumber / binWidth) asFloat successor ceiling * binWidth. contents := Array new: ((maximum - minimum) / binWidth) ceiling. contents atAllPut: 0 ] @@ -108,7 +108,7 @@ PMHistogram >> average [ { #category : #information } PMHistogram >> binIndex: aNumber [ "Answers the index of the bin corresponding to aNumber." - + ^ ((aNumber - minimum) / binWidth) floor + 1 ] @@ -139,7 +139,7 @@ PMHistogram >> chi2ConfidenceLevelAgainst: aScaledDistribution [ { #category : #information } PMHistogram >> collectIntegralPoints: aBlock [ - "Collects the points needed to display the receiver as an integral. + "Collects the points needed to display the receiver as an integral. Needed to use polymorphic behavior when plotting the receiver." | answer bin integral norm x | @@ -151,7 +151,7 @@ PMHistogram >> collectIntegralPoints: aBlock [ integral := self underflow. norm := self totalCount. contents - do: [ :each | + do: [ :each | integral := integral + each. x := integral / norm. answer add: (aBlock value: bin @ x). @@ -173,7 +173,7 @@ PMHistogram >> collectPoints: aBlock [ bin := self minimum. answer add: (aBlock value: bin @ 0). contents - do: [ :each | + do: [ :each | answer add: (aBlock value: bin @ each). bin := bin + binWidth. answer add: (aBlock value: bin @ each) ]. @@ -192,7 +192,7 @@ PMHistogram >> count [ PMHistogram >> countAt: aNumber [ "Answer the count in the bin corresponding to aNumber or 0 if outside the limits." | n | - self isCached + self isCached ifTrue: [ self flushCache]. n := self binIndex: aNumber. ^( n between: 1 and: contents size) @@ -262,21 +262,13 @@ PMHistogram >> flushCache [ "Private" | maximum values | - minimum isNil - ifTrue: [ - minimum := contents isEmpty - ifTrue: [ 0 ] - ifFalse: [ contents first ] ]. + minimum ifNil: [ minimum := contents ifEmpty: [ 0 ] ifNotEmpty: [ contents first ] ]. maximum := minimum. - contents - do: [ :each | - each < minimum - ifTrue: [ minimum := each ] - ifFalse: [ - each > maximum - ifTrue: [ maximum := each ] ] ]. - maximum = minimum - ifTrue: [ maximum := minimum + desiredNumberOfBins ]. + contents do: [ :each | + each < minimum + ifTrue: [ minimum := each ] + ifFalse: [ each > maximum ifTrue: [ maximum := each ] ] ]. + maximum = minimum ifTrue: [ maximum := minimum + desiredNumberOfBins ]. values := contents. self adjustDimensionUpTo: maximum. values do: [ :each | self accumulate: each ] @@ -339,6 +331,8 @@ PMHistogram >> growPositiveContents: anInteger [ PMHistogram >> initialize [ "Private - initializes the receiver with standard settings." + super initialize. + freeExtent := false. cacheSize := self class defaultCacheSize. desiredNumberOfBins := self class defaultNumberOfBins. @@ -358,7 +352,7 @@ PMHistogram >> inverseDistributionValue: aNumber [ x := minimum. integral := 0. contents - do: [ :each | + do: [ :each | | delta | delta := count - integral. each > delta @@ -377,7 +371,7 @@ PMHistogram >> isCached [ { #category : #testing } PMHistogram >> isEmpty [ - "Always false. + "Always false. Needed to use polymorphic behavior when plotting the receiver. " ^ false @@ -392,7 +386,7 @@ PMHistogram >> kurtosis [ { #category : #information } PMHistogram >> lowBinLimitAt: anInteger [ - self isCached + self isCached ifTrue: [ self flushCache]. ^( anInteger - 1) * binWidth + minimum ] @@ -407,11 +401,10 @@ PMHistogram >> maximum [ { #category : #information } PMHistogram >> maximumCount [ - "Answer the maximum count of the receiver." - self isCached - ifTrue: [ self flushCache]. - ^contents inject: ( contents isEmpty ifTrue: [ 1] ifFalse:[ contents at: 1]) - into: [ :max :each | max max: each] + "Answer the maximum count of the receiver." + + self isCached ifTrue: [ self flushCache ]. + ^ contents inject: (contents ifEmpty: [ 1 ] ifNotEmpty: [ contents at: 1 ]) into: [ :max :each | max max: each ] ] { #category : #information } @@ -441,7 +434,7 @@ PMHistogram >> pointsAndErrorsDo: aBlock [ | x | x := self minimum - (binWidth / 2). contents - do: [ :each | + do: [ :each | x := x + binWidth. aBlock value: (PMWeightedPoint point: x count: each) ] ] @@ -451,7 +444,7 @@ PMHistogram >> processOverflows: anInteger for: aNumber [ "Private" freeExtent - ifTrue: [ + ifTrue: [ self growContents: anInteger. moments accumulate: aNumber ] ifFalse: [ self countOverflows: anInteger ] @@ -505,7 +498,7 @@ PMHistogram >> setWidth: aNumber1 from: aNumber2 bins: anInteger [ ifFalse: [ self error: 'Histogram limits cannot be redefined']. minimum := aNumber2. self setDesiredNumberOfBins: anInteger; - adjustDimensionUpTo: ( aNumber1 * anInteger + aNumber2). + adjustDimensionUpTo: ( aNumber1 * anInteger + aNumber2) ] { #category : #information } diff --git a/src/Math-StatisticalMoments/PMStatisticalMoments.class.st b/src/Math-StatisticalMoments/PMStatisticalMoments.class.st index 0380ab5e9..bc6370722 100644 --- a/src/Math-StatisticalMoments/PMStatisticalMoments.class.st +++ b/src/Math-StatisticalMoments/PMStatisticalMoments.class.st @@ -4,7 +4,7 @@ Class { #instVars : [ 'moments' ], - #category : 'Math-StatisticalMoments' + #category : #'Math-StatisticalMoments' } { #category : #creation } @@ -40,11 +40,11 @@ PMStatisticalMoments >> accumulate: aNumber [ cTerm := correction. n1 := n / n1. n := n negated. - 3 to: moments size do: [ :k | + 3 to: moments size do: [ :k | cTerm := cTerm * correction. nTerm := n * nTerm. term := cTerm * (1 + nTerm). - k to: 3 by: -1 do: [ :l | + k to: 3 by: -1 do: [ :l | pascal at: l put: (pascal at: l - 1) + (pascal at: l). term := (pascal at: l) * (oldSums at: l) + term. oldSums at: l put: (oldSums at: l) * correction ]. @@ -90,15 +90,15 @@ PMStatisticalMoments >> fConfidenceLevel: aStatisticalMomentsOrHistogram [ fValue := self variance/ aStatisticalMomentsOrHistogram variance. ^fValue < 1 ifTrue: [ (PMFisherSnedecorDistribution degreeOfFreedom: aStatisticalMomentsOrHistogram count - degreeOfFreedom: self count) + degreeOfFreedom: self count) confidenceLevel: fValue reciprocal] ifFalse:[ (PMFisherSnedecorDistribution degreeOfFreedom: self count - degreeOfFreedom: aStatisticalMomentsOrHistogram count) + degreeOfFreedom: aStatisticalMomentsOrHistogram count) confidenceLevel: fValue] ] { #category : #initialization } -PMStatisticalMoments >> initialize: anInteger [ +PMStatisticalMoments >> initialize: anInteger [ "Private - ( anInteger - 1) is the degree of the highest accumulated central moment." moments := Array new: anInteger. @@ -114,7 +114,7 @@ PMStatisticalMoments >> kurtosis [ n < 4 ifTrue: [^nil]. n23 := (n - 2) * (n - 3). n1 := n - 1. - ^((moments at: 5) * n squared * (n + 1) / (self variance squared * n1) + ^((moments at: 5) * n squared * (n + 1) / (self variance squared * n1) - (n1 squared * 3)) / n23 ] diff --git a/src/Math-TSNE/PMTSNE.class.st b/src/Math-TSNE/PMTSNE.class.st index ad48987da..d9e18a5e6 100644 --- a/src/Math-TSNE/PMTSNE.class.st +++ b/src/Math-TSNE/PMTSNE.class.st @@ -66,7 +66,7 @@ PMTSNE class >> example1 [ PMTSNE class >> exampleGridWithVizualization [ | points tsne v rec xscale yscale s elements | points := self gridDataGeneratorOf: 12. - + tsne := (self new) perplexity: 10; learningRate: 50; @@ -78,7 +78,7 @@ PMTSNE class >> exampleGridWithVizualization [ v := RSView new. "We assign a color to the elements" - rec := Rectangle encompassing: (tsne y rows + rec := Rectangle encompassing: (tsne y rows collect: [:row | row first @ row second ]). xscale := TSScale linear domain: (Array with rec origin x with: rec corner x). yscale := TSScale linear domain: (Array with rec origin y with: rec corner y). @@ -99,15 +99,14 @@ PMTSNE class >> exampleGridWithVizualization [ e position: (point first @ point second) * 20 ]. ]. v addAll: elements. - v open setLabel: 'tSNE example: Points arranged in a grid'. - + v open setLabel: 'tSNE example: Points arranged in a grid' ] { #category : #examples } PMTSNE class >> exampleLinkedRingWithVizualization [ | points tsne v counter s elements | points := self linkedRingsDataGeneratorOf: 50. - + "Perplexity near 10 and learningRate <= 10 gives best results" tsne := (self new) perplexity: 3; @@ -140,8 +139,7 @@ PMTSNE class >> exampleLinkedRingWithVizualization [ (Delay forMilliseconds: 10) wait. ]. v addAll: elements. - v open setLabel: 'tSNE example: Two 3D linked rings'. - + v open setLabel: 'tSNE example: Two 3D linked rings' ] { #category : #'data sets' } @@ -149,9 +147,9 @@ PMTSNE class >> gridDataGeneratorOf: size [ "Demos from https://github.com/distillpub/post--misread-tsne/blob/master/public/assets/demo-configs.js" "A square grid with equal spacing between points." "Returns a PMMatrix" - + | array i | - array := Array new: size*size. + array := Array new: size*size. i := 1. 1 to: size do: [ :x | 1 to: size do: [ :y | array at: i put: (Array with: x with: y). i:=i+1] ]. @@ -195,8 +193,8 @@ PMTSNE >> computeGradient [ ]. pq := p - q. - - dY := OrderedCollection new. + + dY := OrderedCollection new. 1 to: (x dimension x) do: [ :i | tmp := (pq rowAt: i) hadamardProduct: (num rowAt: i). "Create a matrix of rows filled with 'tmp'" @@ -256,7 +254,7 @@ PMTSNE >> computePairwiseAffinities [ It identifies required precision (beta = (1/ variance**2)) for each row using a binary search. The precision is selected based on input perplexity. " - + | d beta logU n betaMin betaMax distanceVector pVector entropy tries entropyDiff | n := x numberOfRows. d := self computePairwiseDistances. @@ -265,25 +263,25 @@ PMTSNE >> computePairwiseAffinities [ logU := self perplexity ln. distanceVector := PMVector new: n - 1. pVector := PMVector new: n - 1. - + job title: 'Step 2/3: Computing joint probablity for point 1 of ', n asString. job progress: 0.0. - + 1 to: n do: [ :i | "Job progress gets updated every 10 rows" (i % 10 = 0) ifTrue: [ job title: ('Step 2/3: Computing joint probablity for point {1} of {2}' format: (Array with: i with: n)). job progress: (i/n). ]. - + "Set minimum and maximum value of precision" betaMin := Float infinity negated. betaMax := Float infinity. - + "Ignore i-th element of the row d[i] and copy rest in distanceVector. Also initialize pVector to 0" 1 to: n do: [ :index | - (index = i) ifFalse: [ + (index = i) ifFalse: [ (index < i) ifTrue: [ distanceVector at: index put: (d rowAt: i columnAt: index). pVector at: index put: 0. ] @@ -294,16 +292,16 @@ PMTSNE >> computePairwiseAffinities [ entropy := self class entropyOf: distanceVector andPRow: pVector withBeta: (beta at: i). entropyDiff := entropy - logU. tries := 0. - [ (entropyDiff abs > 1e-5) & (tries < 50)] whileTrue: [ + [ (entropyDiff abs > 1e-5) & (tries < 50)] whileTrue: [ (entropyDiff > 0) - ifTrue: [ + ifTrue: [ betaMin := beta at: i. ((betaMax = Float infinity) | (betaMin = Float infinity negated)) ifTrue: [ beta at: i put: ((beta at: i) * 2) ] ifFalse: [ beta at: i put: (((beta at: i) + betaMax) / 2) ]. ] - ifFalse: [ + ifFalse: [ betaMax := beta at: i. ((betaMax = Float infinity) | (betaMin = Float infinity negated)) ifTrue: [ beta at: i put: ((beta at: i) / 2) ] @@ -360,12 +358,12 @@ PMTSNE >> gradientDescent [ 1 to: maxIter do: [ :i | self step. self postStep. - ]. + ] ] { #category : #accessing } PMTSNE >> initialDims [ - ^ initialDims + ^ initialDims ] { #category : #accessing } @@ -396,6 +394,8 @@ PMTSNE >> initialMomentumDefaultValue [ { #category : #initialization } PMTSNE >> initialize [ "These parameters rarely need to be modified" + + super initialize. maxIter := self maxIterDefaultValue. initialMomentum := self initialMomentumDefaultValue. finalMomentum := self finalMomentumDefaultValue. @@ -404,26 +404,25 @@ PMTSNE >> initialize [ updateProgressEvery := self updateProgressEveryDefaultValue. updateError := self updateErrorDefaultValue. iterations := 0. - self initializeJob. - + self initializeJob ] { #category : #initialization } PMTSNE >> initializeJob [ "This job represents all the steps in t-SNE" - job := [ + job := [ self initializeUninitializedParameters. self reduceXToInputDims. self initializeYWithRandomValues. self gradientDescent. - ] asJob. + ] asJob ] { #category : #initialization } PMTSNE >> initializeStateVariables [ p := self computePValues. gains := PMMatrix onesRows: x dimension x cols: outputDims. - iY := PMMatrix zerosRows: x dimension x cols: outputDims. + iY := PMMatrix zerosRows: x dimension x cols: outputDims ] { #category : #initialization } @@ -439,15 +438,15 @@ PMTSNE >> initializeYWithRandomValues [ "We should add this to PMMatrix API later" | numberOfRows numberOfColumns distribution rows | - + numberOfRows := x dimension x. numberOfColumns := outputDims. distribution := PMNormalDistribution new: 0 sigma: 1. - - rows := (1 to: numberOfRows) collect: [ :i | + + rows := (1 to: numberOfRows) collect: [ :i | (1 to: numberOfColumns) collect: [ :j | distribution random ] ]. - + y := PMMatrix rows: rows ] @@ -458,7 +457,7 @@ PMTSNE >> iterations [ { #category : #accessing } PMTSNE >> learningRate [ - ^ learningRate + ^ learningRate ] { #category : #accessing } @@ -541,7 +540,7 @@ PMTSNE >> postStep [ PMTSNE >> reduceXToInputDims [ "Runs PCA on X in order to reduce its dimensionality to initialDims dimensions." - self reduceXToInputDimsUsing: PMPrincipalComponentAnalyserJacobiTransformation. + self reduceXToInputDimsUsing: PMPrincipalComponentAnalyserJacobiTransformation ] { #category : #running } @@ -558,45 +557,45 @@ PMTSNE >> reduceXToInputDimsUsing: aClass [ { #category : #running } PMTSNE >> start [ - job run. + job run ] { #category : #'stepping and presenter' } PMTSNE >> step [ | dY momentum yMeanAccumulator | - + dY := self computeGradient. - + "Momentum accelerates gradient descent by dampening one direction" momentum := iterations < 20 ifTrue: [ initialMomentum ] ifFalse: [ finalMomentum ]. - + "Compute gain based on direction of descent" - 1 to: x dimension x do: [ :i | - 1 to: outputDims do: [ :j | + 1 to: x dimension x do: [ :i | + 1 to: outputDims do: [ :j | (dY rowAt: i columnAt: j) > 0 = ((iY rowAt: i columnAt: j) > 0) ifTrue: [ gains rowAt: i columnAt: j put: ((gains rowAt: i columnAt: j) * 0.8 max: minGain) ] ifFalse: [ gains rowAt: i columnAt: j put: (gains rowAt: i columnAt: j) + 0.2 ] ] ]. - + "Update y according to gradient, momentum and gain" iY := iY * momentum - ((dY hadamardProduct: gains) * learningRate). y := y + iY. - + "Center y by subtracting mean" yMeanAccumulator := PMVectorAccumulator new: outputDims. y rowsDo: [ :row | yMeanAccumulator accumulate: row ]. y := PMMatrix rows: (y rowsCollect: [ :row | row - yMeanAccumulator average ]). - + iterations := iterations + 1. "Stop early exaggeration on 100th iteration" iterations = 100 ifFalse: [ ^ self ]. - p := p * (1 / 4). + p := p * (1 / 4) ] { #category : #'stepping and presenter' } @@ -607,7 +606,7 @@ PMTSNE >> step: aNumber [ { #category : #accessing } PMTSNE >> updateError [ - ^ updateError + ^ updateError ] { #category : #accessing } @@ -622,7 +621,7 @@ PMTSNE >> updateErrorDefaultValue [ { #category : #accessing } PMTSNE >> updateProgressEvery [ - ^ updateProgressEvery + ^ updateProgressEvery ] { #category : #accessing } @@ -637,28 +636,22 @@ PMTSNE >> updateProgressEveryDefaultValue [ { #category : #'stepping and presenter' } PMTSNE >> updateProgressWithError [ + | error | - - (iterations % updateProgressEvery = 0) - ifFalse: [ ^ self ]. - + iterations % updateProgressEvery = 0 ifFalse: [ ^ self ]. + "Computing error can take more than 10% additional time. Setting this to false will speedup computation." - updateError ifFalse: [ error := '' ] - ifTrue: [ - error := PMMatrix rows: x dimension x columns: x dimension x. - 1 to: x dimension x do: [ :i | - 1 to: x dimension x do: [ :j | - error rowAt: i columnAt: j - put: (p rowAt: i columnAt: j) * ((p rowAt: i columnAt: j) / (q rowAt: i columnAt: j)) ln - ] ]. - error := error sum sum ]. - - job title: ( - 'Step 3/3: Performing gradient descent {1}/{2} error = {3}' - format: (Array with: iterations with: maxIter with: error) - ). - job progress: iterations / maxIter. + error := updateError + ifFalse: [ '' ] + ifTrue: [ + error := PMMatrix rows: x dimension x columns: x dimension x. + 1 to: x dimension x do: [ :i | + 1 to: x dimension x do: [ :j | error rowAt: i columnAt: j put: (p rowAt: i columnAt: j) * ((p rowAt: i columnAt: j) / (q rowAt: i columnAt: j)) ln ] ]. + error sum sum ]. + + job title: ('Step 3/3: Performing gradient descent {1}/{2} error = {3}' format: (Array with: iterations with: maxIter with: error)). + job progress: iterations / maxIter ] { #category : #accessing } diff --git a/src/Math-Tests-Accuracy/PMAccuracyFindKeyTest.class.st b/src/Math-Tests-Accuracy/PMAccuracyFindKeyTest.class.st index a94b0e144..234e2ecae 100644 --- a/src/Math-Tests-Accuracy/PMAccuracyFindKeyTest.class.st +++ b/src/Math-Tests-Accuracy/PMAccuracyFindKeyTest.class.st @@ -16,17 +16,16 @@ PMAccuracyFindKeyTest >> assertKeyFor: selector equals: expected [ ] { #category : #running } -PMAccuracyFindKeyTest >> setUp [ +PMAccuracyFindKeyTest >> setUp [ super setUp. - accuracy := PMAccuracyTestExample new. - + accuracy := PMAccuracyTestExample new ] { #category : #tests } PMAccuracyFindKeyTest >> testFindKeyReturnsAllTheRestStringWhenSelectorCorrespondsToNonExistentProperty [ | selector | selector := 'NonExistent'. - + self assertKeyFor: selector equals: 'AllTheRest' ] @@ -34,7 +33,7 @@ PMAccuracyFindKeyTest >> testFindKeyReturnsAllTheRestStringWhenSelectorCorrespon PMAccuracyFindKeyTest >> testFindKeyReturnsAllTheRestStringWhenSelectorIsInitialize [ | selector | selector := 'initialize'. - + self assertKeyFor: selector equals: 'AllTheRest' ] @@ -42,6 +41,6 @@ PMAccuracyFindKeyTest >> testFindKeyReturnsAllTheRestStringWhenSelectorIsInitial PMAccuracyFindKeyTest >> testFindKeyReturnsPropertyWhenSelectorIsSuffixOfInitializePropertyMessage [ | selector | selector := 'Aaa'. - + self assertKeyFor: selector equals: 'Aaa' ] diff --git a/src/Math-Tests-Accuracy/PMAccuracyTest.class.st b/src/Math-Tests-Accuracy/PMAccuracyTest.class.st index 577339275..d87445e7f 100644 --- a/src/Math-Tests-Accuracy/PMAccuracyTest.class.st +++ b/src/Math-Tests-Accuracy/PMAccuracyTest.class.st @@ -11,11 +11,10 @@ Class { #category : #'Math-Tests-Accuracy' } -{ #category : #'initialize-release' } -PMAccuracyTest >> initialize [ +{ #category : #initialization } +PMAccuracyTest >> initialize [ super initialize. dp := PMAccuracyTestExample decimalPlaces - ] { #category : #running } @@ -28,7 +27,7 @@ PMAccuracyTest >> setUp [ { #category : #running } PMAccuracyTest >> tearDown [ PMAccuracyTestExample decimalPlaces: dp. - super tearDown. + super tearDown ] { #category : #tests } @@ -89,7 +88,7 @@ PMAccuracyTest >> testExtractFromResultsReturnsAllElementsWhenOnlyOneIsTrue [ extractFromResults: #('bla' 'blah') which: 1 onlyOne: true. - + self assert: results equals: #('bla' 'blah'). argument := a testGetterAaa second. self assert: argument equals: #(#(false) #(true)) @@ -168,16 +167,12 @@ PMAccuracyTest >> testFormatTypePostfixTree [ { #category : #tests } PMAccuracyTest >> testGetters [ + | r | r := a testGetterAaa. - self - assert: r - equals: #(#(#(1 2) #(3 2.8888)) #(#(false) #(true)) #(#(5 3) #(4 4)) 2 2). + self assert: r equals: #( #( #( 1 2 ) #( 3 2.8888 ) ) #( #( false ) #( true ) ) #( #( 5 3 ) #( 4 4 ) ) 2 2 ). r := a testGetterBbb. - self - assert: r - equals: #(#(#(1) #(3)) #(#('a') #('AG')) #(#(2) #(3)) 2 2). - #(#(#(1) #(3)) #(#(1) #(2)) #(#(2) #(3)) 2 2) + self assert: r equals: #( #( #( 1 ) #( 3 ) ) #( #( 'a' ) #( 'AG' ) ) #( #( 2 ) #( 3 ) ) 2 2 ) ] { #category : #tests } diff --git a/src/Math-Tests-Accuracy/PMAccuracyTestExample.class.st b/src/Math-Tests-Accuracy/PMAccuracyTestExample.class.st index 84ee55b68..24b6659f2 100644 --- a/src/Math-Tests-Accuracy/PMAccuracyTestExample.class.st +++ b/src/Math-Tests-Accuracy/PMAccuracyTestExample.class.st @@ -14,7 +14,7 @@ Class { } { #category : #private } -PMAccuracyTestExample >> argumentWith: key [ +PMAccuracyTestExample >> argumentWith: key [ | theArgument | theArgument := self argumentAt: key. numberOfResults ifNotNil: [ :rn | theArgument := theArgument at: rn ]. @@ -77,7 +77,7 @@ PMAccuracyTestExample >> findKey: selector [ ^ matchingMessage ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMAccuracyTestExample >> initialize [ "this is always necessarily the first thing:" @@ -90,7 +90,7 @@ PMAccuracyTestExample >> initialize [ self parameter: #(#(1) #(3)) ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMAccuracyTestExample >> initializeAaa [ "this overrides defaults in #initialize:" @@ -99,7 +99,7 @@ PMAccuracyTestExample >> initializeAaa [ self parameter: #(#(1 2) #(3 2.8888)) ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMAccuracyTestExample >> initializeCcc [ "this overrides defaults in initialize" @@ -107,23 +107,23 @@ PMAccuracyTestExample >> initializeCcc [ self map: 'Ccc' to: #(#(1) #(1.1) #(0.9)) ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMAccuracyTestExample >> initializeDdd [ "this overrides defaults in initialize" self result: #(1.1 2.2). - self map: 'Ddd' to: #(). + self map: 'Ddd' to: #(). self parameter: #() ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMAccuracyTestExample >> initializeEee [ "this overrides defaults in initialize" self result: #(#(1.1 2.2) #(1 3)) ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMAccuracyTestExample >> initializeFff [ "this overrides defaults in initialize" @@ -132,7 +132,7 @@ PMAccuracyTestExample >> initializeFff [ self parameter: nil ] -{ #category : #'initialize-release' } +{ #category : #initialization } PMAccuracyTestExample >> map: key to: anArgument [ arguments at: key diff --git a/src/Math-Tests-Accuracy/PMDataTreeTest.class.st b/src/Math-Tests-Accuracy/PMDataTreeTest.class.st index 4de3357a0..971efe0d5 100644 --- a/src/Math-Tests-Accuracy/PMDataTreeTest.class.st +++ b/src/Math-Tests-Accuracy/PMDataTreeTest.class.st @@ -17,22 +17,22 @@ Class { } { #category : #initialization } -PMDataTreeTest >> initialize [ +PMDataTreeTest >> initialize [ super initialize. dp := PMAccuracyTestExample decimalPlaces ] { #category : #running } -PMDataTreeTest >> setUp [ +PMDataTreeTest >> setUp [ super setUp. a := PMAccuracyTestExample new. - PMAccuracyTestExample decimalPlaces: 3. + PMAccuracyTestExample decimalPlaces: 3 ] { #category : #running } -PMDataTreeTest >> tearDown [ +PMDataTreeTest >> tearDown [ PMAccuracyTestExample decimalPlaces: dp. - super tearDown. + super tearDown ] { #category : #tests } @@ -40,24 +40,24 @@ PMDataTreeTest >> testDataTree [ | keyedTree | a run. keyedTree := a dataTree atPath: #('names' 'Ccc' #(3)). - self assert: keyedTree keys size equals: 5. + self assert: keyedTree keys size equals: 5 ] { #category : #tests } PMDataTreeTest >> testThatDataForAaaIsTheCorrespondingParameter [ | parameterForAaa | a run. - + parameterForAaa := #(#(1 2) #(3 2.8888)). self assert: (a dataTree atPath: #('names' 'Aaa' 'data')) - equals: parameterForAaa. + equals: parameterForAaa ] { #category : #tests } PMDataTreeTest >> testThatKeyedTreeContainsArgsDataErrorResultsAndType [ "SMELL - it's not easy to determine the true purpose of the - test and, perhaps with the exception of the 'expected result', + test and, perhaps with the exception of the 'expected result', how input leads to the output. The test also contains many 'magic' numbers. " @@ -79,13 +79,13 @@ PMDataTreeTest >> testThatKeyedTreeContainsArgsDataErrorResultsAndType [ PMDataTreeTest >> testThatRunIncrementsTheNumberOfIterations [ "SMELL - we're really testing run, it seems." a run. - self assert: (a dataTree atPath: #('iterations')) equals: 1. + self assert: (a dataTree atPath: #('iterations')) equals: 1 ] { #category : #tests } PMDataTreeTest >> testThatTheDataForBbbIsTheDefaultResult [ - "SMELL - magic number. This may be coincidental, but the - expected result in this test is that set in + "SMELL - magic number. This may be coincidental, but the + expected result in this test is that set in PMAccuracyTestExample's initialize method. " | defaultResultAtInitialisation | @@ -104,7 +104,7 @@ PMDataTreeTest >> testThatTheErrorForFffIsCorrect [ self assert: (error copyFrom: 1 to: 4) equals: (Array with: 0 with: Float infinity with: -100.0 with: Float infinity negated). - self assert: (error at: 5) isNaN. + self assert: (error at: 5) isNaN ] { #category : #tests } diff --git a/src/Math-Tests-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloatTest.class.st b/src/Math-Tests-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloatTest.class.st index 4b53a364c..516b91165 100644 --- a/src/Math-Tests-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloatTest.class.st +++ b/src/Math-Tests-ArbitraryPrecisionFloat/PMArbitraryPrecisionFloatTest.class.st @@ -24,7 +24,7 @@ PMArbitraryPrecisionFloatTest class >> defaultTimeLimit [ { #category : #private } PMArbitraryPrecisionFloatTest >> checkDoublePrecision: y forFunction: func nBits: n [ "Check that doubling the precision, then rounding would lead to the same result" - + | anArbitraryPrecisionFloat singlePrecisionResult | anArbitraryPrecisionFloat := y asArbitraryPrecisionFloatNumBits: n. singlePrecisionResult := anArbitraryPrecisionFloat perform: func. @@ -33,7 +33,7 @@ PMArbitraryPrecisionFloatTest >> checkDoublePrecision: y forFunction: func nBits ] { #category : #private } -PMArbitraryPrecisionFloatTest >> checkDoublePrecisionSerie: serie forFunction: func [ +PMArbitraryPrecisionFloatTest >> checkDoublePrecisionSerie: serie forFunction: func [ ^self checkDoublePrecisionSerie: serie forFunction: func nBits: Float precision ] @@ -43,7 +43,7 @@ PMArbitraryPrecisionFloatTest >> checkDoublePrecisionSerie: serie forFunction: f ] { #category : #private } -PMArbitraryPrecisionFloatTest >> checkDoublePrecisionSerieVsFloat: serie forFunction: func [ +PMArbitraryPrecisionFloatTest >> checkDoublePrecisionSerieVsFloat: serie forFunction: func [ ^serie reject: [:y | | farb | farb := self checkDoublePrecision: y forFunction: func nBits: Float precision. @@ -53,12 +53,12 @@ PMArbitraryPrecisionFloatTest >> checkDoublePrecisionSerieVsFloat: serie forFunc { #category : #private } PMArbitraryPrecisionFloatTest >> checkThatEvaluatingFunction: func toDoublePrecisionOf: anArbitraryPrecisionFloat equals: singlePrecisionResult [ "Check that doubling the precision, then rounding would lead to the same result" - + | n doublePrecision doublePrecisionResult lowBits | n := anArbitraryPrecisionFloat numBits. doublePrecision := anArbitraryPrecisionFloat asArbitraryPrecisionFloatNumBits: n * 2. doublePrecisionResult := doublePrecision perform: func. - + "Note: the test must be guarded against double rounding error condition. For example, suppose the single precision is 4 bits, double precision 8 bits. If exact result is 1.001 | 0111 | 1001... @@ -73,19 +73,17 @@ PMArbitraryPrecisionFloatTest >> checkThatEvaluatingFunction: func toDoublePreci ["double precision is ambiguous - retry with quadruple..." ^self checkThatEvaluatingFunction: func toQuadruplePrecisionOf: anArbitraryPrecisionFloat equals: singlePrecisionResult]. self assert: ((doublePrecisionResult asArbitraryPrecisionFloatNumBits: n)- singlePrecisionResult) isZero - - ] { #category : #private } PMArbitraryPrecisionFloatTest >> checkThatEvaluatingFunction: func toQuadruplePrecisionOf: anArbitraryPrecisionFloat equals: singlePrecisionResult [ "Check that quadrupling the precision, then rounding would lead to the same result" - + | n quadruplePrecision quadruplePrecisionResult lowBits | n := anArbitraryPrecisionFloat numBits. quadruplePrecision := anArbitraryPrecisionFloat asArbitraryPrecisionFloatNumBits: n * 4. quadruplePrecisionResult := quadruplePrecision perform: func. - + "Guard against double rounding error condition (exact tie)" quadruplePrecisionResult normalize. lowBits := quadruplePrecisionResult mantissa bitAnd: 1<<(3*n)-1. @@ -93,7 +91,7 @@ PMArbitraryPrecisionFloatTest >> checkThatEvaluatingFunction: func toQuadruplePr ifTrue: ["quadruple precision is ambiguous - give up..." ^self]. - self assert: ((quadruplePrecisionResult asArbitraryPrecisionFloatNumBits: n)- singlePrecisionResult) isZero. + self assert: ((quadruplePrecisionResult asArbitraryPrecisionFloatNumBits: n)- singlePrecisionResult) isZero ] { #category : #'testing-hyperbolic' } @@ -111,15 +109,17 @@ PMArbitraryPrecisionFloatTest >> largeTrigonometricSerie [ ^#(1.0e15 1.1e21 1.2e28 1.0e32 1.1e34 -1.23e51 1.345e67 1.777e151 1.211e308) ] -{ #category : #setup } +{ #category : #running } PMArbitraryPrecisionFloatTest >> setUp [ + + super setUp. zero := 0 asArbitraryPrecisionFloatNumBits: 53. one := 1 asArbitraryPrecisionFloatNumBits: 53. two := 2 asArbitraryPrecisionFloatNumBits: 53. - half := 1/2 asArbitraryPrecisionFloatNumBits: 53. + half := 1 / 2 asArbitraryPrecisionFloatNumBits: 53. minusOne := -1 asArbitraryPrecisionFloatNumBits: 53. minusTwo := -2 asArbitraryPrecisionFloatNumBits: 53. - huge := (10 raisedTo: 100) asArbitraryPrecisionFloatNumBits: 53. + huge := (10 raisedTo: 100) asArbitraryPrecisionFloatNumBits: 53 ] { #category : #'testing-hyperbolic' } @@ -132,7 +132,7 @@ PMArbitraryPrecisionFloatTest >> testArCosh [ { #category : #'testing-hyperbolic' } PMArbitraryPrecisionFloatTest >> testArCoshDomainError [ - self should: [(1/2 asArbitraryPrecisionFloatNumBits: 24) arCosh] raise: DomainError. + self should: [(1/2 asArbitraryPrecisionFloatNumBits: 24) arCosh] raise: DomainError ] { #category : #'testing-hyperbolic' } @@ -154,7 +154,7 @@ PMArbitraryPrecisionFloatTest >> testArTanh [ { #category : #'testing-hyperbolic' } PMArbitraryPrecisionFloatTest >> testArTanhDomainError [ self should: [(2 asArbitraryPrecisionFloatNumBits: 24) arTanh] raise: DomainError. - self should: [(-3 asArbitraryPrecisionFloatNumBits: 24) arTanh] raise: DomainError. + self should: [(-3 asArbitraryPrecisionFloatNumBits: 24) arTanh] raise: DomainError ] { #category : #'testing-trigonometry' } @@ -162,20 +162,13 @@ PMArbitraryPrecisionFloatTest >> testArcCos [ "seconds" - | badArcCos | - badArcCos := self - checkDoublePrecisionSerieVsFloat: self inverseTrigonometricSerie - forFunction: #arcCos. - "badArcCos isEmpty - ifFalse: [ Transcript - cr; - show: 'bad arcCos for ' , badArcCos printString ]" + self checkDoublePrecisionSerieVsFloat: self inverseTrigonometricSerie forFunction: #arcCos ] { #category : #'testing-trigonometry' } PMArbitraryPrecisionFloatTest >> testArcCosDomainError [ self should: [(2 asArbitraryPrecisionFloatNumBits: 24) arcCos] raise: DomainError. - self should: [(-3 asArbitraryPrecisionFloatNumBits: 24) arcCos] raise: DomainError. + self should: [(-3 asArbitraryPrecisionFloatNumBits: 24) arcCos] raise: DomainError ] { #category : #'testing-trigonometry' } @@ -183,20 +176,13 @@ PMArbitraryPrecisionFloatTest >> testArcSin [ "seconds" - | badArcSin | - badArcSin := self - checkDoublePrecisionSerieVsFloat: self inverseTrigonometricSerie - forFunction: #arcSin. -" badArcSin isEmpty - ifFalse: [ Transcript - cr; - show: 'bad arcSin for ' , badArcSin printString ]" + self checkDoublePrecisionSerieVsFloat: self inverseTrigonometricSerie forFunction: #arcSin ] { #category : #'testing-trigonometry' } PMArbitraryPrecisionFloatTest >> testArcSinDomainError [ self should: [(2 asArbitraryPrecisionFloatNumBits: 24) arcSin] raise: DomainError. - self should: [(-3 asArbitraryPrecisionFloatNumBits: 24) arcSin] raise: DomainError. + self should: [(-3 asArbitraryPrecisionFloatNumBits: 24) arcSin] raise: DomainError ] { #category : #'testing-trigonometry' } @@ -204,15 +190,9 @@ PMArbitraryPrecisionFloatTest >> testArcTan [ "seconds" - | badArcTan serie | + | serie | serie := (-50 to: 50) collect: [ :e | (e / 10) asFloat ]. - badArcTan := self - checkDoublePrecisionSerieVsFloat: serie - forFunction: #arcTan. -" badArcTan isEmpty - ifFalse: [ Transcript - cr; - show: 'bad arcTan for ' , badArcTan printString ]" + self checkDoublePrecisionSerieVsFloat: serie forFunction: #arcTan ] { #category : #'testing-trigonometry' } @@ -226,85 +206,89 @@ PMArbitraryPrecisionFloatTest >> testArcTan2 [ | xf xd | xf := x asArbitraryPrecisionFloatNumBits: Float precision. xd := xf asArbitraryPrecisionFloatNumBits: Float precision * 2. - self assert: ((yd arcTan: xd) asFloat - (yf arcTan: xf) asFloat) isZero]]. + self assert: ((yd arcTan: xd) asFloat - (yf arcTan: xf) asFloat) isZero]] ] { #category : #'testing-converting' } PMArbitraryPrecisionFloatTest >> testAsFloat [ - self assert: (half asArbitraryPrecisionFloatNumBits: Float precision) asFloat = 0.5e0. - self assert: (half asArbitraryPrecisionFloatNumBits: Float precision * 2) asFloat = 0.5e0. + + self assert: (half asArbitraryPrecisionFloatNumBits: Float precision) asFloat equals: 0.5e0. + self assert: (half asArbitraryPrecisionFloatNumBits: Float precision * 2) asFloat equals: 0.5e0 ] { #category : #'testing-converting' } PMArbitraryPrecisionFloatTest >> testAsFloatWithUnderflow [ + | fmin fminA | fmin := Float fmin. fminA := fmin asArbitraryPrecisionFloatNumBits: one numBits. - Float emin - Float precision + 1 to: Float emin + 1 do: [:n | - self assert: ((one timesTwoPower: n) + fminA) asFloat = ((1.0e0 timesTwoPower: n) + fmin)]. + Float emin - Float precision + 1 to: Float emin + 1 do: [ :n | self assert: ((one timesTwoPower: n) + fminA) asFloat equals: (1.0e0 timesTwoPower: n) + fmin ] ] { #category : #'testing-converting' } PMArbitraryPrecisionFloatTest >> testAsMinimalDecimalFraction [ + | emax emin leadingOne significands | - significands := 0 to: 1<<10-1. - leadingOne := 1<<10. + significands := 0 to: 1 << 10 - 1. + leadingOne := 1 << 10. emin := -14. emax := 15. - + "Test all normal finite half precision float" - emin to: emax do: [:e | - significands do: [:s | + emin to: emax do: [ :e | + significands do: [ :s | | f | f := (leadingOne + s asArbitraryPrecisionFloatNumBits: 11) timesTwoPower: e - 10. - self assert: (f asMinimalDecimalFraction asArbitraryPrecisionFloatNumBits: 11) = f]]. - + self assert: (f asMinimalDecimalFraction asArbitraryPrecisionFloatNumBits: 11) equals: f ] ]. + "Test all subnormal finite half precision float" - significands do: [:s | + significands do: [ :s | | f | f := (s asArbitraryPrecisionFloatNumBits: s highBit) timesTwoPower: emin - 10. - self assert: (f asMinimalDecimalFraction asArbitraryPrecisionFloatNumBits: s highBit) = f]. + self assert: (f asMinimalDecimalFraction asArbitraryPrecisionFloatNumBits: s highBit) equals: f ] ] { #category : #'testing-coercing' } PMArbitraryPrecisionFloatTest >> testCoercingDivide [ - (Array with: 1/2 with: 0.5e0 with: 0.5s1) do: [:heteroHalf | - self assert: one / heteroHalf = two. - self assert: (one / heteroHalf) class = one class. - self assert: (one / heteroHalf) numBits = one numBits. - self assert: heteroHalf / one = half. - self assert: (heteroHalf / one) class = one class. - self assert: (heteroHalf / one) numBits = one numBits]. - - self assert: one / 2 = half. - self assert: (one / 2) class = one class. - self assert: (one / 2) numBits = one numBits. - self assert: -2 / two = minusOne. - self assert: (-2 / two) class = two class. - self assert: (-2 / two) numBits = two numBits. + + (Array with: 1 / 2 with: 0.5e0 with: 0.5s1) do: [ :heteroHalf | + self assert: one / heteroHalf equals: two. + self assert: (one / heteroHalf) class equals: one class. + self assert: (one / heteroHalf) numBits equals: one numBits. + self assert: heteroHalf / one equals: half. + self assert: (heteroHalf / one) class equals: one class. + self assert: (heteroHalf / one) numBits equals: one numBits ]. + + self assert: one / 2 equals: half. + self assert: (one / 2) class equals: one class. + self assert: (one / 2) numBits equals: one numBits. + self assert: -2 / two equals: minusOne. + self assert: (-2 / two) class equals: two class. + self assert: (-2 / two) numBits equals: two numBits ] { #category : #'testing-coercing' } PMArbitraryPrecisionFloatTest >> testCoercingEqual [ - self assert: half = (1/2). - self assert: (1/2) = half. - self deny: half = (1/3). - self deny: (1/3) = half. - self assert: two = 2. - self assert: -2 = minusTwo. - self deny: -3 = two. - self deny: two = 3. + self assert: half equals: 1 / 2. + self assert: 1 / 2 equals: half. + self deny: half equals: 1 / 3. + self deny: 1 / 3 equals: half. - self assert: half = (0.5e0). - self assert: (0.5e0) = half. - self deny: half = (0.33e0). - self deny: (0.33e0) = half. + self assert: two equals: 2. + self assert: -2 equals: minusTwo. + self deny: -3 equals: two. + self deny: two equals: 3. - self assert: half = (0.5s1). - self assert: (0.5s1) = half. - self deny: half = (0.33s2). - self deny: (0.33s2) = half. + self assert: half equals: 0.5e0. + self assert: 0.5e0 equals: half. + self deny: half equals: 0.33e0. + self deny: 0.33e0 equals: half. + + self assert: half equals: 0.5s1. + self assert: 0.5s1 equals: half. + self deny: half equals: 0.33s2. + self deny: 0.33s2 equals: half ] { #category : #'testing-coercing' } @@ -335,61 +319,64 @@ PMArbitraryPrecisionFloatTest >> testCoercingLessThan [ self assert: half < (0.66s2). self deny: (0.5s1) < half. self assert: (0.33s2) < half. - self deny: (0.66s2) < half. + self deny: (0.66s2) < half ] { #category : #'testing-coercing' } PMArbitraryPrecisionFloatTest >> testCoercingMultiply [ - (Array with: 1/2 with: 0.5e0 with: 0.5s1) do: [:heteroHalf | - self assert: two * heteroHalf = one. - self assert: (two * heteroHalf) class = half class. - self assert: (two * heteroHalf) numBits = half numBits. - self assert: heteroHalf * two = one. - self assert: (heteroHalf * two) class = half class. - self assert: (heteroHalf * two) numBits = half numBits]. - - self assert: minusOne * 2 = minusTwo. - self assert: (minusOne * 2) class = minusOne class. - self assert: (minusOne * 2) numBits = minusOne numBits. - self assert: 2 * one = two. - self assert: (2 * one) class = one class. - self assert: (2 * one) numBits = one numBits. + + (Array with: 1 / 2 with: 0.5e0 with: 0.5s1) do: [ :heteroHalf | + self assert: two * heteroHalf equals: one. + self assert: (two * heteroHalf) class equals: half class. + self assert: (two * heteroHalf) numBits equals: half numBits. + self assert: heteroHalf * two equals: one. + self assert: (heteroHalf * two) class equals: half class. + self assert: (heteroHalf * two) numBits equals: half numBits ]. + + self assert: minusOne * 2 equals: minusTwo. + self assert: (minusOne * 2) class equals: minusOne class. + self assert: (minusOne * 2) numBits equals: minusOne numBits. + self assert: 2 * one equals: two. + self assert: (2 * one) class equals: one class. + self assert: (2 * one) numBits equals: one numBits ] { #category : #'testing-coercing' } PMArbitraryPrecisionFloatTest >> testCoercingSubtract [ - (Array with: 1/2 with: 0.5e0 with: 0.5s1) do: [:heteroHalf | - self assert: half - heteroHalf = zero. - self assert: (half - heteroHalf) class = half class. - self assert: (half - heteroHalf) numBits = half numBits. - self assert: heteroHalf - half = zero. - self assert: (heteroHalf - half) class = half class. - self assert: (heteroHalf - half) numBits = half numBits]. - - self assert: one - 1 = zero. - self assert: (one - 1) class = minusOne class. - self assert: (one - 1) numBits = minusOne numBits. - self assert: -2 - minusTwo = zero. - self assert: (-2 - minusTwo) class = minusTwo class. - self assert: (-2 - minusTwo) numBits = minusTwo numBits. + + (Array with: 1 / 2 with: 0.5e0 with: 0.5s1) do: [ :heteroHalf | + self assert: half - heteroHalf equals: zero. + self assert: (half - heteroHalf) class equals: half class. + self assert: (half - heteroHalf) numBits equals: half numBits. + self assert: heteroHalf - half equals: zero. + self assert: (heteroHalf - half) class equals: half class. + self assert: (heteroHalf - half) numBits equals: half numBits ]. + + self assert: one - 1 equals: zero. + self assert: (one - 1) class equals: minusOne class. + self assert: (one - 1) numBits equals: minusOne numBits. + self assert: -2 - minusTwo equals: zero. + self assert: (-2 - minusTwo) class equals: minusTwo class. + self assert: (-2 - minusTwo) numBits equals: minusTwo numBits ] { #category : #'testing-coercing' } PMArbitraryPrecisionFloatTest >> testCoercingSum [ - (Array with: 1/2 with: 0.5e0 with: 0.5s1) do: [:heteroHalf | - self assert: half + heteroHalf = one. - self assert: (half + heteroHalf) class = half class. - self assert: (half + heteroHalf) numBits = half numBits. - self assert: heteroHalf + half = one. - self assert: (heteroHalf + half) class = half class. - self assert: (heteroHalf + half) numBits = half numBits]. - - self assert: minusOne + 1 = zero. - self assert: (minusOne + 1) class = minusOne class. - self assert: (minusOne + 1) numBits = minusOne numBits. - self assert: 2 + minusTwo = zero. - self assert: (2 + minusTwo) class = minusTwo class. - self assert: (2 + minusTwo) numBits = minusTwo numBits. + + (Array with: 1 / 2 with: 0.5e0 with: 0.5s1) do: [ :heteroHalf | + self assert: half + heteroHalf equals: one. + self assert: (half + heteroHalf) class equals: half class. + self assert: (half + heteroHalf) numBits equals: half numBits. + self assert: heteroHalf + half equals: one. + self assert: (heteroHalf + half) class equals: half class. + self assert: (heteroHalf + half) numBits equals: half numBits ]. + + self assert: minusOne + 1 equals: zero. + self assert: (minusOne + 1) class equals: minusOne class. + self assert: (minusOne + 1) numBits equals: minusOne numBits. + self assert: 2 + minusTwo equals: zero. + self assert: (2 + minusTwo) class equals: minusTwo class. + self assert: (2 + minusTwo) numBits equals: minusTwo numBits ] { #category : #'testing-trigonometry' } @@ -397,16 +384,7 @@ PMArbitraryPrecisionFloatTest >> testCos [ "seconds" - | badCos | - badCos := self - checkDoublePrecisionSerieVsFloat: self trigonometricSerie - forFunction: #cos. -" badCos isEmpty - ifFalse: [ Transcript - cr; - show: - 'bad cos for angles (degrees) ' - , (badCos collect: [ :i | i radiansToDegrees rounded ]) printString ]" + self checkDoublePrecisionSerieVsFloat: self trigonometricSerie forFunction: #cos ] { #category : #'testing-hyperbolic' } @@ -417,66 +395,74 @@ PMArbitraryPrecisionFloatTest >> testCosh [ { #category : #'testing-arithmetic' } PMArbitraryPrecisionFloatTest >> testDivide [ + | serie | - serie := #(1 2 3 5 6 7 9 10 11 12 19 243) asOrderedCollection - add: (10 raisedTo: Float precision + 1); - add: Float precision factorial; - add: Float pi; - asArray. - serie do: [:num | + serie := #( 1 2 3 5 6 7 9 10 11 12 19 243 ) asOrderedCollection + add: (10 raisedTo: Float precision + 1); + add: Float precision factorial; + add: Float pi; + asArray. + serie do: [ :num | | nf na | nf := num asFloat. na := num asArbitraryPrecisionFloatNumBits: Float precision. - serie do:[:den | + serie do: [ :den | | df da ff fa | df := den asFloat. da := den asArbitraryPrecisionFloatNumBits: Float precision. ff := nf / df. fa := na / da. - self assert: ff = fa]]. + self assert: ff equals: fa ] ] ] { #category : #'testing-compare' } PMArbitraryPrecisionFloatTest >> testEqual [ - self assert: zero = zero. - self assert: one = one. - self assert: one = one copy. - self assert: one = (one asArbitraryPrecisionFloatNumBits: one numBits * 2). - self deny: zero = one. - self deny: minusOne = one. + self assert: zero equals: zero. + self assert: one equals: one. + self assert: one equals: one copy. + self assert: one equals: (one asArbitraryPrecisionFloatNumBits: one numBits * 2). - self assert: zero = 0. - self assert: 0 = zero. - self assert: zero = 0.0. - self assert: 0.0 = zero. + self deny: zero equals: one. + self deny: minusOne equals: one. - self deny: two = (1/2). - self deny: (1/2) = two. - self deny: zero = 1.0. - self deny: 0.0 = one. + self assert: zero equals: 0. + self assert: 0 equals: zero. + self assert: zero equals: 0.0. + self assert: 0.0 equals: zero. - self deny: one = nil. - self deny: nil = one. + self deny: two equals: 1 / 2. + self deny: 1 / 2 equals: two. + self deny: zero equals: 1.0. + self deny: 0.0 equals: one. + + self deny: one isNil. + self deny: nil equals: one ] { #category : #'testing-functions' } PMArbitraryPrecisionFloatTest >> testExp [ - + "seconds" + + | badExp serie | - serie := ((-20 to: 20) collect: [:e |e asFloat]). + serie := (-20 to: 20) collect: [ :e | e asFloat ]. badExp := self checkDoublePrecisionSerieVsFloat: serie forFunction: #exp. - badExp isEmpty ifFalse: [Transcript cr; show: 'bad exp for ' , badExp printString] + badExp ifNotEmpty: [ + Transcript + cr; + show: 'bad exp for ' , badExp printString ] ] { #category : #'testing-functions' } PMArbitraryPrecisionFloatTest >> testExpLn [ - |n| - self assert: (1 asArbitraryPrecisionFloatNumBits: 53) exp asFloat = 1 asFloat exp. + + | n | + self assert: (1 asArbitraryPrecisionFloatNumBits: 53) exp asFloat equals: 1 asFloat exp. n := 5 exp. - self assert: ((5 asArbitraryPrecisionFloatNumBits: 53) exp - n)abs <= n ulp. + self assert: ((5 asArbitraryPrecisionFloatNumBits: 53) exp - n) abs <= n ulp. "self assert: (5 asArbitraryPrecisionFloatNumBits: 53) exp asFloat = 5 asFloat exp." - self assert: ((5 asArbitraryPrecisionFloatNumBits: 53) exp ln asFloat - n ln)abs <= 5.0 ulp. + self assert: ((5 asArbitraryPrecisionFloatNumBits: 53) exp ln asFloat - n ln) abs <= 5.0 ulp "this test was skipped. changed that & loosened 2. test, since '5 exp' seems to round up instead of down here, which results in an error of almost one ulp in '5 exp'" @@ -484,35 +470,33 @@ PMArbitraryPrecisionFloatTest >> testExpLn [ { #category : #'testing-compare' } PMArbitraryPrecisionFloatTest >> testGreaterThan [ - + self assert: zero < one. self deny: one > two. self deny: two > huge. self deny: minusOne > one. self deny: minusTwo > minusOne. self deny: minusTwo > huge. - + self assert: huge > one. self assert: huge > zero. self assert: huge > minusOne. self assert: one > minusOne. - self assert: minusOne > minusTwo. + self assert: minusOne > minusTwo ] { #category : #'testing-arithmetic' } PMArbitraryPrecisionFloatTest >> testIEEEArithmeticVersusFloat [ + | floats ops ref new | - floats := #(1.0 2.0 3.0 5.0 10.0 2r1.0e52 2r1.0e53 2r1.0e54 0.5 0.25 2r1.0e-52 2r1.0e-53 2r1.0e-54 1.0e60 0.1 1.1e-30 1.0e-60) copyWith: Float pi. - ops := #(#+ #- #* #/ #= #< #> ). - ops - do: [:op | floats - do: [:f1 | floats - do: [:f2 | - ref := f1 perform: op with: f2. - new := (f1 asArbitraryPrecisionFloatNumBits: 53) - perform: op - with: (f2 asArbitraryPrecisionFloatNumBits: 53). - self assert: new = ref]]] + floats := #( 1.0 2.0 3.0 5.0 10.0 2r1.0e52 2r1.0e53 2r1.0e54 0.5 0.25 2r1.0e-52 2r1.0e-53 2r1.0e-54 1.0e60 0.1 1.1e-30 1.0e-60 ) copyWith: Float pi. + ops := #( #+ #- #* #/ #= #< #> ). + ops do: [ :op | + floats do: [ :f1 | + floats do: [ :f2 | + ref := f1 perform: op with: f2. + new := (f1 asArbitraryPrecisionFloatNumBits: 53) perform: op with: (f2 asArbitraryPrecisionFloatNumBits: 53). + self assert: new equals: ref ] ] ] ] { #category : #'testing-arithmetic' } @@ -522,55 +506,47 @@ PMArbitraryPrecisionFloatTest >> testIEEEArithmeticVersusIntegerAndFraction [ because our exponent is unlimited" | floats ops ref new intAndFractions | - floats := #(1.0e0 2.0e0 3.0e0 5.0e0 10.0e0) - , (#(52 53 54 -52 -53 -54) collect: [:e | 1.0e0 timesTwoPower: e]) - , #(0.5e0 0.25e0 1.0e60 0.1e0 1.1e-30 1.0e-60) copyWith: Float pi. - intAndFractions := #(1 3 5 10 12345678901234567890 -1 -22 -3 1.2s1) copyWith: 7/9. - intAndFractions := intAndFractions , (intAndFractions collect: [:e | e reciprocal]). - - ops := 1/10 = 0.1 - ifTrue: [#(#+ #- #* #/)] - ifFalse: [#(#+ #- #* #/ #= #< #>)]. "BEWARE: ArbitraryPrecisionFloat compare exactly, Float don't, unless http://bugs.squeak.org/view.php?id=3374" - ops do: - [:op | - floats do: - [:f1 | - intAndFractions do: - [:f2 | - ref := f1 perform: op with: f2 asFloat. - new := (f1 asArbitraryPrecisionFloatNumBits: 53) perform: op - with: (f2 asArbitraryPrecisionFloatNumBits: 53). - self assert: new = ref. - new := f1 perform: op - with: (f2 asArbitraryPrecisionFloatNumBits: 53). - self assert: new = ref. - - ref := f1 perform: op with: f2. - new := (f1 asArbitraryPrecisionFloatNumBits: 53) perform: op - with: f2. - self assert: new = ref. - - ref := f2 asFloat perform: op with: f1. - new := (f2 asArbitraryPrecisionFloatNumBits: 53) perform: op - with: (f1 asArbitraryPrecisionFloatNumBits: 53). - self assert: new = ref. - new := (f2 asArbitraryPrecisionFloatNumBits: 53) perform: op with: f1. - self assert: new = ref. - - ref := f2 perform: op with: f1. - new := f2 perform: op - with: (f1 asArbitraryPrecisionFloatNumBits: 53). - self assert: new = ref]]] + floats := #( 1.0e0 2.0e0 3.0e0 5.0e0 10.0e0 ) , (#( 52 53 54 -52 -53 -54 ) collect: [ :e | 1.0e0 timesTwoPower: e ]) + , #( 0.5e0 0.25e0 1.0e60 0.1e0 1.1e-30 1.0e-60 ) copyWith: Float pi. + intAndFractions := #( 1 3 5 10 12345678901234567890 -1 -22 -3 1.2s1 ) copyWith: 7 / 9. + intAndFractions := intAndFractions , (intAndFractions collect: [ :e | e reciprocal ]). + + ops := 1 / 10 = 0.1 + ifTrue: [ #( #+ #- #* #/ ) ] + ifFalse: [ #( #+ #- #* #/ #= #< #> ) ]. "BEWARE: ArbitraryPrecisionFloat compare exactly, Float don't, unless http://bugs.squeak.org/view.php?id=3374" + ops do: [ :op | + floats do: [ :f1 | + intAndFractions do: [ :f2 | + ref := f1 perform: op with: f2 asFloat. + new := (f1 asArbitraryPrecisionFloatNumBits: 53) perform: op with: (f2 asArbitraryPrecisionFloatNumBits: 53). + self assert: new equals: ref. + new := f1 perform: op with: (f2 asArbitraryPrecisionFloatNumBits: 53). + self assert: new equals: ref. + + ref := f1 perform: op with: f2. + new := (f1 asArbitraryPrecisionFloatNumBits: 53) perform: op with: f2. + self assert: new equals: ref. + + ref := f2 asFloat perform: op with: f1. + new := (f2 asArbitraryPrecisionFloatNumBits: 53) perform: op with: (f1 asArbitraryPrecisionFloatNumBits: 53). + self assert: new equals: ref. + new := (f2 asArbitraryPrecisionFloatNumBits: 53) perform: op with: f1. + self assert: new equals: ref. + + ref := f2 perform: op with: f1. + new := f2 perform: op with: (f1 asArbitraryPrecisionFloatNumBits: 53). + self assert: new equals: ref ] ] ] ] { #category : #'testing-coercing' } PMArbitraryPrecisionFloatTest >> testInfinityAndNaN [ + | inf nan | inf := Float infinity. nan := Float nan. self assert: inf + two equals: inf. - self assert: half + inf negated equals: inf negated. - self assert: (nan + minusOne) isNaN . + self assert: half + inf negated equals: inf negated. + self assert: (nan + minusOne) isNaN. self assert: inf - huge equals: inf. self assert: half - inf equals: inf negated. self assert: minusTwo - inf negated equals: inf. @@ -580,10 +556,10 @@ PMArbitraryPrecisionFloatTest >> testInfinityAndNaN [ self assert: inf negated * minusOne equals: inf. self assert: (huge * nan) isNaN. self assert: inf negated / minusTwo equals: inf. - self assert: zero / inf negated equals: 0. + self assert: zero / inf negated equals: 0. self assert: one / inf equals: 0. - self should: [inf / zero] raise: ZeroDivide. - self assert: (nan / two) isNaN. + self should: [ inf / zero ] raise: ZeroDivide. + self assert: (nan / two) isNaN. self assert: (inf raisedTo: huge) equals: inf. self assert: (huge raisedTo: inf) equals: inf. self assert: (nan raisedTo: two) isNaN. @@ -592,94 +568,100 @@ PMArbitraryPrecisionFloatTest >> testInfinityAndNaN [ self deny: zero >= nan. self assert: one < inf. self assert: zero ~= nan. - self deny: nan = one. + self deny: nan equals: one ] { #category : #'testing-compare' } PMArbitraryPrecisionFloatTest >> testIsZero [ self assert: zero isZero. self deny: one isZero. - self deny: minusTwo isZero. + self deny: minusTwo isZero ] { #category : #'testing-compare' } PMArbitraryPrecisionFloatTest >> testLessThan [ - + self assert: zero < one. self assert: one < two. self assert: two < huge. self assert: minusOne < one. self assert: minusTwo < minusOne. self assert: minusTwo < huge. - + self deny: huge < one. self deny: huge < zero. self deny: huge < minusOne. self deny: one < minusOne. - self deny: minusOne < minusTwo. + self deny: minusOne < minusTwo ] { #category : #'testing-functions' } PMArbitraryPrecisionFloatTest >> testLn [ - + "seconds" + + | badLn serie | - serie := ((1 to: 100) collect: [:e |e asFloat]). + serie := (1 to: 100) collect: [ :e | e asFloat ]. badLn := self checkDoublePrecisionSerieVsFloat: serie forFunction: #ln. - badLn isEmpty ifFalse: [Transcript cr; show: 'bad ln for ' , badLn printString] + badLn ifNotEmpty: [ + Transcript + cr; + show: 'bad ln for ' , badLn printString ] ] { #category : #'testing-functions' } PMArbitraryPrecisionFloatTest >> testLnDomainError [ - self should: [(-2 asArbitraryPrecisionFloatNumBits: 24) ln] raise: DomainError. + self should: [(-2 asArbitraryPrecisionFloatNumBits: 24) ln] raise: DomainError ] { #category : #'testing-arithmetic' } PMArbitraryPrecisionFloatTest >> testMultiply [ - self assert: zero * zero = zero. - self assert: zero * minusOne = zero. - self assert: huge * zero = zero. - self assert: one * zero = zero. - - self assert: one * two = two. - self assert: minusOne * one = minusOne. - self assert: minusOne * minusTwo = two. - - self assert: half * two = one. - + + self assert: zero * zero equals: zero. + self assert: zero * minusOne equals: zero. + self assert: huge * zero equals: zero. + self assert: one * zero equals: zero. + + self assert: one * two equals: two. + self assert: minusOne * one equals: minusOne. + self assert: minusOne * minusTwo equals: two. + + self assert: half * two equals: one. + "check rounding" - self assert: huge * one = huge. + self assert: huge * one equals: huge ] { #category : #'testing-arithmetic' } PMArbitraryPrecisionFloatTest >> testNegated [ - self assert: zero negated = zero. - self assert: one negated = minusOne. - self assert: minusTwo negated = two. - self assert: huge negated negated = huge. + self assert: zero negated equals: zero. + self assert: one negated equals: minusOne. + self assert: minusTwo negated equals: two. + self assert: huge negated negated equals: huge ] { #category : #'testing-compare' } PMArbitraryPrecisionFloatTest >> testNegative [ - + self deny: zero negative. self deny: two negative. - self assert: minusTwo negative. + self assert: minusTwo negative ] { #category : #'testing-arithmetic' } PMArbitraryPrecisionFloatTest >> testPi [ "check computation of pi" - self assert: (1 asArbitraryPrecisionFloatNumBits: 53) pi = Float pi. + self assert: (1 asArbitraryPrecisionFloatNumBits: 53) pi equals: Float pi ] { #category : #'testing-compare' } PMArbitraryPrecisionFloatTest >> testPositive [ - + self assert: zero positive. self assert: one positive. - self deny: minusOne positive. + self deny: minusOne positive ] { #category : #'testing-converting' } @@ -694,9 +676,9 @@ PMArbitraryPrecisionFloatTest >> testPrintAndEvaluate [ emax := 15. "Test all normal finite half precision float" - emin to: emax do: [ :e | + emin to: emax do: [ :e | significands - do: [ :s | + do: [ :s | | f | f := (leadingOne + s asArbitraryPrecisionFloatNumBits: 11) timesTwoPower: e - 10. @@ -709,7 +691,7 @@ PMArbitraryPrecisionFloatTest >> testPrintAndEvaluate [ "Test all subnormal finite half precision float" significands - do: [ :s | + do: [ :s | | f | f := (s asArbitraryPrecisionFloatNumBits: s highBit) timesTwoPower: emin - 10. @@ -723,7 +705,7 @@ PMArbitraryPrecisionFloatTest >> testRaisedToNegativeInteger [ n := 11. 1 to: 1<> testRaisedToPositiveInteger [ n := 11. 1 to: 1<> testReciprocal [ + | b | b := 1 << (Float precision - 1). - 1 to: 10000 do: [:i | + 1 to: 10000 do: [ :i | | a | a := i asArbitraryPrecisionFloatNumBits: Float precision. - self assert: a reciprocal = i asFloat reciprocal. - self assert: (a+b) reciprocal = (i+b) asFloat reciprocal. - self assert: a negated reciprocal = i asFloat negated reciprocal.] + self assert: a reciprocal equals: i asFloat reciprocal. + self assert: (a + b) reciprocal equals: (i + b) asFloat reciprocal. + self assert: a negated reciprocal equals: i asFloat negated reciprocal ] ] { #category : #'testing-arithmetic' } PMArbitraryPrecisionFloatTest >> testRoundToNearestEven [ "Check that IEEE default rounding mode is honoured, that is rounding to nearest even" - - self assert: ((one timesTwoPower: 52)+(0+(1/4))) asTrueFraction = ((1 bitShift: 52)+0). - self assert: ((one timesTwoPower: 52)+(0+(1/2))) asTrueFraction = ((1 bitShift: 52)+0). - self assert: ((one timesTwoPower: 52)+(0+(3/4))) asTrueFraction = ((1 bitShift: 52)+1). - self assert: ((one timesTwoPower: 52)+(1+(1/4))) asTrueFraction = ((1 bitShift: 52)+1). - self assert: ((one timesTwoPower: 52)+(1+(1/2))) asTrueFraction = ((1 bitShift: 52)+2). - self assert: ((one timesTwoPower: 52)+(1+(3/4))) asTrueFraction = ((1 bitShift: 52)+2). + + self assert: ((one timesTwoPower: 52) + (0 + (1 / 4))) asTrueFraction equals: (1 bitShift: 52) + 0. + self assert: ((one timesTwoPower: 52) + (0 + (1 / 2))) asTrueFraction equals: (1 bitShift: 52) + 0. + self assert: ((one timesTwoPower: 52) + (0 + (3 / 4))) asTrueFraction equals: (1 bitShift: 52) + 1. + self assert: ((one timesTwoPower: 52) + (1 + (1 / 4))) asTrueFraction equals: (1 bitShift: 52) + 1. + self assert: ((one timesTwoPower: 52) + (1 + (1 / 2))) asTrueFraction equals: (1 bitShift: 52) + 2. + self assert: ((one timesTwoPower: 52) + (1 + (3 / 4))) asTrueFraction equals: (1 bitShift: 52) + 2 ] { #category : #'testing-arithmetic' } PMArbitraryPrecisionFloatTest >> testRoundToNearestEvenAgainstIEEEDouble [ "Check that IEEE default rounding mode is honoured" - #(1 2 3 5 6 7) do: - [:i | - self assert: ((one timesTwoPower: 52) + (i / 4)) asTrueFraction - = ((1 asFloat timesTwoPower: 52) + (i / 4)) asTrueFraction. - self assert: ((one timesTwoPower: 52) - (i / 4)) asTrueFraction - = ((1 asFloat timesTwoPower: 52) - (i / 4)) asTrueFraction] + #( 1 2 3 5 6 7 ) do: [ :i | + self assert: ((one timesTwoPower: 52) + (i / 4)) asTrueFraction equals: ((1 asFloat timesTwoPower: 52) + (i / 4)) asTrueFraction. + self assert: ((one timesTwoPower: 52) - (i / 4)) asTrueFraction equals: ((1 asFloat timesTwoPower: 52) - (i / 4)) asTrueFraction ] ] { #category : #'testing-trigonometry' } @@ -777,31 +757,24 @@ PMArbitraryPrecisionFloatTest >> testSin [ "seconds" - | badSin | - badSin := self - checkDoublePrecisionSerieVsFloat: self trigonometricSerie - forFunction: #sin. -" badSin isEmpty - ifFalse: [ Transcript - cr; - show: - 'bad sin for angles (degrees) ' - , (badSin collect: [ :i | i radiansToDegrees rounded ]) printString ]" + self checkDoublePrecisionSerieVsFloat: self trigonometricSerie forFunction: #sin ] { #category : #'testing-trigonometry' } PMArbitraryPrecisionFloatTest >> testSincos [ - - self trigonometricSerie do: [:aFloat | + "seconds" + + + self trigonometricSerie do: [ :aFloat | | x sc s c | x := aFloat asArbitraryPrecisionFloatNumBits: 53. sc := x sincos. s := x sin. c := x cos. - self assert: sc size = 2. + self assert: sc size equals: 2. - self assert: sc first = s. - self assert: sc last = c] + self assert: sc first equals: s. + self assert: sc last equals: c ] ] { #category : #'testing-hyperbolic' } @@ -812,49 +785,56 @@ PMArbitraryPrecisionFloatTest >> testSinh [ { #category : #'testing-functions' } PMArbitraryPrecisionFloatTest >> testSqrt [ - + "seconds" + + | badSqrt serie | "knowing that (10**3) < (2**10), 100 bits are enough for representing 10**30 exactly" - self assert: ((10 raisedTo: 30) asArbitraryPrecisionFloatNumBits: 100) sqrt = (10 raisedTo: 15). + self assert: ((10 raisedTo: 30) asArbitraryPrecisionFloatNumBits: 100) sqrt equals: (10 raisedTo: 15). - serie := ((0 to: 20) collect: [:e | e asFloat]) , ((2 to: 20) collect: [:e | e reciprocal asFloat]). + serie := ((0 to: 20) collect: [ :e | e asFloat ]) , ((2 to: 20) collect: [ :e | e reciprocal asFloat ]). badSqrt := self checkDoublePrecisionSerieVsFloat: serie forFunction: #sqrt. - badSqrt isEmpty ifFalse: [Transcript cr; show: 'bad sqrt for ' , badSqrt printString] + badSqrt ifNotEmpty: [ + Transcript + cr; + show: 'bad sqrt for ' , badSqrt printString ] ] { #category : #'testing-functions' } PMArbitraryPrecisionFloatTest >> testSqrtDomainError [ - self should: [(-2 asArbitraryPrecisionFloatNumBits: 24) sqrt] raise: DomainError. + self should: [(-2 asArbitraryPrecisionFloatNumBits: 24) sqrt] raise: DomainError ] { #category : #'testing-arithmetic' } PMArbitraryPrecisionFloatTest >> testSubtract [ - self assert: zero - zero = zero. - self assert: zero - minusOne = one. - self assert: huge - zero = huge. - self assert: one - zero = one. - - self assert: one - minusOne = two. - self assert: minusOne - minusTwo = one. - self assert: minusOne - one = minusTwo. - + + self assert: zero - zero equals: zero. + self assert: zero - minusOne equals: one. + self assert: huge - zero equals: huge. + self assert: one - zero equals: one. + + self assert: one - minusOne equals: two. + self assert: minusOne - minusTwo equals: one. + self assert: minusOne - one equals: minusTwo. + "check rounding" - self assert: huge - one = huge. + self assert: huge - one equals: huge ] { #category : #'testing-arithmetic' } PMArbitraryPrecisionFloatTest >> testSum [ - self assert: zero + zero = zero. - self assert: zero + minusOne = minusOne. - self assert: huge + zero = huge. - self assert: one + zero = one. - - self assert: one + minusOne = zero. - self assert: minusOne + two = one. - self assert: one + minusTwo = minusOne. - + + self assert: zero + zero equals: zero. + self assert: zero + minusOne equals: minusOne. + self assert: huge + zero equals: huge. + self assert: one + zero equals: one. + + self assert: one + minusOne equals: zero. + self assert: minusOne + two equals: one. + self assert: one + minusTwo equals: minusOne. + "check rounding" - self assert: huge + one = huge. + self assert: huge + one equals: huge ] { #category : #'testing-trigonometry' } @@ -862,16 +842,7 @@ PMArbitraryPrecisionFloatTest >> testTan [ "seconds" - | badTan | - badTan := self - checkDoublePrecisionSerieVsFloat: self trigonometricSerie - forFunction: #tan. -" badTan isEmpty - ifFalse: [ Transcript - cr; - show: - 'bad tan for angles (degrees) ' - , (badTan collect: [ :i | i radiansToDegrees rounded ]) printString ]" + self checkDoublePrecisionSerieVsFloat: self trigonometricSerie forFunction: #tan ] { #category : #'testing-hyperbolic' } @@ -883,29 +854,29 @@ PMArbitraryPrecisionFloatTest >> testTanh [ { #category : #'testing-trigonometry' } PMArbitraryPrecisionFloatTest >> testVeryLargeCos [ - self checkDoublePrecisionSerie: self largeTrigonometricSerie forFunction: #cos. + self checkDoublePrecisionSerie: self largeTrigonometricSerie forFunction: #cos ] { #category : #'testing-trigonometry' } PMArbitraryPrecisionFloatTest >> testVeryLargeSin [ - self checkDoublePrecisionSerie: self largeTrigonometricSerie forFunction: #sin. + self checkDoublePrecisionSerie: self largeTrigonometricSerie forFunction: #sin ] { #category : #'testing-trigonometry' } PMArbitraryPrecisionFloatTest >> testVeryLargeTan [ - self checkDoublePrecisionSerie: self largeTrigonometricSerie forFunction: #tan. + self checkDoublePrecisionSerie: self largeTrigonometricSerie forFunction: #tan ] { #category : #'testing-arithmetic' } PMArbitraryPrecisionFloatTest >> testZeroOne [ - self assert: (312 asArbitraryPrecisionFloatNumBits: 53) one = 1. + self assert: (312 asArbitraryPrecisionFloatNumBits: 53) one equals: 1. self assert: (312 asArbitraryPrecisionFloatNumBits: 24) zero isZero. - self assert: (312 asArbitraryPrecisionFloatNumBits: 53) one asInteger = 1. - self assert: (312 asArbitraryPrecisionFloatNumBits: 24) zero asInteger isZero. + self assert: (312 asArbitraryPrecisionFloatNumBits: 53) one asInteger equals: 1. + self assert: (312 asArbitraryPrecisionFloatNumBits: 24) zero asInteger isZero ] { #category : #'testing-trigonometry' } diff --git a/src/Math-Tests-AutomaticDifferenciation/PMDualNumberTest.class.st b/src/Math-Tests-AutomaticDifferenciation/PMDualNumberTest.class.st index 9605bc7f9..fb8617f17 100644 --- a/src/Math-Tests-AutomaticDifferenciation/PMDualNumberTest.class.st +++ b/src/Math-Tests-AutomaticDifferenciation/PMDualNumberTest.class.st @@ -19,6 +19,8 @@ PMDualNumberTest >> assertEquality: aDualNumber and: anotherDualNumber [ { #category : #running } PMDualNumberTest >> setUp [ + + super setUp. zero := PMDualNumber value: 0 eps: 1. zeroc := PMDualNumber value: 0 eps: 0. one := PMDualNumber value: 1 eps: 1. @@ -99,16 +101,17 @@ PMDualNumberTest >> testConjugated [ { #category : #tests } PMDualNumberTest >> testConverting [ + | a | - self assert: zeroc asInteger == 0. - self assert: three asInteger == 3. + self assert: zeroc asInteger identicalTo: 0. + self assert: three asInteger identicalTo: 3. self assert: onec asFloat isFloat. self deny: onec isFloat. self assert: onec asFloat equals: 1. a := three negated asFloat. self assert: a isFloat. self assert: a equals: -3. - self assert: (PMDualNumber value: -3.7 eps: 2) asInteger == -3 + self assert: (PMDualNumber value: -3.7 eps: 2) asInteger identicalTo: -3 ] { #category : #'tests-mathematical functions' } diff --git a/src/Math-Tests-AutomaticDifferenciation/PMGradientAndHessianTest.class.st b/src/Math-Tests-AutomaticDifferenciation/PMGradientAndHessianTest.class.st index 706ae7c7a..ca01d90f6 100644 --- a/src/Math-Tests-AutomaticDifferenciation/PMGradientAndHessianTest.class.st +++ b/src/Math-Tests-AutomaticDifferenciation/PMGradientAndHessianTest.class.st @@ -7,7 +7,7 @@ Class { { #category : #tests } PMGradientAndHessianTest >> test [ | f g h r | - f := [ :i | + f := [ :i | | x y | x := i first. y := i second. @@ -28,7 +28,7 @@ PMGradientAndHessianTest >> test [ PMGradientAndHessianTest >> test2 [ | f g h r | - f := [ :i | + f := [ :i | | x y | x := i first. y := i second. diff --git a/src/Math-Tests-AutomaticDifferenciation/PMHyperDualNumberTest.class.st b/src/Math-Tests-AutomaticDifferenciation/PMHyperDualNumberTest.class.st index 710b7a663..22f5fb7f1 100644 --- a/src/Math-Tests-AutomaticDifferenciation/PMHyperDualNumberTest.class.st +++ b/src/Math-Tests-AutomaticDifferenciation/PMHyperDualNumberTest.class.st @@ -48,13 +48,14 @@ PMHyperDualNumberTest >> testAbs [ { #category : #tests } PMHyperDualNumberTest >> testAccessing [ + self assert: three eps equals: 1. self assert: three value equals: 3. self assert: three eps2 equals: 1. self assert: three eps1eps2 equals: 0. three eps1eps2: 2. three eps2: 2. - self assert: three eps2 == 2. + self assert: three eps2 identicalTo: 2. self assert: three eps1eps2 equals: 2 ] @@ -124,16 +125,17 @@ PMHyperDualNumberTest >> testArcTan [ { #category : #tests } PMHyperDualNumberTest >> testConverting [ + | a | - self assert: zeroc asInteger == 0. - self assert: three asInteger == 3. + self assert: zeroc asInteger identicalTo: 0. + self assert: three asInteger identicalTo: 3. self assert: onec asFloat isFloat. self deny: onec isFloat. self assert: onec asFloat equals: 1. a := three negated asFloat. self assert: a isFloat. self assert: a equals: -3. - self assert: (PMDualNumber value: -3.7 eps: 2) asInteger == -3 + self assert: (PMDualNumber value: -3.7 eps: 2) asInteger identicalTo: -3 ] { #category : #'tests-mathematical functions' } diff --git a/src/Math-Tests-Clustering/PMClusterFinderTest.class.st b/src/Math-Tests-Clustering/PMClusterFinderTest.class.st index 3d2e74621..05fa626d5 100644 --- a/src/Math-Tests-Clustering/PMClusterFinderTest.class.st +++ b/src/Math-Tests-Clustering/PMClusterFinderTest.class.st @@ -8,53 +8,52 @@ Class { #category : #'Math-Tests-Clustering' } -{ #category : #utils } +{ #category : #utilities } PMClusterFinderTest >> accumulateAround: aVector size: aNumber into: aCollection [ "Private - Generate a random point around the given center and insert it into the collection. aNumber is the sigma for the distance to the center" - + | r phi psi localVector | - + r := randomNumberGenerator nextBetween: -1 * aNumber and: aNumber. phi := randomNumberGenerator nextBetween: 0 and: Float pi. psi := randomNumberGenerator nextBetween: 0 and: Float pi. - + localVector := PMVector new: 3. localVector at: 1 put: (phi sin * psi sin * r); at: 2 put: (phi cos * psi sin * r); at: 3 put: (psi cos * r). - - aCollection add: (localVector + aVector). + + aCollection add: (localVector + aVector) ] -{ #category : #utils } +{ #category : #utilities } PMClusterFinderTest >> generatedPoints: anInteger [ "Private - Generate random points into aCollection. 3 clusters are used" | centers results randomNumber | - + centers := { #( 200 200 200) asPMVector . #(-200 200 200) asPMVector . #( 200 200 -200) asPMVector }. - + results := OrderedCollection new. - + anInteger timesRepeat: [ randomNumber := randomNumberGenerator nextIntegerBetween: 1 and: 3. self accumulateAround: (centers at: randomNumber) size: 1 into: results ]. - + ^ results ] -{ #category : #setUp } +{ #category : #running } PMClusterFinderTest >> setUp [ super setUp. randomNumberGenerator := Random seed: 3. - + dataServer := PMMemoryBasedDataServer new. - dataServer data: (self generatedPoints: 1000). - + dataServer data: (self generatedPoints: 1000) ] { #category : #tests } @@ -85,7 +84,7 @@ PMClusterFinderTest >> testMahalanobisCenter [ | center distance | center := PMMahalanobisCenter new: 3. #( #( 1 2 3 ) #( 2 3 4 ) #( 1 3 2 ) #( 4 3 1 ) #( 1 3 1 ) #( 1 4 2 ) - #( 3 1 2 ) #( 3 4 2 ) ) do: [ :x | + #( 3 1 2 ) #( 3 4 2 ) ) do: [ :x | center accumulate: x asPMVector ]. center computeParameters. distance := center distanceTo: #( 1 2 3 ) asPMVector. diff --git a/src/Math-Tests-Complex/PMComplexNumberTest.class.st b/src/Math-Tests-Complex/PMComplexNumberTest.class.st index 85fd3d66b..c14e34ee9 100644 --- a/src/Math-Tests-Complex/PMComplexNumberTest.class.st +++ b/src/Math-Tests-Complex/PMComplexNumberTest.class.st @@ -7,7 +7,7 @@ Class { { #category : #'testing - equality' } PMComplexNumberTest >> testAPureImaginaryNumberIsNotEqualToZero [ self deny: 1 i equals: 0. - self deny: 0 equals: 1 i. + self deny: 0 equals: 1 i ] { #category : #'testing - arithmetic' } @@ -38,13 +38,13 @@ PMComplexNumberTest >> testAddingComplexNumbersToAnArrayOfIntegers [ | c arrayOfIntegers expected | c := 6 - 6 i. arrayOfIntegers := #(0 1 2 3 4 5). - + expected := { 6 - 6 i . 7 - 6 i . 8 - 6 i . 9 - 6 i . 10 - 6 i . 11 - 6 i }. - self assert: (arrayOfIntegers + c) equals: expected. + self assert: (arrayOfIntegers + c) equals: expected ] { #category : #'testing - arithmetic' } -PMComplexNumberTest >> testAddingFractionsAndComplexNumbers [ +PMComplexNumberTest >> testAddingFractionsAndComplexNumbers [ self assert: 1 + 2 i + (2 / 3) equals: 5 / 3 + 2 i. self assert: 2 / 3 + (1 + 2 i) equals: 5 / 3 + 2 i ] @@ -52,13 +52,13 @@ PMComplexNumberTest >> testAddingFractionsAndComplexNumbers [ { #category : #'testing - arithmetic' } PMComplexNumberTest >> testAddingIntegersAndComplexNumbers [ self assert: 1 + 2 i + 1 equals: 2 + 2 i. - self assert: 1 + (1 + 2 i) equals: 2 + 2 i. + self assert: 1 + (1 + 2 i) equals: 2 + 2 i ] { #category : #'testing - arithmetic' } PMComplexNumberTest >> testAddingRealNumbersAndComplexNumbers [ self assert: 1 + 2 i + 1.0 equals: 2.0 + 2 i. - self assert: 1.0 + (1 + 2 i) equals: 2.0 + 2 i. + self assert: 1.0 + (1 + 2 i) equals: 2.0 + 2 i ] { #category : #'testing - arithmetic' } @@ -190,7 +190,7 @@ PMComplexNumberTest >> testArgumentOfAPositivePureImaginaryNumber [ { #category : #'testing - polar coordinates' } PMComplexNumberTest >> testArgumentOfAPositiveRealNumber [ - self assert: (5 + 0 i) arg equals: 0. + self assert: (5 + 0 i) arg equals: 0 ] { #category : #'testing - polar coordinates' } @@ -208,7 +208,7 @@ PMComplexNumberTest >> testCloseTo [ self assert: 2 + 3.000000000000001i closeTo: 2 + 3i. self assert: 2.000000000000001 + 3i closeTo: 2 + 3i. - self assert: 2.000000000000001 + 3.000000000000001i closeTo: 2 + 3i. + self assert: 2.000000000000001 + 3.000000000000001i closeTo: 2 + 3i ] { #category : #'testing - close to' } @@ -216,7 +216,7 @@ PMComplexNumberTest >> testCloseToReal [ self assert: 2 + 0.000000000000001i closeTo: 2. self assert: 2.000000000000001 + 0.000000000000001i closeTo: 2. - + self assert: 2 + 0i closeTo: 2.000000000000001. self deny: 2 + 3i closeTo: 2.000000000000001 ] @@ -225,7 +225,7 @@ PMComplexNumberTest >> testCloseToReal [ PMComplexNumberTest >> testCloseToRealWithPrecision [ self assert: 2 + 0.001i closeTo: 2 precision: 0.01. - self assert: 2.001 + 0.001i closeTo: 2 precision: 0.01. + self assert: 2.001 + 0.001i closeTo: 2 precision: 0.01 ] { #category : #'testing - close to' } @@ -233,18 +233,18 @@ PMComplexNumberTest >> testCloseToWithPrecision [ self assert: 2 + 3.001i closeTo: 2 + 3i precision: 0.01. self assert: 2.001 + 3i closeTo: 2 + 3i precision: 0.01. - self assert: 2.001 + 3.001i closeTo: 2 + 3i precision: 0.01. + self assert: 2.001 + 3.001i closeTo: 2 + 3i precision: 0.01 ] { #category : #'testing - arithmetic' } PMComplexNumberTest >> testComplexConjugate [ - self assert: (5 - 6i) complexConjugate equals: (5 + 6i). + self assert: (5 - 6i) complexConjugate equals: (5 + 6i) ] { #category : #'testing - equality' } PMComplexNumberTest >> testComplexNumberAndIntegerAreUnequalEvenIfRealPartIsEqualToInteger [ - self deny: 1 + 3 i equals: 1. + self deny: 1 + 3 i equals: 1 ] { #category : #'testing - mathematical functions' } @@ -256,7 +256,7 @@ PMComplexNumberTest >> testCos [ c := (2 + 3 i). c2 := c i exp + c i negated exp / 2. self assert: (c cos real closeTo: c2 real). - self assert: (c cos imaginary closeTo: c2 imaginary). + self assert: (c cos imaginary closeTo: c2 imaginary) ] { #category : #'testing - mathematical functions' } @@ -281,7 +281,7 @@ PMComplexNumberTest >> testCosh [ self assert: (c cosh imaginary closeTo: c2 imaginary). c2 := c i cos. self assert: (c cosh real closeTo: c2 real). - self assert: (c cosh imaginary closeTo: c2 imaginary). + self assert: (c cosh imaginary closeTo: c2 imaginary) ] { #category : #'testing - mathematical functions' } @@ -321,12 +321,10 @@ PMComplexNumberTest >> testDividingALargeComplexNumbersByItself [ c2 := c1. quotient := c1 / c2. self deny: (quotient - 1) isZero. - - "This test fails due to the wonders of floating point arithmetic. + + "This test fails due to the wonders of floating point arithmetic. Please have a look at Complex>>divideSecureBy: and #divideFastAndSecureBy: how this can be avoided." - - ] { #category : #'testing - arithmetic' } @@ -342,7 +340,7 @@ PMComplexNumberTest >> testEqualsIsReflexive [ | z | z := -10 + 10 i. - self assert: z equals: z. + self assert: z equals: z ] { #category : #'testing - equality' } @@ -353,7 +351,7 @@ PMComplexNumberTest >> testEqualsIsSymmetric [ w := 13 + 14 i. self assert: z equals: w. - self assert: w equals: z. + self assert: w equals: z ] { #category : #'testing - equality' } @@ -365,13 +363,13 @@ PMComplexNumberTest >> testEqualsIsSymmetricWithRespectToFractions [ { #category : #'testing - equality' } PMComplexNumberTest >> testEqualsIsSymmetricWithRespectToIntegers [ self assert: 1 + 0 i equals: 1. - self assert: 1 equals: 1 + 0 i. + self assert: 1 equals: 1 + 0 i ] { #category : #'testing - equality' } PMComplexNumberTest >> testEqualsIsSymmetricWithRespectToRealNumbers [ self assert: 1 + 0 i equals: 1.0. - self assert: 1.0 equals: 1 + 0 i. + self assert: 1.0 equals: 1 + 0 i ] { #category : #'testing - equality' } @@ -384,7 +382,7 @@ PMComplexNumberTest >> testEqualsIsTransitive [ self assert: z equals: w. self assert: w equals: u. - self assert: z equals: u. + self assert: z equals: u ] { #category : #tests } @@ -404,37 +402,37 @@ PMComplexNumberTest >> testHash [ { #category : #'testing - type checking' } PMComplexNumberTest >> testIsComplexNumberOnComplex [ - + self assert: (3 + 2i) isComplexNumber ] { #category : #'testing - type checking' } PMComplexNumberTest >> testIsComplexNumberOnNaN [ - + self deny: Character space isComplexNumber ] { #category : #'testing - type checking' } PMComplexNumberTest >> testIsComplexNumberOnReal [ - + self deny: 5 isComplexNumber ] { #category : #'testing - type checking' } PMComplexNumberTest >> testIsRealNumberOnComplex [ - + self deny: (3 + 2i) isRealNumber ] { #category : #'testing - type checking' } PMComplexNumberTest >> testIsRealNumberOnNaN [ - + self deny: Character space isRealNumber ] { #category : #'testing - type checking' } PMComplexNumberTest >> testIsRealNumberOnReal [ - + self assert: 0.5 isRealNumber ] @@ -501,20 +499,20 @@ PMComplexNumberTest >> testMultiplyingAnArrayOfIntegersByAComplexNumber [ | c arrayOfIntegers expected | c := 6 - 6 i. arrayOfIntegers := #(0 1 2 3 4 5). - + expected := { 0 + 0 i . 6 - 6 i . 12 - 12 i . 18 - 18 i . 24 - 24 i . 30 - 30 i }. - self assert: (arrayOfIntegers * c) equals: expected . + self assert: (arrayOfIntegers * c) equals: expected ] { #category : #'testing - arithmetic' } PMComplexNumberTest >> testMultiplyingArraysOfComplexNumbers [ | complexNumbersMultiplied complexNumbers expected | complexNumbers := Array with: 1 + 2 i with: 3 + 4 i with: 5 + 6 i. - + complexNumbersMultiplied := 2 * complexNumbers . - - expected := Array with: 2 + 4 i with: 6 + 8 i with: 10 + 12 i. - complexNumbersMultiplied + + expected := Array with: 2 + 4 i with: 6 + 8 i with: 10 + 12 i. + complexNumbersMultiplied with: expected do: [ :actual :expectedComplexNumber | self assert: actual equals: expectedComplexNumber ] ] @@ -546,20 +544,20 @@ PMComplexNumberTest >> testNew [ { #category : #'testing - expressing complex numbers' } PMComplexNumberTest >> testNormalizedFractionsOfComplexNumbersCannotBeWritten [ - | z w numerator denominator | + | z w numerator | z := 1 + 2 i. w := 3 + 4 i. numerator := z * w complexConjugate. - denominator := w squaredNorm. - - self should: [ Fraction numerator: numerator denominator: w squaredNorm ] raise: Exception. + w squaredNorm. + + self should: [ Fraction numerator: numerator denominator: w squaredNorm ] raise: Exception ] { #category : #'testing - close to' } PMComplexNumberTest >> testNotCloseToRealWithPrecision [ self deny: 2 + 0.001i closeTo: 2 precision: 0.000001. - self deny: 2.001 + 0.001i closeTo: 2 precision: 0.000001. + self deny: 2.001 + 0.001i closeTo: 2 precision: 0.000001 ] { #category : #'testing - close to' } @@ -567,7 +565,7 @@ PMComplexNumberTest >> testNotCloseToWithPrecision [ self deny: 2 + 3.001i closeTo: 2 + 3i precision: 0.000001. self deny: 2.001 + 3i closeTo: 2 + 3i precision: 0.000001. - self deny: 2.001 + 3.001i closeTo: 2 + 3i precision: 0.000001. + self deny: 2.001 + 3.001i closeTo: 2 + 3i precision: 0.000001 ] { #category : #tests } @@ -600,11 +598,12 @@ PMComplexNumberTest >> testProductWithVector [ ] { #category : #'testing - equality' } -PMComplexNumberTest >> testPureImaginaryNumbersAreNotEqualToObjectsOfADifferentType [ - self deny: 1 i = nil. - self deny: nil = 1 i. - self deny: 1 i = #(1 2 3). - self deny: #(1 2 3) = 1 i. +PMComplexNumberTest >> testPureImaginaryNumbersAreNotEqualToObjectsOfADifferentType [ + + self deny: 1 i isNil. + self deny: nil equals: 1 i. + self deny: 1 i equals: #( 1 2 3 ). + self deny: #( 1 2 3 ) equals: 1 i ] { #category : #'testing - expressing complex numbers' } @@ -615,17 +614,17 @@ PMComplexNumberTest >> testQuotientsOfComplexNumbersCannotBeWritten [ numerator := PMComplexNumber real: 1 imaginary: 1. denominator := PMComplexNumber real: 3 imaginary: 4 . - self should: [ Fraction numerator: numerator denominator: denominator ] raise: Exception . + self should: [ Fraction numerator: numerator denominator: denominator ] raise: Exception ] { #category : #'testing - mathematical functions' } PMComplexNumberTest >> testRaisedTo [ - + | c c3 | c := (5 - 6 i). c3 := (c raisedTo: 0.2) raisedTo: 5. self assert: (c3 real closeTo: c real). - self assert: (c3 imaginary closeTo: c imaginary). + self assert: (c3 imaginary closeTo: c imaginary) ] { #category : #'testing - mathematical functions' } @@ -662,26 +661,24 @@ PMComplexNumberTest >> testReciprocal [ PMComplexNumberTest >> testSecureDivision1 [ "self run: #testSecureDivision1" "self debug: #testSecureDivision1" - + | c1 c2 quotient | c1 := 2.0e252 + 3.0e70 i. c2 := c1. quotient := c1 divideSecureBy: c2. - self assert: (quotient - 1) isZero. - + self assert: (quotient - 1) isZero ] { #category : #'testing - arithmetic' } PMComplexNumberTest >> testSecureDivision2 [ "self run: #testSecureDivision2" "self debug: #testSecureDivision2" - + | c1 c2 quotient | c1 := 2.0e252 + 3.0e70 i. c2 := c1. quotient := c1 divideFastAndSecureBy: c2. - self assert: (quotient - 1) isZero. - + self assert: (quotient - 1) isZero ] { #category : #'testing - mathematical functions' } @@ -693,7 +690,7 @@ PMComplexNumberTest >> testSin [ c := 2 + 3 i. c2 := c i exp - c i negated exp / 2 i. self assert: (c sin real closeTo: c2 real). - self assert: (c sin imaginary closeTo: c2 imaginary). + self assert: (c sin imaginary closeTo: c2 imaginary) ] { #category : #'testing - mathematical functions' } @@ -711,7 +708,7 @@ PMComplexNumberTest >> testSinh [ self assert: (c sinh imaginary closeTo: c2 imaginary). c2 := c i sin i negated. self assert: (c sinh real closeTo: c2 real). - self assert: (c sinh imaginary closeTo: c2 imaginary). + self assert: (c sinh imaginary closeTo: c2 imaginary) ] { #category : #'testing - mathematical functions' } @@ -721,9 +718,9 @@ PMComplexNumberTest >> testSquareRootOfANegativeRealNumberIsPureImaginary [ | squareRoot z | z := PMComplexNumber real: -4 imaginary: 0. - + squareRoot := z sqrt. - + self assert: squareRoot equals: 2 i ] @@ -731,7 +728,7 @@ PMComplexNumberTest >> testSquareRootOfANegativeRealNumberIsPureImaginary [ PMComplexNumberTest >> testSquareRootOfComplexNumberIsAComplexNumber [ | squareRoot z | z := PMComplexNumber real: 2 imaginary: 2. - + squareRoot := z sqrt. self assert: squareRoot real closeTo: 1.55377397. @@ -742,13 +739,12 @@ PMComplexNumberTest >> testSquareRootOfComplexNumberIsAComplexNumber [ PMComplexNumberTest >> testSquareRootOfNegativePureImaginaryNumberIsAComplexNumberWithRealAndImaginaryParts [ | squareRoot expected pureImaginaryNumber | pureImaginaryNumber := PMComplexNumber real: 0 imaginary: -4. - + squareRoot := pureImaginaryNumber sqrt. expected := 2 sqrt - 2 sqrt i. self assert: squareRoot real closeTo: expected real. self assert: squareRoot imaginary closeTo: expected imaginary - ] { #category : #'testing - mathematical functions' } @@ -758,7 +754,7 @@ PMComplexNumberTest >> testSquareRootOfPositivePureImaginaryNumberIsAComplexNumb | squareRoot expected pureImaginaryNumber | pureImaginaryNumber := PMComplexNumber real: 0 imaginary: 4. - + squareRoot := pureImaginaryNumber sqrt. expected := 2 sqrt + 2 sqrt i. @@ -773,7 +769,7 @@ PMComplexNumberTest >> testSquareRootOfPositiveRealNumberIsAComplexNumberWithOnl | squareRoot expected positiveRealNumber | positiveRealNumber := PMComplexNumber real: 6 imaginary: 0. - + squareRoot := positiveRealNumber sqrt. expected := PMComplexNumber real: 6 sqrt imaginary: 0. @@ -784,18 +780,18 @@ PMComplexNumberTest >> testSquareRootOfPositiveRealNumberIsAComplexNumberWithOnl PMComplexNumberTest >> testSquareRootOfVeryLargeRealAndVerySmallImaginary [ "This may cause problems because of the loss of precision. Very large and very small floating point numbers have different units of least precision. - + verySmall ~= 0. veryLarge + verySmall = veryLarge." | veryLarge verySmall complexNumber expected | - + veryLarge := 1e20. verySmall := 1e-20. - + complexNumber := veryLarge + verySmall i. expected := 1e10 + 1e-31 i. - + self assert: complexNumber sqrt closeTo: expected ] @@ -803,18 +799,18 @@ PMComplexNumberTest >> testSquareRootOfVeryLargeRealAndVerySmallImaginary [ PMComplexNumberTest >> testSquareRootOfVerySmallRealAndVeryLargeImaginary [ "This may cause problems because of the loss of precision. Very large and very small floating point numbers have different units of least precision. - + verySmall ~= 0. veryLarge + verySmall = veryLarge." | veryLarge verySmall complexNumber expected | - + veryLarge := 1e20. verySmall := 1e-20. - + complexNumber := verySmall + veryLarge i. expected := 7071067811.865476 + 7071067811.865475 i. - + self assert: complexNumber sqrt closeTo: expected ] @@ -822,9 +818,9 @@ PMComplexNumberTest >> testSquareRootOfVerySmallRealAndVeryLargeImaginary [ PMComplexNumberTest >> testSquareRootOfZeroIsZero [ | squareRoot expected | squareRoot := PMComplexNumber zero sqrt . - + expected := PMComplexNumber zero. - self assert: squareRoot equals: expected. + self assert: squareRoot equals: expected ] { #category : #'testing - mathematical functions' } @@ -854,7 +850,7 @@ PMComplexNumberTest >> testTan [ c := 2 + 3 i. c2 := c sin / c cos. self assert: (c2 real closeTo: c tan real). - self assert: (c2 imaginary closeTo: c tan imaginary). + self assert: (c2 imaginary closeTo: c tan imaginary) ] { #category : #'testing - mathematical functions' } @@ -866,7 +862,7 @@ PMComplexNumberTest >> testTanh [ c := 2 + 3 i. c2 := c sinh / c cosh. self assert: (c2 real closeTo: c tanh real). - self assert: (c2 imaginary closeTo: c tanh imaginary). + self assert: (c2 imaginary closeTo: c tanh imaginary) ] { #category : #'testing - equality' } @@ -875,7 +871,7 @@ PMComplexNumberTest >> testTwoComplexNumbersWithDifferentImaginaryPartsAreNotEqu z := 1 + 3 i. w := 1 + 2 i. - self deny: z equals: w. + self deny: z equals: w ] { #category : #'testing - equality' } @@ -884,16 +880,16 @@ PMComplexNumberTest >> testTwoComplexNumbersWithDifferentRealPartsAreNotEqual [ z := 4 + 3 i. w := -7 + 3 i. - self deny: z equals: w. + self deny: z equals: w ] { #category : #'testing - expressing complex numbers' } PMComplexNumberTest >> testWritingComplexNumbersWhoseRealAndImaginaryPartsAreFractions [ | z | z := PMComplexNumber real: 3 / 5 imaginary: 4 / 5. - + self assert: (z real) equals: (Fraction numerator: 3 denominator: 5). - self assert: (z imaginary) equals: (Fraction numerator: 4 denominator: 5). + self assert: (z imaginary) equals: (Fraction numerator: 4 denominator: 5) ] { #category : #'testing - expressing complex numbers' } @@ -903,16 +899,16 @@ PMComplexNumberTest >> testZero [ self assert: z isZero. self assert: z isComplexNumber. self assert: z real isZero. - self assert: z imaginary isZero. + self assert: z imaginary isZero ] { #category : #'testing - equality' } PMComplexNumberTest >> testZeroComplexNumberIsEqualToIntegerZero [ self assert: 0 i equals: 0. - self assert: 0 equals: 0 i. + self assert: 0 equals: 0 i ] { #category : #'testing - arithmetic' } PMComplexNumberTest >> testZeroComplexNumbersDoNotHaveAReciprocal [ - self should: [ PMComplexNumber zero reciprocal ] raise: ZeroDivide. + self should: [ PMComplexNumber zero reciprocal ] raise: ZeroDivide ] diff --git a/src/Math-Tests-Core-Process/PMFixpointTest.class.st b/src/Math-Tests-Core-Process/PMFixpointTest.class.st index 55d404e50..d499a7544 100644 --- a/src/Math-Tests-Core-Process/PMFixpointTest.class.st +++ b/src/Math-Tests-Core-Process/PMFixpointTest.class.st @@ -9,14 +9,16 @@ Class { { #category : #running } PMFixpointTest >> setUp [ -fp:=PMFixpoint new. -fp verbose: false. + + super setUp. + fp := PMFixpoint new. + fp verbose: false ] { #category : #tests } PMFixpointTest >> testBug [ fp - block: [ :x | + block: [ :x | x < 64 ifTrue: [ x bitShift: 2 ] ifFalse: [ 1 ] ]; @@ -38,7 +40,7 @@ PMFixpointTest >> testBug [ { #category : #tests } PMFixpointTest >> testCheckForLongerCycles [ fp := PMFixpoint - block: [ :x | + block: [ :x | | d | d := x - 1. d < -2 @@ -62,7 +64,7 @@ PMFixpointTest >> testCheckForLongerCycles [ { #category : #tests } PMFixpointTest >> testCheckStrongEquality [ fp - block: [ :x | + block: [ :x | | d | d := x - 1. d < -2 @@ -78,7 +80,7 @@ PMFixpointTest >> testCheckStrongEquality [ { #category : #tests } PMFixpointTest >> testEqualityTest [ fp - block: [ :x | + block: [ :x | | d | d := x - 1. d < -2 diff --git a/src/Math-Tests-Distributions/PMKolmogorovSmirnov1Sample.class.st b/src/Math-Tests-Distributions/PMKolmogorovSmirnov1Sample.class.st index 26a8d1328..2cb50ef81 100644 --- a/src/Math-Tests-Distributions/PMKolmogorovSmirnov1Sample.class.st +++ b/src/Math-Tests-Distributions/PMKolmogorovSmirnov1Sample.class.st @@ -24,12 +24,12 @@ Class { { #category : #'instance creation' } PMKolmogorovSmirnov1Sample class >> compareData: aCollection withDistribution: aDistribution [ -^self new data: aCollection ;populationDistribution: aDistribution ;yourself +^self new data: aCollection ;populationDistribution: aDistribution ;yourself ] { #category : #'instance creation' } PMKolmogorovSmirnov1Sample class >> data: aCollection [ -^self new data: aCollection ;yourself +^self new data: aCollection ;yourself ] { #category : #accessing } @@ -46,7 +46,7 @@ PMKolmogorovSmirnov1Sample >> ksStatistic [ | s d | s := data size. d := (1 to: s) - collect: [ :i | + collect: [ :i | | f | f := compareWith value: (data at: i). f - ((i - 1) / s) max: i / s - f ]. diff --git a/src/Math-Tests-Distributions/PMKolmogorovSmirnov1SampleTest.class.st b/src/Math-Tests-Distributions/PMKolmogorovSmirnov1SampleTest.class.st index 69870f0f0..bb8b57316 100644 --- a/src/Math-Tests-Distributions/PMKolmogorovSmirnov1SampleTest.class.st +++ b/src/Math-Tests-Distributions/PMKolmogorovSmirnov1SampleTest.class.st @@ -13,7 +13,7 @@ PMKolmogorovSmirnov1SampleTest >> numberOfRejectionsFor: aDistribution [ | n | test populationDistribution: aDistribution. n := 0. - 1 to: 100 do: [ :j | + 1 to: 100 do: [ :j | test data: ((1 to: 300) collect: [ :i | distribution random ]). (test rejectEqualityHypothesisWithAlpha: 0.05) ifTrue: [ n := n + 1 ] ]. @@ -38,16 +38,13 @@ PMKolmogorovSmirnov1SampleTest >> testCorrectPopulationProbabilistic [ { #category : #tests } PMKolmogorovSmirnov1SampleTest >> testRejectOfEqualityHypothesesForSampleVersusDistribution [ + | sample | "The data below are taken from http://www.maths.qmul.ac.uk/~bb/CTS_Chapter3_Students.pdf" - sample := #(-1.2 0.2 -0.6 0.8 -1.0). - test := PMKolmogorovSmirnov1Sample - compareData: sample - withDistribution: distribution. - - self - assert: (test rejectEqualityHypothesisWithAlpha: 0.05) - equals: false + sample := #( -1.2 0.2 -0.6 0.8 -1.0 ). + test := PMKolmogorovSmirnov1Sample compareData: sample withDistribution: distribution. + + self deny: (test rejectEqualityHypothesisWithAlpha: 0.05) ] { #category : #tests } diff --git a/src/Math-Tests-Distributions/PMKolmogorovSmirnov2Sample.class.st b/src/Math-Tests-Distributions/PMKolmogorovSmirnov2Sample.class.st index a01e9892c..9a1362e81 100644 --- a/src/Math-Tests-Distributions/PMKolmogorovSmirnov2Sample.class.st +++ b/src/Math-Tests-Distributions/PMKolmogorovSmirnov2Sample.class.st @@ -34,7 +34,7 @@ Class { { #category : #'instance creation' } PMKolmogorovSmirnov2Sample class >> compareData: aCollection withData: anotherCollection [ -^self new data: aCollection ;otherData: anotherCollection ;yourself +^self new data: aCollection ;otherData: anotherCollection ;yourself ] { #category : #private } @@ -56,7 +56,7 @@ PMKolmogorovSmirnov2Sample >> data: aCollection [ PMKolmogorovSmirnov2Sample >> initCachedUCalculation [ "recursive calc, slow without memoization" - uCalcBlock := [ :iandj | + uCalcBlock := [ :iandj | | cij i j | i := iandj first. j := iandj second. @@ -99,7 +99,7 @@ PMKolmogorovSmirnov2Sample >> ksStatistic [ addAll: compareWith; yourself. cdfs - withIndexDo: [ :a :i | + withIndexDo: [ :a :i | (i < s and: [ (cdfs at: i + 1) key = a key ]) ifTrue: [ a value second ifTrue: [ c2 := (cdfs at: i + 1) value first ] @@ -116,14 +116,14 @@ PMKolmogorovSmirnov2Sample >> ksStatistic [ { #category : #private } PMKolmogorovSmirnov2Sample >> makeCDFOf: aCollection intoFirst: aBoolean [ - "if aCollection consists of numbers, + "if aCollection consists of numbers, it returns a sorted array of (number-> (Array with: cdf with: aBoolean))" | cd s result | cd := 0. s := aCollection size. result := aCollection asBag sortedElements - do: [ :a | + do: [ :a | cd := a value / s + cd. a value: (Array with: cd with: aBoolean) ]. ^ aBoolean @@ -141,7 +141,7 @@ PMKolmogorovSmirnov2Sample >> otherData: aCollection [ PMKolmogorovSmirnov2Sample >> pValue [ "uses procedure explained in: -Kim, P. J. & Jennrich, R. I. +Kim, P. J. & Jennrich, R. I. 'Tables of the exact sampling distribution of the two-sample Kolmogorov–Smirnov criterion...' in 'Selected Tables in Mathematical Statistics Volume I' (1973)." diff --git a/src/Math-Tests-Distributions/PMKolmogorovSmirnov2SampleTest.class.st b/src/Math-Tests-Distributions/PMKolmogorovSmirnov2SampleTest.class.st index a875c7e3b..4849ed71e 100644 --- a/src/Math-Tests-Distributions/PMKolmogorovSmirnov2SampleTest.class.st +++ b/src/Math-Tests-Distributions/PMKolmogorovSmirnov2SampleTest.class.st @@ -20,18 +20,14 @@ PMKolmogorovSmirnov2SampleTest >> testRejectOfEqualityHypothesesForTwoSamples [ " | ks | - ks := PMKolmogorovSmirnov2Sample - compareData: #(1.2 1.4 1.9 3.7 4.4 4.8 9.7 17.3 21.1 28.4) - withData: #(5.6 6.5 6.6 6.9 9.2 10.4 10.6 19.3). - - self - assert: (ks rejectEqualityHypothesisWithAlpha: 0.05) - equals: true + ks := PMKolmogorovSmirnov2Sample compareData: #( 1.2 1.4 1.9 3.7 4.4 4.8 9.7 17.3 21.1 28.4 ) withData: #( 5.6 6.5 6.6 6.9 9.2 10.4 10.6 19.3 ). + + self assert: (ks rejectEqualityHypothesisWithAlpha: 0.05) ] { #category : #tests } PMKolmogorovSmirnov2SampleTest >> testSecondSmallSample [ - "sample from Kim, P. J. & Jennrich, R. I. + "sample from Kim, P. J. & Jennrich, R. I. Tables of the exact sampling distribution of the two-sample Kolmogorov–Smirnov criterion in Selected Tables in Mathematical Statistics Volume I (1973)" diff --git a/src/Math-Tests-Distributions/PMKolmogorovSmirnovSample.class.st b/src/Math-Tests-Distributions/PMKolmogorovSmirnovSample.class.st index 085318b86..71f95d949 100644 --- a/src/Math-Tests-Distributions/PMKolmogorovSmirnovSample.class.st +++ b/src/Math-Tests-Distributions/PMKolmogorovSmirnovSample.class.st @@ -13,19 +13,19 @@ Class { { #category : #accessing } PMKolmogorovSmirnovSample >> data: aCollection [ -^self subclassResponsibility +^self subclassResponsibility ] { #category : #accessing } PMKolmogorovSmirnovSample >> ksStatistic [ "the kolmogorov-smirnov statistic D" -^self subclassResponsibility +^self subclassResponsibility ] { #category : #accessing } PMKolmogorovSmirnovSample >> pValue [ "the probability of getting a ksStatistic <= the actual one" -^self subclassResponsibility +^self subclassResponsibility ] { #category : #printing } @@ -39,12 +39,10 @@ PMKolmogorovSmirnovSample >> printOn: aStream [ { #category : #accessing } PMKolmogorovSmirnovSample >> rejectEqualityHypothesisWithAlpha: aFloat [ -^self pValue > (1-aFloat) - +^self pValue > (1-aFloat) ] { #category : #private } PMKolmogorovSmirnovSample >> testDataComplete [ -(data isNil or:[compareWith isNil ]) ifTrue: [ self error:'data not completely set' ]. - +(data isNil or:[compareWith isNil ]) ifTrue: [ self error:'data not completely set' ] ] diff --git a/src/Math-Tests-Distributions/PMMultivariateNormalDistributionTest.class.st b/src/Math-Tests-Distributions/PMMultivariateNormalDistributionTest.class.st index 66f673e8b..c426527b9 100644 --- a/src/Math-Tests-Distributions/PMMultivariateNormalDistributionTest.class.st +++ b/src/Math-Tests-Distributions/PMMultivariateNormalDistributionTest.class.st @@ -12,16 +12,16 @@ Class { { #category : #running } PMMultivariateNormalDistributionTest >> setUp [ super setUp. - + meanVector := #(0 1) asPMVector. - + covarianceMatrix := PMMatrix rows: #( (1 0.8) (0.8 1)). - + distribution := PMMultivariateNormalDistribution meanVector: meanVector - covarianceMatrix: covarianceMatrix. + covarianceMatrix: covarianceMatrix ] { #category : #tests } @@ -42,17 +42,17 @@ PMMultivariateNormalDistributionTest >> testRandom [ { #category : #tests } PMMultivariateNormalDistributionTest >> testValue [ | interval points expectedPDF | - + interval := -1 to: 1 by: 0.5. - + points := interval flatCollect: [ :i | interval collect: [ :j | { i . j } asPMVector ] ]. - + "Values calculated using Python's scipy" expectedPDF := #(0.021773722141141552 0.08146294715905042 0.1521928217104107 0.14198250365871087 0.06614272766298167 0.0066868859054493935 0.043603973467720346 0.14198250365871087 0.23086080368580453 0.18744427741405117 0.0010254671663260122 0.011654633617442983 0.06614272766298167 0.18744427741405117 0.26525823848649227 7.852830360809077e-05 0.001555527859401226 0.015386363253590088 0.07599775773306434 0.18744427741405117 3.0028751901985315e-06 0.00010367250011136624 0.0017872959519927589 0.015386363253590088 0.06614272766298167). 1 to: points size do: [ :i | self assert: (distribution value: (points at: i)) - closeTo: (expectedPDF at: i) ]. + closeTo: (expectedPDF at: i) ] ] diff --git a/src/Math-Tests-Distributions/PMSmoothedDensityTest.class.st b/src/Math-Tests-Distributions/PMSmoothedDensityTest.class.st index d82a5f9b7..30119fce3 100644 --- a/src/Math-Tests-Distributions/PMSmoothedDensityTest.class.st +++ b/src/Math-Tests-Distributions/PMSmoothedDensityTest.class.st @@ -8,8 +8,10 @@ Class { } { #category : #running } -PMSmoothedDensityTest >> setUp [ -density:=PMKernelSmoothedDensity fromData: #(1 2 3 1 2.3 2.4). +PMSmoothedDensityTest >> setUp [ + + super setUp. + density := PMKernelSmoothedDensity fromData: #( 1 2 3 1 2.3 2.4 ) ] { #category : #tests } @@ -90,7 +92,7 @@ PMSmoothedDensityTest >> testNormal [ density normal. r := 0.2419707245. self assert: - ((#( 1 0 -1 -2.9 ) collect: [ :x | density kernel value: x ]) + ((#( 1 0 -1 -2.9 ) collect: [ :x | density kernel value: x ]) closeTo: (Array with: r with: 0.3989422804 @@ -109,8 +111,7 @@ density printOn: aStream . s :=aStream contents . self assert: ((s findString: 'normal')>0). self assert: ((s findString: '6')>0). -self assert: ((s findString: '0.50589967')>0). - +self assert: ((s findString: '0.50589967')>0) ] { #category : #tests } diff --git a/src/Math-Tests-Distributions/PMStatisticsBugs.class.st b/src/Math-Tests-Distributions/PMStatisticsBugs.class.st index 847b075ed..2186c7d3f 100644 --- a/src/Math-Tests-Distributions/PMStatisticsBugs.class.st +++ b/src/Math-Tests-Distributions/PMStatisticsBugs.class.st @@ -115,7 +115,7 @@ PMStatisticsBugs >> testProbabilityDensity [ 0.9). "zerodivide" self assert: - ((a distributionValue: (a inverseDistributionValue: 0.001)) + ((a distributionValue: (a inverseDistributionValue: 0.001)) closeTo: 0.001). "ok" a := PMFisherTippettDistribution shape: -3 scale: 0.7. @@ -139,7 +139,7 @@ PMStatisticsBugs >> testProbabilityDensity [ 0.7). "zerodivide" self assert: - ((a distributionValue: (a inverseDistributionValue: 0.004)) + ((a distributionValue: (a inverseDistributionValue: 0.004)) closeTo: 0.004). "zerodivide" a := PMChiSquareDistribution degreeOfFreedom: 300. @@ -148,7 +148,7 @@ PMStatisticsBugs >> testProbabilityDensity [ 0.7). "'Function''s derivative seems to be zero everywhere'" self assert: - ((a distributionValue: (a inverseDistributionValue: 0.004)) + ((a distributionValue: (a inverseDistributionValue: 0.004)) closeTo: 0.004). "ok" self assert: @@ -163,7 +163,7 @@ PMStatisticsBugs >> testProbabilityDensity [ 0.7). "zerodivide" self assert: - ((a distributionValue: (a inverseDistributionValue: 0.004)) + ((a distributionValue: (a inverseDistributionValue: 0.004)) closeTo: 0.004). "zerodivide" a := PMLogNormalDistribution new: 3 sigma: 1.4. @@ -205,7 +205,7 @@ PMStatisticsBugs >> testProbabilityDensity [ ((a distributionValue: (a inverseDistributionValue: 0)) closeTo: 0). "ok" self assert: - ((a distributionValue: (a inverseDistributionValue: 0.333333)) + ((a distributionValue: (a inverseDistributionValue: 0.333333)) closeTo: 0.333333). "ok" a := PMWeibullDistribution shape: 0.5 scale: 1. @@ -320,7 +320,7 @@ PMStatisticsBugs >> testProbabilityDensity [ ((a distributionValue: (a inverseDistributionValue: 1.0)) closeTo: 1). "ok" - "a:=KernelSmoothedDensity fromData: #(1 2 3 1 2.3 2.4). + "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'" @@ -333,10 +333,10 @@ self assert: ((a distributionValue: (a inverseDistributionValue: 0.9))equalsTo: "zerod" a := PMHistogram new. random := Random new. - + 20 timesRepeat: [ a accumulate: (random nextBetween: 0 and: 7) ]. - + b := PMHistogrammedDistribution histogram: a. self assert: ((b distributionValue: (b inverseDistributionValue: 0.99)) closeTo: @@ -346,7 +346,7 @@ self assert: ((a distributionValue: (a inverseDistributionValue: 0.9))equalsTo: ((b distributionValue: (b inverseDistributionValue: 0.0)) closeTo: 0). "ok" self assert: - ((b distributionValue: (b inverseDistributionValue: 1.0) asFloat) + ((b distributionValue: (b inverseDistributionValue: 1.0) asFloat) closeTo: 1) "ok" ] diff --git a/src/Math-Tests-FastFourierTransform/PMFFTTest.class.st b/src/Math-Tests-FastFourierTransform/PMFFTTest.class.st index c13c974d9..42bf0acce 100644 --- a/src/Math-Tests-FastFourierTransform/PMFFTTest.class.st +++ b/src/Math-Tests-FastFourierTransform/PMFFTTest.class.st @@ -7,7 +7,7 @@ Class { { #category : #tests } PMFFTTest >> generateCosineWaveSignal: sampleSize [ - ^ (1 to: sampleSize) collect: [ :i | + ^ (1 to: sampleSize) collect: [ :i | (Float pi * (i - 1) / (sampleSize / 8)) cos ] ] @@ -71,30 +71,30 @@ PMFFTTest >> testFastFourierTransformCalculatesTheDiscreteFourierTransformWithou PMFFTTest >> testFrequencyDomainRepresentationMatchesRandomizedInputSignalClosely [ | random cosineWaveSignal randomizedCosineWaveSignal fourier | - + cosineWaveSignal := self generateCosineWaveSignal: 256. random := Random new. - + randomizedCosineWaveSignal := cosineWaveSignal collect: [ :i | i + (random nextBetween: 0 and: 0.001) - 0.0005 ]. - + fourier := PMFastFourierTransform data: randomizedCosineWaveSignal. fourier transform. fourier chop: 0.01. fourier inverseTransform. - + fourier realData with: cosineWaveSignal do: [ :expected :actual | - self assert: actual closeTo: expected ]. + self assert: actual closeTo: expected ] ] { #category : #tests } -PMFFTTest >> testThatChopSuccessivelyRemovesInputSignalPointsLowerThanTolerance [ +PMFFTTest >> testThatChopSuccessivelyRemovesInputSignalPointsLowerThanTolerance [ | inputSignal f | inputSignal := #(-2 -2 -2 3 3 3 1 -2). f := PMFastFourierTransform data: inputSignal. f chop: 1.01. self assert: f realData equals: #(-2 -2 -2 3 3 3 0 -2). f chop: 2.01. - self assert: f realData equals: #(0 0 0 3 3 3 0 0). + self assert: f realData equals: #(0 0 0 3 3 3 0 0) ] diff --git a/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st b/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st index 8977402eb..9918eac11 100644 --- a/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st +++ b/src/Math-Tests-FunctionFit/PMAnotherChromosomeManagerTest.class.st @@ -17,15 +17,17 @@ PMAnotherChromosomeManagerTest >> setHammersleyTest: aBoolean [ self assert: (cm population anySatisfy: [ :g | g second < 2 ]). self assert: (cm population anySatisfy: [ :g | g second > 3 ]). cm population - do: [ :i | + do: [ :i | self assert: i size equals: 2. self assert: (i first between: 0 and: 2). self assert: (i second between: 1 and: 4) ] ] { #category : #running } -PMAnotherChromosomeManagerTest >> setUp [ -cm:=(PMAnotherChromosomeManager origin: #(0 1) range: #( 2 3)). +PMAnotherChromosomeManagerTest >> setUp [ + + super setUp. + cm := PMAnotherChromosomeManager origin: #( 0 1 ) range: #( 2 3 ) ] { #category : #tests } @@ -37,18 +39,20 @@ PMAnotherChromosomeManagerTest >> testAccessing [ { #category : #tests } PMAnotherChromosomeManagerTest >> testCrossOver [ -|a| -1 to: 20 do: [:i| a:=cm 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)). - self assert: (#(3 6) includes:((a at: index) at: 3)).]. - self deny: (((a at: 1)at: 2)=((a at: 2)at: 2)). - self deny: (((a at: 1)at: 1)=((a at: 2)at: 1)). - self deny: (((a at: 1)at: 3)=((a at: 2)at: 3)). - a]. -a:= a collect: [:g|g first]. -self assert: ((a occurrencesOf: #(1 2 3))<20). + + | a | + 1 to: 20 do: [ :i | + a := cm 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)). + self assert: (#( 3 6 ) includes: ((a at: index) at: 3)) ]. + self deny: ((a at: 1) at: 2) equals: ((a at: 2) at: 2). + self deny: ((a at: 1) at: 1) equals: ((a at: 2) at: 1). + self deny: ((a at: 1) at: 3) equals: ((a at: 2) at: 3). + a ]. + a := a collect: [ :g | g first ]. + self assert: (a occurrencesOf: #( 1 2 3 )) < 20 ] { #category : #tests } @@ -74,8 +78,7 @@ self shouldnt: [a:=cm eirCrossover: #(1 -3) and: #(1 -3)] raise: Error. self assert: (((a at: 1)at:2) between: -2 and: 2). self assert: (((a at: 2)at:1) between: -2 and: 0). self assert: (((a at: 2)at:2) between: -2 and: 0). - ]. - + ]. ] { #category : #tests } @@ -117,8 +120,7 @@ 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). - +self assert: (s size between: 3 and: 20) ] { #category : #tests } @@ -128,8 +130,7 @@ aStream :=ReadWriteStream with:''. cm printOn: aStream . s :=aStream contents . self assert: (s includesSubstring: '#(0 1)'). -self assert: (s includesSubstring: '#(2 3)'). - +self assert: (s includesSubstring: '#(2 3)') ] { #category : #tests } @@ -145,15 +146,15 @@ PMAnotherChromosomeManagerTest >> testProcessand [ { #category : #tests } PMAnotherChromosomeManagerTest >> testRandomizePopulation [ -|g| -self setHammersleyTest: true. -g :=cm population first. -self setHammersleyTest: false. -self deny: (cm population first =g). -g :=cm population first. -self setHammersleyTest: false. -self deny: (cm population first =g). + | g | + self setHammersleyTest: true. + g := cm population first. + self setHammersleyTest: false. + self deny: cm population first equals: g. + g := cm population first. + self setHammersleyTest: false. + self deny: cm population first equals: g ] { #category : #tests } @@ -170,14 +171,13 @@ self should: [cm rateOfEir: 0.26] raise: Warning . self should: [cm 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 . - +self should: [cm rateOfCrossover: 0.1500001] raise: Warning ] { #category : #tests } PMAnotherChromosomeManagerTest >> testlineCrossOver [ | a | - 1 to: 10 do: [ :i | + 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 ] @@ -221,7 +221,7 @@ PMAnotherChromosomeManagerTest >> testnumberOfHamersleyPoints [ dimension: 4 randomized: true). rand - do: [ :i | + do: [ :i | self assert: i first >= 0. self assert: (i at: 2) < 0. self assert: (i at: 3) < 0 ]. diff --git a/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st b/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st index 32ed4de21..94635e186 100644 --- a/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st +++ b/src/Math-Tests-FunctionFit/PMAnotherGeneticOptimizerTest.class.st @@ -11,15 +11,13 @@ Class { PMAnotherGeneticOptimizerTest >> setUp [ | origin f | - f := [ :x | + super setUp. + f := [ :x | | v | v := x asPMVector. v * v ]. origin := #( -5 -5 -5 ). - go := PMAnotherGeneticOptimizer - function: f - minimumValues: origin - maximumValues: origin negated. + go := PMAnotherGeneticOptimizer function: f minimumValues: origin maximumValues: origin negated. go maximumIterations: 50. go chromosomeManager populationSize: 20 ] @@ -40,8 +38,7 @@ go evaluate . r:=go computePrecision:0. go maximumIterations: 50 . go evaluate . -self assert: (r>go computePrecision ). - +self assert: (r>go computePrecision ) ] { #category : #tests } @@ -54,17 +51,15 @@ PMAnotherGeneticOptimizerTest >> testEvaluate [ { #category : #tests } PMAnotherGeneticOptimizerTest >> testInitializeIterations [ -self assert: (go bestPoints isEmpty ). -go initializeIterations . -self deny: (go bestPoints isEmpty ). -go calcStatistics: true. -go evaluate . -self deny: (go bestValueHistory isEmpty ). -go initializeIterations . -self assert: (go bestValueHistory isEmpty ). - - + 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 ] { #category : #tests } @@ -95,7 +90,7 @@ PMAnotherGeneticOptimizerTest >> testRangeScaleProbabilistic [ | r1 r2 correct | correct := 0. 9 - timesRepeat: [ + timesRepeat: [ self setUp. go maximumIterations: 500. go rangeScale: true. @@ -115,7 +110,7 @@ PMAnotherGeneticOptimizerTest >> testRemoveLastProbabilistic [ | r1 r2 correct | correct := 0. 3 - timesRepeat: [ + timesRepeat: [ self setUp. go maximumIterations: 1000. go removeLast: true. @@ -141,8 +136,7 @@ self setUp . go steadyState: true. go maximumIterations: 1000. r2 :=go evaluate norm. -self assert: (r1>r2 ). - +self assert: (r1>r2 ) ] { #category : #tests } @@ -174,11 +168,12 @@ PMAnotherGeneticOptimizerTest >> testaddPointAt [ { #category : #tests } PMAnotherGeneticOptimizerTest >> testcalcStatistics [ + | s | go evaluate. - self assert: go bestValueHistory isEmpty. - self assert: go worstValueHistory isEmpty. - self assert: go whateverHistory isEmpty. + self assertEmpty: go bestValueHistory. + self assertEmpty: go worstValueHistory. + self assertEmpty: go whateverHistory. go calcStatistics: true. go evaluate. s := go iterations. @@ -189,8 +184,8 @@ PMAnotherGeneticOptimizerTest >> testcalcStatistics [ { #category : #tests } PMAnotherGeneticOptimizerTest >> testresetBestPoints [ -go evaluate . -go resetBestPoints . -self assert: (go bestPoints isEmpty ). + go evaluate. + go resetBestPoints. + self assertEmpty: go bestPoints ] diff --git a/src/Math-Tests-FunctionFit/PMDataHolderTest.class.st b/src/Math-Tests-FunctionFit/PMDataHolderTest.class.st index 97bec4ba3..aa937fa2d 100644 --- a/src/Math-Tests-FunctionFit/PMDataHolderTest.class.st +++ b/src/Math-Tests-FunctionFit/PMDataHolderTest.class.st @@ -8,5 +8,5 @@ Class { PMDataHolderTest >> testpointsAndErrorsDo [ |g| g:=PMDataHolder new: 2 withAll: 2@3. -g pointsAndErrorsDo: [:i|( i xValue =2)ifFalse:[self error].( i yValue =3)ifFalse:[self error].( i weight=1)ifFalse:[self error]]. +g pointsAndErrorsDo: [:i|( i xValue =2)ifFalse:[self error].( i yValue =3)ifFalse:[self error].( i weight=1)ifFalse:[self error]] ] diff --git a/src/Math-Tests-FunctionFit/PMErrorAsParameterFunctionTest.class.st b/src/Math-Tests-FunctionFit/PMErrorAsParameterFunctionTest.class.st index 38cc9cd29..8857a80d0 100644 --- a/src/Math-Tests-FunctionFit/PMErrorAsParameterFunctionTest.class.st +++ b/src/Math-Tests-FunctionFit/PMErrorAsParameterFunctionTest.class.st @@ -11,18 +11,16 @@ Class { PMErrorAsParameterFunctionTest >> setUp [ | col | - f := PMErrorOfParameterFunction new function: [ :x :a :b | - a * x / (b + x) ]. - col := (1 to: 3) collect: [ :i | - i @ (f function cull: i cull: 1 cull: 1) ]. + super setUp. + f := PMErrorOfParameterFunction new function: [ :x :a :b | a * x / (b + x) ]. + col := (1 to: 3) collect: [ :i | i @ (f function cull: i cull: 1 cull: 1) ]. f data: col. f := PMErrorAsParameterFunction new function: f ] { #category : #tests } PMErrorAsParameterFunctionTest >> testMaxFunction [ -self assert: (f parameters size < f maxFunction ). - +self assert: (f parameters size < f maxFunction ) ] { #category : #tests } diff --git a/src/Math-Tests-FunctionFit/PMErrorOfParameterFunctionTest.class.st b/src/Math-Tests-FunctionFit/PMErrorOfParameterFunctionTest.class.st index 812f9da9b..6cd7c5c52 100644 --- a/src/Math-Tests-FunctionFit/PMErrorOfParameterFunctionTest.class.st +++ b/src/Math-Tests-FunctionFit/PMErrorOfParameterFunctionTest.class.st @@ -11,10 +11,10 @@ Class { { #category : #running } PMErrorOfParameterFunctionTest >> setUp [ - f := PMErrorOfParameterFunction new function: [ :x :a :b | - a * x / (b + x) ]. - col := (1 to: 3) collect: [ :i | - i @ (f function cull: i cull: 1 cull: 1) ] + super setUp. + + f := PMErrorOfParameterFunction new function: [ :x :a :b | a * x / (b + x) ]. + col := (1 to: 3) collect: [ :i | i @ (f function cull: i cull: 1 cull: 1) ] ] { #category : #tests } @@ -65,9 +65,7 @@ f printOn: aStream . s :=aStream contents . self assert: (s includesSubstring: 'a * x / (b + x)'). self assert: (s includesSubstring: 'squared'). -self assert: (s includesSubstring: 'false'). - - +self assert: (s includesSubstring: 'false') ] { #category : #tests } diff --git a/src/Math-Tests-FunctionFit/PMFunctionFitTest.class.st b/src/Math-Tests-FunctionFit/PMFunctionFitTest.class.st index 2540d4db3..55360ecb0 100644 --- a/src/Math-Tests-FunctionFit/PMFunctionFitTest.class.st +++ b/src/Math-Tests-FunctionFit/PMFunctionFitTest.class.st @@ -11,6 +11,8 @@ Class { { #category : #running } PMFunctionFitTest >> setUp [ + super setUp. + f := [ :x :a :b | a * x / (b + x) ]. d := (1 to: 20) collect: [ :i | i @ (f cull: i cull: 2 cull: 0.4) ] ] @@ -21,7 +23,7 @@ PMFunctionFitTest >> testFunctionFit [ | ff ar p | ff := PMFunctionFit function: f data: d. ar := ff parameters. - ar do: [ :i | + ar do: [ :i | self assert: i isNumber. self assert: i ~= 0 ]. ff parameters: #( 1 2 ). @@ -41,7 +43,5 @@ ff:= PMFunctionFit function: f data: d . ff printOn: aStream . s :=aStream contents . self assert: (s includesSubstring: 'a * x / (b + x)'). -self assert: (s includesSubstring: '20'). - - +self assert: (s includesSubstring: '20') ] diff --git a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st index 036df3a23..d058e1c39 100644 --- a/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st +++ b/src/Math-Tests-FunctionFit/PMGeneralFunctionFitTest.class.st @@ -13,6 +13,8 @@ Class { PMGeneralFunctionFitTest >> 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. @@ -74,7 +76,7 @@ PMGeneralFunctionFitTest >> testMaximumIterationsProbabilistic [ correct := 0. fit populationSize: 20. 7 - timesRepeat: [ + timesRepeat: [ fit resetBestPoints. fit maximumIterations: 200. r := (fit evaluate - #(0.1 0.4)) abs. @@ -104,10 +106,7 @@ 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 < 1e-6 ) ] { #category : #tests } @@ -125,7 +124,7 @@ fit evaluate . aStream :=ReadWriteStream with:''. fit printOn: aStream . s :=aStream contents . -self assert: (s includesSubstring: '#(0.'). +self assert: (s includesSubstring: '#(0.') ] { #category : #tests } @@ -154,10 +153,15 @@ PMGeneralFunctionFitTest >> testRelativeError [ { #category : #tests } PMGeneralFunctionFitTest >> testResetBestPoints [ -fit:=PMGeneralFunctionFit function: f data: col minimumValues: 0 maximumValues: 5 . -fit evaluate . -fit resetBestPoints. -self assert: (fit optimizer bestPoints isEmpty ). + + fit := PMGeneralFunctionFit + function: f + data: col + minimumValues: 0 + maximumValues: 5. + fit evaluate. + fit resetBestPoints. + self assertEmpty: fit optimizer bestPoints ] { #category : #tests } diff --git a/src/Math-Tests-FunctionFit/PMSimpleParameterFunctionTest.class.st b/src/Math-Tests-FunctionFit/PMSimpleParameterFunctionTest.class.st index 2fb363889..d3464155c 100644 --- a/src/Math-Tests-FunctionFit/PMSimpleParameterFunctionTest.class.st +++ b/src/Math-Tests-FunctionFit/PMSimpleParameterFunctionTest.class.st @@ -9,7 +9,7 @@ Class { { #category : #running } PMSimpleParameterFunctionTest >> setUp [ - f:=[:a :x :cc :b|x]. + f:=[:a :x :cc :b|x] ] { #category : #tests } @@ -37,8 +37,7 @@ s :=aStream contents . self assert: ((s beginsWith: 'a PMSimpleParameterFunction')). self assert: (s includesSubstring: '1'). self assert: (s includesSubstring: ' 2'). -self assert: (s includesSubstring: ' 3'). - +self assert: (s includesSubstring: ' 3') ] { #category : #tests } diff --git a/src/Math-Tests-KDTree/PMKDTreeTest.class.st b/src/Math-Tests-KDTree/PMKDTreeTest.class.st index b0f67ab8c..2ea888616 100644 --- a/src/Math-Tests-KDTree/PMKDTreeTest.class.st +++ b/src/Math-Tests-KDTree/PMKDTreeTest.class.st @@ -19,14 +19,16 @@ self assert: ( (aResult with: bResult collect: [:a :b|a hasEqualElements: b] ] { #category : #running } -PMKDTreeTest >> initializeTreeWith: aCollection as: simpleTree [ +PMKDTreeTest >> initializeTreeWith: aCollection as: simpleTree [ "used to initialize all tests" stupid :=PMStupidNN withAll: aCollection. -tree := simpleTree ifTrue: [ PMKDTree withAll: aCollection ] ifFalse: [PMIndexedKDTree withAll: aCollection ]. +tree := simpleTree ifTrue: [ PMKDTree withAll: aCollection ] ifFalse: [PMIndexedKDTree withAll: aCollection ] ] { #category : #running } PMKDTreeTest >> setUp [ + + super setUp. rand := Random new ] @@ -50,8 +52,8 @@ PMKDTreeTest >> testIndexedKDTree1Dimension [ self initializeTreeWith: m as: false. 1 to: 11 do: [:v | aVector := Array with: 1 / v asFloat. aResult := stupid nnSearch: aVector i: 3. "3 nearest numbers to aVector " - bResult := m atAll: ((tree nnSearch: aVector i: 3) collect: [:a | a first]). - self equalityTest: aResult and: bResult]. + bResult := m atAll: ((tree nnSearch: aVector i: 3) collect: [:a | a first]). + self equalityTest: aResult and: bResult] ] { #category : #tests } @@ -62,8 +64,7 @@ PMKDTreeTest >> testIndexedKDTree4Dimensions [ 50 timesRepeat: [aVector := (rand next: 4) - 0.5. aResult := stupid nnSearch: aVector i: 2. "2 nearest neighbours" bResult := m atAll: ((tree nnSearch: aVector i: 2)collect: [:a | a first]). - self equalityTest: aResult and: bResult]. - + self equalityTest: aResult and: bResult]. ] { #category : #tests } @@ -83,7 +84,7 @@ PMKDTreeTest >> testIndexedKDTreeSimple [ withAll: (r collect: [ :i | Float32Array with: i with: i ]). "2-dimensional data" bTree := PMIndexedKDTree withAll: (r collect: [ :i | Float32Array with: i ]). "1-dimensional data" - 1 to: 20 do: [ :v | + 1 to: 20 do: [ :v | n := 1 / v. self assert: (aTree nnSearch: (Array with: n with: n) i: 1) @@ -97,8 +98,8 @@ PMKDTreeTest >> testKDTree1Dimension [ self initializeTreeWith: m as: true . 1 to: 11 do: [:v | aVector := Array with: 1 / v asFloat. aResult := stupid nnSearch: aVector i: 3. "3 nearest numbers to aVector " - bResult := tree nnSearch: aVector i: 3. - self equalityTest: aResult and: bResult]. + bResult := tree nnSearch: aVector i: 3. + self equalityTest: aResult and: bResult] ] { #category : #tests } @@ -109,7 +110,7 @@ PMKDTreeTest >> testKDTree1DimensionIntegers [ 0 to: 11 do:[:v | aVector := Array with: v. aResult :=(aVector first - (stupid nnSearch: aVector i: 3)) abs. "distances between 3 nearest numbers and aVector " bResult :=(aVector first - (tree nnSearch: aVector i: 3)) abs. "distances using KDTree" - self equalityTest: aResult and: bResult ] . + self equalityTest: aResult and: bResult ] ] { #category : #tests } @@ -119,7 +120,7 @@ self initializeTreeWith: ((1 to: 2000) collect: [:n| (rand next:2)]) as: true 100 timesRepeat: [aVector :=rand next:2. aResult :=stupid nnSearch: aVector i:3. bResult :=tree nnSearch: aVector i:3. - self equalityTest: aResult and: bResult ] . + self equalityTest: aResult and: bResult ] . ] { #category : #tests } @@ -127,9 +128,9 @@ PMKDTreeTest >> testKDTree4Dimensions [ |aVector| self initializeTreeWith: ((1 to: 2000) collect: [:n| (rand next:4)-0.5]) as: true . "4-dimensional data" 50 timesRepeat: [aVector :=(rand next: 4)- 0.5. "2 nearest neighbours" - self equalityTest: (stupid nnSearch: aVector i:2) and: (tree nnSearch: aVector i:2) ] . + self equalityTest: (stupid nnSearch: aVector i:2) and: (tree nnSearch: aVector i:2) ] . 50 timesRepeat: [aVector :=(rand next: 4)-0.5. "just 1 nearest neighbour" - self assert: ( (stupid nnSearch: aVector i:1) hasEqualElements: (tree nnSearch: aVector i:1) ) ] . + self assert: ( (stupid nnSearch: aVector i:1) hasEqualElements: (tree nnSearch: aVector i:1) ) ] . ] { #category : #tests } diff --git a/src/Math-Tests-KDTree/PMNNStoreTest.class.st b/src/Math-Tests-KDTree/PMNNStoreTest.class.st index 66fc0dccf..40ffa14f4 100644 --- a/src/Math-Tests-KDTree/PMNNStoreTest.class.st +++ b/src/Math-Tests-KDTree/PMNNStoreTest.class.st @@ -13,87 +13,90 @@ PMNNStoreTest >> testCopy [ "a separate copy method is necessary because of this scenario" | a b | - a := PMNNStore withAll: #(1 2 4). + a := PMNNStore withAll: #( 1 2 4 ). b := a copy. self assert: b equals: a. self assert: b hash equals: a hash. b sortFor: nil. - self deny: b = a. "here is the problem" - self deny: b hash = a hash + self deny: b equals: a. "here is the problem" + self deny: b hash equals: a hash ] { #category : #tests } PMNNStoreTest >> testCopyEmpty [ + | n m | - n := PMNNStore newFrom: #(#(1 $a) #(3 1.0) #(0 '2')). + n := PMNNStore newFrom: #( #( 1 $a ) #( 3 1.0 ) #( 0 '2' ) ). n := n copyEmpty. - self assert: n isEmpty. + self assertEmpty: n. n - add: #(2 10); - add: #(1 100). - self deny: n isEmpty. - self assert: n maxDistance equals: Float infinity. "because it is not yet full" - self assert: n data equals: #(100 10). + add: #( 2 10 ); + add: #( 1 100 ). + self denyEmpty: n. + self assert: n maxDistance equals: Float infinity. "because it is not yet full" + self assert: n data equals: #( 100 10 ). m := n copyEmpty. - self assert: m size equals: 2. "size is reduced now" + self assert: m size equals: 2. "size is reduced now" m - add: #(2 10); - add: #(1 100). - self deny: m = n. + add: #( 2 10 ); + add: #( 1 100 ). + self deny: m equals: n. self assert: m completeData equals: n completeData ] { #category : #tests } PMNNStoreTest >> testEqual [ + | a b | - b := #(#(1 $a) #(3 1.0) #(0 '2')). + b := #( #( 1 $a ) #( 3 1.0 ) #( 0 '2' ) ). a := PMNNStore newFrom: b. - self deny: a = b. - b := PMNNStore newFrom: #(#(1 $a) #(3 1.0) #(0 2)). - self deny: a = b. + self deny: a equals: b. + b := PMNNStore newFrom: #( #( 1 $a ) #( 3 1.0 ) #( 0 2 ) ). + self deny: a equals: b. b := a copyEmpty. - self deny: a = b. - b addAll: #(#(3 1.0) #(1 $a) #(4 true) #(0 '2')). + self deny: a equals: b. + b addAll: #( #( 3 1.0 ) #( 1 $a ) #( 4 true ) #( 0 '2' ) ). self assert: a equals: b. - b add: #(2 nil). - self deny: a = b. + b add: #( 2 nil ). + self deny: a equals: b. b := PMNNStore new: 3. a := PMNNStore new: 2. - a add: #(2 nil). - b add: #(2 nil). - self deny: a = b. - self deny: b hash = a hash + a add: #( 2 nil ). + b add: #( 2 nil ). + self deny: a equals: b. + self deny: b hash equals: a hash ] { #category : #tests } PMNNStoreTest >> testExtremeCase [ + | n | n := PMNNStore new. - n sortFor: nil. "this should indeed always be possible and shouldnt raise an error!" + n sortFor: nil. "this should indeed always be possible and shouldnt raise an error!" self assert: n isFull. - n add: #(1 1). "adding should also always be possible, although it will not be added in this case" - self deny: n maxDistance = 1. - n - add: (Array with: (0 - Float infinity) with: 1). "and this extreme case too." - self assert: n isEmpty. - self assert: n data equals: #(). - self should: [ n add: (Array with: nil with: 1) ] raise: Error "but this should always raise an error (not only in NNStores with size 0), also in subclasses, otherwise one can have strange bugs" + n add: #( 1 1 ). "adding should also always be possible, although it will not be added in this case" + self deny: n maxDistance equals: 1. + n add: (Array with: 0 - Float infinity with: 1). "and this extreme case too." + self assertEmpty: n. + self assert: n data equals: #( ). + self should: [ n add: (Array with: nil with: 1) ] raise: Error "but this should always raise an error (not only in NNStores with size 0), also in subclasses, otherwise one can have strange bugs" ] { #category : #tests } PMNNStoreTest >> testInitialize [ + | a b | - a := PMNNStore newFrom: #(#(4 $a) #(5 1.0) #(6 '2')). - b := (PMNNStore newFrom: #(#(4 $a) #(5 1.0) #(6 '2'))) initialize. - self deny: a = b. + a := PMNNStore newFrom: #( #( 4 $a ) #( 5 1.0 ) #( 6 '2' ) ). + b := (PMNNStore newFrom: #( #( 4 $a ) #( 5 1.0 ) #( 6 '2' ) )) initialize. + self deny: a equals: b. a initialize. self assert: a equals: b. - b add: #(4 $a). - self deny: a = b. - a add: #(4 $a). + b add: #( 4 $a ). + self deny: a equals: b. + a add: #( 4 $a ). self assert: a equals: b. - a add: #(5 1.0). - self deny: a = b + a add: #( 5 1.0 ). + self deny: a equals: b ] { #category : #tests } @@ -101,16 +104,16 @@ PMNNStoreTest >> testInitialize2 [ "a separate = method is necessary because of this scenario with resetting" | a b c | - a := (PMNNStore newFrom: #(#(1 $a) #(3 1.0) #(0 '2'))) initialize. "initialize = resetting" - b := (PMNNStore newFrom: #(#(1 $a) #(3 false) #(0 '2'))) initialize. - self assert: a equals: b. "first problematic part" - c := #(#(3 true) #(2 1)). + a := (PMNNStore newFrom: #( #( 1 $a ) #( 3 1.0 ) #( 0 '2' ) )) initialize. "initialize = resetting" + b := (PMNNStore newFrom: #( #( 1 $a ) #( 3 false ) #( 0 '2' ) )) initialize. + self assert: a equals: b. "first problematic part" + c := #( #( 3 true ) #( 2 1 ) ). a addAll: c. b addAll: c. - self assert: a equals: b. "second problematic part" - c := #(2 nil). + self assert: a equals: b. "second problematic part" + c := #( 2 nil ). a add: c. - self deny: a = b. + self deny: a equals: b. b add: c. self assert: a equals: b ] @@ -128,14 +131,15 @@ PMNNStoreTest >> testInitialize3 [ { #category : #tests } PMNNStoreTest >> testNew [ + | n | n := PMNNStore new: 1. - self assert: n isEmpty. - self assert: n data equals: #(). - self assert: n completeData equals: #(). - n add: #(1 2). - n add: #(3 1). "will not be added" - self assert: n data equals: #(2) + self assertEmpty: n. + self assert: n data equals: #( ). + self assert: n completeData equals: #( ). + n add: #( 1 2 ). + n add: #( 3 1 ). "will not be added" + self assert: n data equals: #( 2 ) ] { #category : #tests } @@ -150,13 +154,14 @@ PMNNStoreTest >> testNew2 [ { #category : #tests } PMNNStoreTest >> testNew3 [ + | n | n := PMNNStore new: 0. - self assert: n isEmpty. + self assertEmpty: n. self assert: n isFull. self assert: n equals: n copyEmpty. - self assert: n data equals: #(). - self assert: n completeData equals: #() + self assert: n data equals: #( ). + self assert: n completeData equals: #( ) ] { #category : #tests } @@ -176,18 +181,16 @@ PMNNStoreTest >> testNewFrom [ { #category : #tests } PMNNStoreTest >> testWithAll [ - | n array | + | n | n := PMNNStore withAll: #( 2 5 4 ). - self - assert: n completeData - equals: #( #( nil 2 ) #( nil 5 ) #( nil 4 ) ). + self assert: n completeData equals: #( #( nil 2 ) #( nil 5 ) #( nil 4 ) ). n sortFor: nil. "calling sortFor: is necessary with withAll:" self assert: n data equals: #( 2 4 5 ). self assert: n isFull. - n add: #(3 6) copy. - - "one has to be a bit carefull when one uses - PMNNStore withAll:, as sortfor: changes this data. + n add: #( 3 6 ) copy. + + "one has to be a bit carefull when one uses + PMNNStore withAll:, as sortfor: changes this data. n add: #(3 6) is not possible here!" self assert: n data equals: #( 2 6 4 ). n sortFor: nil. diff --git a/src/Math-Tests-Number-Extensions/PMNumberExtensionsTest.class.st b/src/Math-Tests-Number-Extensions/PMNumberExtensionsTest.class.st index cd114199f..11730aec2 100644 --- a/src/Math-Tests-Number-Extensions/PMNumberExtensionsTest.class.st +++ b/src/Math-Tests-Number-Extensions/PMNumberExtensionsTest.class.st @@ -6,7 +6,8 @@ Class { { #category : #tests } PMNumberExtensionsTest >> testArTanh [ - self assert: 0 arTanh = 0.0 arTanh. + + self assert: 0 arTanh equals: 0.0 arTanh. self assert: 1 arTanh isFloat. self assert: 1 arTanh equals: 1.0 arTanh ] diff --git a/src/Math-Tests-Numerical/IntegerTest.extension.st b/src/Math-Tests-Numerical/IntegerTest.extension.st index e5f1d2939..5fad2645f 100644 --- a/src/Math-Tests-Numerical/IntegerTest.extension.st +++ b/src/Math-Tests-Numerical/IntegerTest.extension.st @@ -5,7 +5,7 @@ IntegerTest >> testFindNK [ self assert: 6 inverseBinomialCoefficient equals: #(6 1 6 5 4 2). self assert: 10 inverseBinomialCoefficient equals: #(10 1 10 9 5 2 5 3). - self assert: 20 inverseBinomialCoefficient equals: #(20 1 20 19 6 3). + self assert: 20 inverseBinomialCoefficient equals: #(20 1 20 19 6 3). self assert: 21 inverseBinomialCoefficient equals: #(21 1 21 20 7 2 7 5). self assert: 55 inverseBinomialCoefficient equals: #(55 1 55 54 11 2 11 9). self assert: 120 inverseBinomialCoefficient equals: #(120 1 120 119 16 2 16 14 10 3 10 7). @@ -13,5 +13,5 @@ IntegerTest >> testFindNK [ self assert: 8966473191018617158916954970192684 inverseBinomialCoefficient equals: #(8966473191018617158916954970192684 1 8966473191018617158916954970192684 8966473191018617158916954970192683 123 45 123 78). self should: [ 1 inverseBinomialCoefficient ] raise: Error. - self should: [ 0 inverseBinomialCoefficient ] raise: Error. + self should: [ 0 inverseBinomialCoefficient ] raise: Error ] diff --git a/src/Math-Tests-Numerical/PMCovarianceAccumulatorTest.class.st b/src/Math-Tests-Numerical/PMCovarianceAccumulatorTest.class.st index ada7a6d0e..a229f22fa 100644 --- a/src/Math-Tests-Numerical/PMCovarianceAccumulatorTest.class.st +++ b/src/Math-Tests-Numerical/PMCovarianceAccumulatorTest.class.st @@ -12,7 +12,7 @@ PMCovarianceAccumulatorTest >> testCovarianceAccumulation [ | accumulator average covarianceMatrix | accumulator := PMCovarianceAccumulator new: 3. #( #( 1 2 3 ) #( 2 3 4 ) #( 1 3 2 ) #( 4 3 1 ) #( 1 3 1 ) #( 1 4 2 ) - #( 3 1 2 ) #( 3 4 2 ) ) do: [ :x | + #( 3 1 2 ) #( 3 4 2 ) ) do: [ :x | accumulator accumulate: x asPMVector ]. average := accumulator average. self assert: ((average at: 1) closeTo: 2.0). diff --git a/src/Math-Tests-Numerical/PMFloatingPointMachineTestCase.class.st b/src/Math-Tests-Numerical/PMFloatingPointMachineTestCase.class.st index c6f885e87..c4e3d5b19 100644 --- a/src/Math-Tests-Numerical/PMFloatingPointMachineTestCase.class.st +++ b/src/Math-Tests-Numerical/PMFloatingPointMachineTestCase.class.st @@ -77,10 +77,11 @@ PMFloatingPointMachineTestCase >> testMachinePrecisionSmallestNumberNotZero [ { #category : #precision } PMFloatingPointMachineTestCase >> testUniqueInstance [ + | mach1 mach2 mach3 | mach1 := PMFloatingPointMachine new. mach2 := PMFloatingPointMachine new. - self assert: mach1 == mach2. + self assert: mach1 identicalTo: mach2. PMFloatingPointMachine reset. mach3 := PMFloatingPointMachine new. self shouldnt: [ mach3 == mach2 ] diff --git a/src/Math-Tests-Numerical/PMGeneticOptimizerBugsTest.class.st b/src/Math-Tests-Numerical/PMGeneticOptimizerBugsTest.class.st index d51f8ebac..8c800aff9 100644 --- a/src/Math-Tests-Numerical/PMGeneticOptimizerBugsTest.class.st +++ b/src/Math-Tests-Numerical/PMGeneticOptimizerBugsTest.class.st @@ -11,11 +11,13 @@ Class { { #category : #running } PMGeneticOptimizerBugsTest >> setUp [ -manager:= PMChromosomeManager new. -manager populationSize:3. -function:=[:x| (x*x)sum]. -optimizer:= PMGeneticOptimizer minimizingFunction: function. -optimizer chromosomeManager: manager. + + super setUp. + manager := PMChromosomeManager new. + manager populationSize: 3. + function := [ :x | (x * x) sum ]. + optimizer := PMGeneticOptimizer minimizingFunction: function. + optimizer chromosomeManager: manager ] { #category : #tests } @@ -37,5 +39,5 @@ optimizer addPointAt: #(2 3). optimizer addPointAt: (Array with: Float nan with: 3). "if you inspect r here you will see that a _single nan result can _completely throw off the ga calculations" r:=optimizer randomScale. -self deny: r first isNaN. +self deny: r first isNaN ] diff --git a/src/Math-Tests-Numerical/PMHistogramTestsAndBugs.class.st b/src/Math-Tests-Numerical/PMHistogramTestsAndBugs.class.st index 79ba75a55..018671251 100644 --- a/src/Math-Tests-Numerical/PMHistogramTestsAndBugs.class.st +++ b/src/Math-Tests-Numerical/PMHistogramTestsAndBugs.class.st @@ -14,9 +14,11 @@ PMHistogramTestsAndBugs >> readMe [ { #category : #running } PMHistogramTestsAndBugs >> setUp [ -h:=PMHistogram new. -h freeExtent: true. -1to:3 do: [:i |h accumulate: i]. + + super setUp. + h := PMHistogram new. + h freeExtent: true. + 1 to: 3 do: [ :i | h accumulate: i ] ] { #category : #tests } @@ -43,7 +45,7 @@ PMHistogramTestsAndBugs >> testBinWidth [ PMHistogramTestsAndBugs >> testChi2Against [ self assert: ((h chi2Against: (PMScaledProbabilityDensityFunction histogram: h against: PMNormalDistribution new)) - closeTo: 2.937623). + closeTo: 2.937623). ] { #category : #tests } @@ -85,7 +87,7 @@ PMHistogramTestsAndBugs >> testCountsUpTo [ { #category : #tests } PMHistogramTestsAndBugs >> testErrorOnAverage [ -self assert: (h errorOnAverage isFloat). +self assert: (h errorOnAverage isFloat) ] { #category : #tests } @@ -107,12 +109,12 @@ PMHistogramTestsAndBugs >> testKurtosis [ { #category : #tests } PMHistogramTestsAndBugs >> testLowBinLimitAt [ -self assert: ((h lowBinLimitAt:2) isNumber). +self assert: ((h lowBinLimitAt:2) isNumber) ] { #category : #tests } PMHistogramTestsAndBugs >> testMaximum [ -self assert: ( h maximum >=3). +self assert: ( h maximum >=3) ] { #category : #tests } @@ -124,7 +126,7 @@ PMHistogramTestsAndBugs >> testMaximumCount [ { #category : #tests } PMHistogramTestsAndBugs >> testMinimum [ -self assert: ( h minimum <= 1). +self assert: ( h minimum <= 1) ] { #category : #tests } diff --git a/src/Math-Tests-Numerical/PMLeastSquaresTest.class.st b/src/Math-Tests-Numerical/PMLeastSquaresTest.class.st index 67b76b0d9..4612b5a62 100644 --- a/src/Math-Tests-Numerical/PMLeastSquaresTest.class.st +++ b/src/Math-Tests-Numerical/PMLeastSquaresTest.class.st @@ -21,49 +21,49 @@ PMLeastSquaresTest >> setUp [ PMLeastSquaresTest >> testPseudoinverseOfDiagonalSquareMatrix [ | matrix expectedInverse inverse | - + matrix := PMMatrix rows: #( (2 0 0 0) (0 1 0 0) (0 0 -3 0) (0 0 0 -1) ). - + expectedInverse := PMMatrix rows: { { 1/2 . 0 . 0 . 0 } . { 0 . 1 . 0 . 0 } . { 0 . 0 . -1/3 . 0} . { 0 . 0 . 0 . -1 } }. - + inverse := leastSquares pseudoinverseOfDiagonal: matrix. - self assert: inverse closeTo: expectedInverse. + self assert: inverse closeTo: expectedInverse ] { #category : #tests } PMLeastSquaresTest >> testPseudoinverseOfDiagonalSquareMatrixWithZeros [ | matrix expectedInverse inverse | - + matrix := PMMatrix rows: #( (2 0 0 0) (0 1 0 0) (0 0 0 0) (0 0 0 0) ). - + expectedInverse := PMMatrix rows: #( (0.5 0 0 0) ( 0 1 0 0) ( 0 0 0 0) ( 0 0 0 0) ). - + inverse := leastSquares pseudoinverseOfDiagonal: matrix. - self assert: inverse closeTo: expectedInverse. + self assert: inverse closeTo: expectedInverse ] { #category : #tests } PMLeastSquaresTest >> testPseudoinverseOfDiagonalTallMatrix [ | matrix expectedInverse inverse | - + matrix := PMMatrix rows: #( (2 0 0 0) (0 1 0 0) @@ -71,28 +71,28 @@ PMLeastSquaresTest >> testPseudoinverseOfDiagonalTallMatrix [ (0 0 0 -1) (0 0 0 0) (0 0 0 0) ). - + expectedInverse := PMMatrix rows: { { 1/2 . 0 . 0 . 0 . 0 . 0 } . { 0 . 1 . 0 . 0 . 0 . 0 } . { 0 . 0 . -1/3 . 0 . 0 . 0 } . { 0 . 0 . 0 . -1 . 0 . 0 }}. - + inverse := leastSquares pseudoinverseOfDiagonal: matrix. - self assert: inverse closeTo: expectedInverse. + self assert: inverse closeTo: expectedInverse ] { #category : #tests } PMLeastSquaresTest >> testPseudoinverseOfDiagonalWideMatrix [ | matrix expectedInverse inverse | - + matrix := PMMatrix rows: #( (2 0 0 0 0 0) (0 1 0 0 0 0) (0 0 -3 0 0 0) (0 0 0 -1 0 0)). - + expectedInverse := PMMatrix rows: { { 1/2 . 0 . 0 . 0 } . { 0 . 1 . 0 . 0 } . @@ -100,27 +100,27 @@ PMLeastSquaresTest >> testPseudoinverseOfDiagonalWideMatrix [ {0 . 0 . 0 . -1 } . {0 . 0 . 0 . 0 } . {0 . 0 . 0 . 0 }}. - + inverse := leastSquares pseudoinverseOfDiagonal: matrix. - self assert: inverse closeTo: expectedInverse. + self assert: inverse closeTo: expectedInverse ] { #category : #tests } PMLeastSquaresTest >> testSolveSmallOneSolution [ "Small example of least squares system (AX = B) with one solution taken from here: https://textbooks.math.gatech.edu/ila/least-squares.html" | matrixA vectorB expectedSolution solution | - + matrixA := PMMatrix rows: #( (0 1.1) (1 0 ) (0 -0.2) ). - + vectorB := #(1.1 -1.1 -0.2) asPMVector. expectedSolution := #(-1.1 1) asPMVector. - + solution := leastSquares solveMatrixA: matrixA matrixB: vectorB. - - self assert: solution closeTo: expectedSolution. + + self assert: solution closeTo: expectedSolution ] diff --git a/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st b/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st index d81c8e915..c2ae5b139 100644 --- a/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st +++ b/src/Math-Tests-Numerical/PMNumericalMethodsTestCase.class.st @@ -4,12 +4,14 @@ Class { #category : #'Math-Tests-Numerical' } -{ #category : #privateMethods } +{ #category : #running } 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. + PMFloatingPointMachine reset ] { #category : #'linear algebra' } @@ -49,10 +51,9 @@ PMNumericalMethodsTestCase >> testDeterminant [ { #category : #'linear algebra' } PMNumericalMethodsTestCase >> testDimension [ - | a | - a := PMMatrix rows: #( ( 1 0 1) (-1 -2 3)). - self assert: a dimension equals: 2@3. - + | a | + a := PMMatrix rows: #( ( 1 0 1) (-1 -2 3)). + self assert: a dimension equals: 2@3 ] { #category : #'linear algebra' } @@ -326,7 +327,7 @@ PMNumericalMethodsTestCase >> testLanczosFormulaObject [ second := PMLanczosFormula new. self shouldnt: [ first == second ]. third := PMLanczosFormula new. - self assert: second == third + self assert: second identicalTo: third ] { #category : #estimation } @@ -382,27 +383,27 @@ PMNumericalMethodsTestCase >> testLeastSquarePolynomial [ { #category : #'iterative algorithms' } PMNumericalMethodsTestCase >> testLeastSquaresSingularMatrixError [ | histogram leastSquares | - + histogram := PMHistogram new freeExtent: true; yourself. - + 1 to: 3 do: [:i| histogram accumulate: i ]. - + leastSquares := PMLeastSquareFit histogram: histogram distributionClass: PMTriangularDistribution. - + self should: [ leastSquares evaluate ] raise: PMSingularMatrixError. - self should: [ leastSquares errorMatrix ] raise: PMSingularMatrixError . + self should: [ leastSquares errorMatrix ] raise: PMSingularMatrixError ] { #category : #'iterative algorithms' } PMNumericalMethodsTestCase >> testLineSearch1 [ "Test line searh for an initial step of Newton solver for equation - + atan x = 0 with x0 = 2. - + D[atan x] = 1 / (1+x^2). " | xOld p functionBlock g0 g1 dg0 xAnswer | @@ -419,46 +420,45 @@ PMNumericalMethodsTestCase >> testLineSearch1 [ valueAtOne: g1) evaluate. self assert: (xAnswer <= 0.5) & (xAnswer > 1e-3). self assert: (functionBlock value: xAnswer) < g0. - self assert: (functionBlock value: xAnswer) < g1. - + self assert: (functionBlock value: xAnswer) < g1 ] { #category : #'iterative algorithms' } PMNumericalMethodsTestCase >> testLineSearch2 [ "Test line searh for an initial step of Newton solver for equation - + F(x) := sqrt(x) - x = 0 with x = 2. - + F'(x) = 0.5 / sqrt(x) - 1. - + This case does not require line search, should return 1. " + | xOld p functionBlock g0 g1 dg0 xAnswer | xOld := 2.0. - p := ((xOld sqrt - xOld) / (0.5 / xOld sqrt - 1)) negated. - functionBlock := [ :x | 0.5 * ((x * p + xOld) sqrt - (x * p + xOld)) squared ]. + p := (xOld sqrt - xOld / (0.5 / xOld sqrt - 1)) negated. + functionBlock := [ :x | 0.5 * ((x * p + xOld) sqrt - (x * p + xOld)) squared ]. g0 := functionBlock value: 0. g1 := functionBlock value: 1. dg0 := 2.0 * g0 negated. xAnswer := (PMLineSearch - function: functionBlock - valueAtZero: g0 - derivativeAtZero: dg0 - valueAtOne: g1) evaluate. + function: functionBlock + valueAtZero: g0 + derivativeAtZero: dg0 + valueAtOne: g1) evaluate. self assert: xAnswer equals: 1.0. self assert: (functionBlock value: xAnswer) < g0. - self assert: (functionBlock value: xAnswer) = g1. - + self assert: (functionBlock value: xAnswer) equals: g1 ] { #category : #'iterative algorithms' } PMNumericalMethodsTestCase >> testLineSearch3 [ "Test line searh for the final step of Newton solver for equation - + F(x) := x + 1 for x = -1 (+ small epsilon) - + F'(x) = 1. - + This case does not require line search, should return 1. " | xOld eps p functionBlock g0 g1 dg0 lineSearch xAnswer | @@ -472,8 +472,7 @@ PMNumericalMethodsTestCase >> testLineSearch3 [ lineSearch := PMLineSearch function: functionBlock valueAtZero: g0 derivativeAtZero: dg0 valueAtOne: g1. lineSearch desiredPrecision: eps. xAnswer := lineSearch evaluate. - self assert: xAnswer equals: 1.0. - + self assert: xAnswer equals: 1.0 ] { #category : #'linear algebra' } @@ -743,11 +742,11 @@ PMNumericalMethodsTestCase >> testNewtonZeroFinder [ { #category : #'iterative algorithms' } PMNumericalMethodsTestCase >> testNewtonZeroFinder2 [ "Test Newton's method for - + atan x = 0, x = 5. - + atan' x = 1 / (1+x^2) - + This case requires line search to decrease the initial step." | zeroFinder result | zeroFinder := PMNewtonZeroFinder @@ -762,20 +761,21 @@ PMNumericalMethodsTestCase >> testNewtonZeroFinder2 [ { #category : #'iterative algorithms' } PMNumericalMethodsTestCase >> testNewtonZeroFinder3 [ "Test Newton's method for linear function - + F(x) = x + 1 = 0, x = 5. - + F'(x) = 1 - + This should converge in two iterations: the first iteration produces large step, but the second iteration step is zero => convergence" + | zeroFinder result | - zeroFinder := PMNewtonZeroFinder function: [ :x | x + 1 ] derivative: [ :x | 1 ]. + zeroFinder := PMNewtonZeroFinder function: [ :x | x + 1 ] derivative: [ :x | 1 ]. zeroFinder initialValue: 5.0. result := zeroFinder evaluate. self assert: zeroFinder hasConverged. self assert: (result + 1) abs <= zeroFinder precision. - self assert: zeroFinder iterations = 2. + self assert: zeroFinder iterations equals: 2 ] { #category : #statistics } @@ -794,7 +794,7 @@ PMNumericalMethodsTestCase >> testOptimize [ "General optimizer to test genetic algorithm" | fBlock finder result | - fBlock := [ :x | + fBlock := [ :x | | r | r := x * x. r = 0 diff --git a/src/Math-Tests-ODE/PMAB2SolverTest.class.st b/src/Math-Tests-ODE/PMAB2SolverTest.class.st index 972ba657b..caa6773dc 100644 --- a/src/Math-Tests-ODE/PMAB2SolverTest.class.st +++ b/src/Math-Tests-ODE/PMAB2SolverTest.class.st @@ -12,8 +12,7 @@ PMAB2SolverTest >> testSimpleSystem2 [ stepper := PMAB2Stepper onSystem: system. solver := PMAB2Solver new stepper: stepper; system: system; dt: dt. self assert: ((solver solve: system startState: 5 startTime: 0 endTime: 3) closeTo: 1.1237). - self assert: ((solver solve: system startState: 0 startTime: 1 endTime: 4) closeTo: -0.2451). - + self assert: ((solver solve: system startState: 0 startTime: 1 endTime: 4) closeTo: -0.2451) ] { #category : #'tests-solving' } @@ -24,8 +23,7 @@ PMAB2SolverTest >> testSimpleSystem3 [ stepper := PMAB2Stepper onSystem: system. solver := PMAB2Solver new stepper: stepper; system: system; dt: dt. self assert: ((solver solve: system startState: 1 startTime: 0 endTime: 1 ) closeTo: 2.1875). - self assert: ((solver solve: system startState: 1.25 startTime: 0.5 endTime: 2 ) closeTo: 17.4512). - + self assert: ((solver solve: system startState: 1.25 startTime: 0.5 endTime: 2 ) closeTo: 17.4512) ] { #category : #'tests-solving' } @@ -36,23 +34,21 @@ PMAB2SolverTest >> testSimpleSystem4 [ ((t ** 3) * (1- (6 * (t ln))) ** 2)]. stepper := PMAB2Stepper onSystem: system. solver := PMAB2Solver new stepper: stepper; system: system; dt: dt. - self assert: ((solver solve: system startState: 2 startTime: 1 endTime: 4.5 ) closeTo: 22.3431). - - + self assert: ((solver solve: system startState: 2 startTime: 1 endTime: 4.5 ) closeTo: 22.3431) ] { #category : #'tests-solving' } PMAB2SolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. - system := PMExplicitSystem block: [:x :t | + system := PMExplicitSystem block: [:x :t | | v | - v := PMVector new: 2. - v at: 1 put: t sin. + v := PMVector new: 2. + v at: 1 put: t sin. v at: 2 put: t cos. v]. stepper := PMAB2Stepper onSystem: system. solver := PMAB2Solver new stepper: stepper; system: system; dt: dt. self assert: (((solver solve: system startState: #(-1 0) startTime: 0 endTime: Float pi ) at: 1) closeTo: 1). - self assert: (((solver solve: system startState: #(-1 0) startTime: 0 endTime: Float pi / 2 ) at: 2 ) closeTo: 1). + self assert: (((solver solve: system startState: #(-1 0) startTime: 0 endTime: Float pi / 2 ) at: 2 ) closeTo: 1) ] diff --git a/src/Math-Tests-ODE/PMAB3SolverTest.class.st b/src/Math-Tests-ODE/PMAB3SolverTest.class.st index 02c96ab29..88b003722 100644 --- a/src/Math-Tests-ODE/PMAB3SolverTest.class.st +++ b/src/Math-Tests-ODE/PMAB3SolverTest.class.st @@ -83,7 +83,7 @@ PMAB3SolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.001. system := PMExplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMAB4SolverTest.class.st b/src/Math-Tests-ODE/PMAB4SolverTest.class.st index b360760f9..2d0df43f8 100644 --- a/src/Math-Tests-ODE/PMAB4SolverTest.class.st +++ b/src/Math-Tests-ODE/PMAB4SolverTest.class.st @@ -83,7 +83,7 @@ PMAB4SolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.001. system := PMExplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMAM3SolverTest.class.st b/src/Math-Tests-ODE/PMAM3SolverTest.class.st index 3b8f7d4d8..20c012e46 100644 --- a/src/Math-Tests-ODE/PMAM3SolverTest.class.st +++ b/src/Math-Tests-ODE/PMAM3SolverTest.class.st @@ -11,9 +11,9 @@ PMAM3SolverTest >> testSimpleSystem2 [ system := PMImplicitSystem block: [:x :t | 3 * (t negated exp) - (0.4 * x)]. stepper := PMAM3Stepper onSystem: system. solver := (PMAM3Solver new) stepper: stepper; system: system; dt: dt. - + self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3) closeTo: 2.8978). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: 0.8577). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: 0.8577) ] { #category : #'tests-solving' } @@ -61,7 +61,7 @@ PMAM3SolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMImplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMAM3StepperTest.class.st b/src/Math-Tests-ODE/PMAM3StepperTest.class.st index e01071de6..994f7589f 100644 --- a/src/Math-Tests-ODE/PMAM3StepperTest.class.st +++ b/src/Math-Tests-ODE/PMAM3StepperTest.class.st @@ -38,7 +38,7 @@ PMAM3StepperTest >> testSimpleSystem2 [ self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.7) closeTo: 4.5912). self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.5) closeTo: 4.9614). self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3.0) closeTo: 2.8977). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 4.0) closeTo: 0.5375). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 4.0) closeTo: 0.5375) ] { #category : #'tests-stepping' } @@ -86,7 +86,7 @@ PMAM3StepperTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMImplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMAM4SolverTest.class.st b/src/Math-Tests-ODE/PMAM4SolverTest.class.st index 4c09c9bfc..d2e926a44 100644 --- a/src/Math-Tests-ODE/PMAM4SolverTest.class.st +++ b/src/Math-Tests-ODE/PMAM4SolverTest.class.st @@ -11,9 +11,9 @@ PMAM4SolverTest >> testSimpleSystem2 [ system := PMImplicitSystem block: [:x :t | 3 * (t negated exp) - (0.4 * x)]. stepper := PMAM4Stepper onSystem: system. solver := (PMAM4Solver new) stepper: stepper; system: system; dt: dt. - + self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3) closeTo: 2.6231). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: 0.8577). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: 0.8577) ] { #category : #'tests-solving' } @@ -61,7 +61,7 @@ PMAM4SolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMImplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMAM4StepperTest.class.st b/src/Math-Tests-ODE/PMAM4StepperTest.class.st index 8e53d4073..a0e812310 100644 --- a/src/Math-Tests-ODE/PMAM4StepperTest.class.st +++ b/src/Math-Tests-ODE/PMAM4StepperTest.class.st @@ -38,7 +38,7 @@ PMAM4StepperTest >> testSimpleSystem2 [ self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.7) closeTo: 4.5912). self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.5) closeTo: 4.9614). self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3.0) closeTo: 2.6231). - self should: ((solver solve: system startState: 0.1 startTime: 2 endTime: 4.1) closeTo: 0.2908). + self should: ((solver solve: system startState: 0.1 startTime: 2 endTime: 4.1) closeTo: 0.2908) ] { #category : #'tests-stepping' } diff --git a/src/Math-Tests-ODE/PMBDF2SolverTest.class.st b/src/Math-Tests-ODE/PMBDF2SolverTest.class.st index 5ff9aa6bc..742fe64da 100644 --- a/src/Math-Tests-ODE/PMBDF2SolverTest.class.st +++ b/src/Math-Tests-ODE/PMBDF2SolverTest.class.st @@ -11,9 +11,9 @@ PMBDF2SolverTest >> testSimpleSystem2 [ system := PMImplicitSystem block: [:x :t | 3 * (t negated exp) - (0.4 * x)]. stepper := PMBDF2Stepper onSystem: system. solver := (PMBDF2Solver new) stepper: stepper; system: system; dt: dt. - + self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3) closeTo: 0.54985). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: -0.5306). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: -0.5306) ] { #category : #'tests-solving' } diff --git a/src/Math-Tests-ODE/PMBDF2StepperTest.class.st b/src/Math-Tests-ODE/PMBDF2StepperTest.class.st index 3025f1063..cb9b70b6e 100644 --- a/src/Math-Tests-ODE/PMBDF2StepperTest.class.st +++ b/src/Math-Tests-ODE/PMBDF2StepperTest.class.st @@ -38,8 +38,7 @@ PMBDF2StepperTest >> testSimpleSystem2 [ self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.7) closeTo: 1.10147). self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.5) closeTo: 2.10409). self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3.0) closeTo: 0.54985). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 4.0) closeTo: -0.71539). - + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 4.0) closeTo: -0.71539) ] { #category : #'tests-stepping' } @@ -87,7 +86,7 @@ PMBDF2StepperTest >> testVectorSystem [ | solver stepper system dt | dt := 0.0001. system := PMImplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMBDF3SolverTest.class.st b/src/Math-Tests-ODE/PMBDF3SolverTest.class.st index f8a0ac823..cec568d43 100644 --- a/src/Math-Tests-ODE/PMBDF3SolverTest.class.st +++ b/src/Math-Tests-ODE/PMBDF3SolverTest.class.st @@ -11,9 +11,9 @@ PMBDF3SolverTest >> testSimpleSystem2 [ system := PMImplicitSystem block: [:x :t | 3 * (t negated exp) - (0.4 * x)]. stepper := PMBDF3Stepper onSystem: system. solver := (PMBDF3Solver new) stepper: stepper; system: system; dt: dt. - + self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3) closeTo: 0.54985). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: -0.5306). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: -0.5306) ] { #category : #'tests-solving' } @@ -61,7 +61,7 @@ PMBDF3SolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMImplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMBDF3StepperTest.class.st b/src/Math-Tests-ODE/PMBDF3StepperTest.class.st index 2e6d075db..77f5013fe 100644 --- a/src/Math-Tests-ODE/PMBDF3StepperTest.class.st +++ b/src/Math-Tests-ODE/PMBDF3StepperTest.class.st @@ -38,7 +38,7 @@ PMBDF3StepperTest >> testSimpleSystem2 [ self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.7) closeTo: 1.10147). self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.5) closeTo: 2.10409). self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3.0) closeTo: 0.54985). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 4.0) closeTo: -0.71539). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 4.0) closeTo: -0.71539) ] { #category : #'tests-stepping' } diff --git a/src/Math-Tests-ODE/PMBDF4SolverTest.class.st b/src/Math-Tests-ODE/PMBDF4SolverTest.class.st index 19a735170..15557e0c2 100644 --- a/src/Math-Tests-ODE/PMBDF4SolverTest.class.st +++ b/src/Math-Tests-ODE/PMBDF4SolverTest.class.st @@ -11,10 +11,10 @@ PMBDF4SolverTest >> testSimpleSystem2 [ system := PMImplicitSystem block: [:x :t | 3 * (t negated exp) - (0.4 * x)]. stepper := PMBDF4Stepper onSystem: system. solver := (PMBDF4Solver new) stepper: stepper; system: system; dt: dt. - + self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3) closeTo: 2.5637). self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: 0.4395). - self should: ((solver solve: system startState: 0 startTime: 0 endTime: 3) closeTo: 1.0793). + self should: ((solver solve: system startState: 0 startTime: 0 endTime: 3) closeTo: 1.0793) ] { #category : #'tests-solving' } @@ -69,7 +69,7 @@ PMBDF4SolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMImplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMBDF4StepperTest.class.st b/src/Math-Tests-ODE/PMBDF4StepperTest.class.st index 2ba63d843..f44bdb8ba 100644 --- a/src/Math-Tests-ODE/PMBDF4StepperTest.class.st +++ b/src/Math-Tests-ODE/PMBDF4StepperTest.class.st @@ -39,7 +39,7 @@ PMBDF4StepperTest >> testSimpleSystem2 [ self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.7) closeTo: 3.6812). self should: ((solver solve: system startState: 5 startTime: 0 endTime: 2.0) closeTo: 3.5316). self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3.0) closeTo: 2.5637). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 4.0) closeTo: 0.35925). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 4.0) closeTo: 0.35925) ] { #category : #'tests-stepping' } diff --git a/src/Math-Tests-ODE/PMBeckwardEulerSolverTest.class.st b/src/Math-Tests-ODE/PMBeckwardEulerSolverTest.class.st index f399e0874..7a2fc18aa 100644 --- a/src/Math-Tests-ODE/PMBeckwardEulerSolverTest.class.st +++ b/src/Math-Tests-ODE/PMBeckwardEulerSolverTest.class.st @@ -31,7 +31,7 @@ PMBeckwardEulerSolverTest >> testSimpleSystem2 [ stepper := PMImplicitStepper onSystem: system. solver := (PMImplicitSolver new) stepper: stepper; system: system; dt: dt. self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3) closeTo: 0.16567). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: -0.5306). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: -0.5306) ] { #category : #'tests-solving' } @@ -39,7 +39,7 @@ PMBeckwardEulerSolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMImplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMBeckwardEulerStepperTest.class.st b/src/Math-Tests-ODE/PMBeckwardEulerStepperTest.class.st index f15d31a35..3be63c388 100644 --- a/src/Math-Tests-ODE/PMBeckwardEulerStepperTest.class.st +++ b/src/Math-Tests-ODE/PMBeckwardEulerStepperTest.class.st @@ -45,7 +45,7 @@ PMBeckwardEulerStepperTest >> testSimpleSystem2 [ stepper := PMImplicitStepper onSystem: system. solver := (PMImplicitSolver new) stepper: stepper; system: system; dt: dt. self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.5) closeTo: 2.10408). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: -0.5306). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: -0.5306) ] { #category : #'tests-stepping' } diff --git a/src/Math-Tests-ODE/PMEulerStepperTest.class.st b/src/Math-Tests-ODE/PMEulerStepperTest.class.st index cda9ab668..3aea4e285 100644 --- a/src/Math-Tests-ODE/PMEulerStepperTest.class.st +++ b/src/Math-Tests-ODE/PMEulerStepperTest.class.st @@ -40,9 +40,10 @@ PMEulerStepperTest >> testDoStepTimeStepSize [ { #category : #'tests-stepping' } PMEulerStepperTest >> testOrderOfBaseExplicitStepperIsOne [ + | order | order := PMExplicitStepper new order. - self assert: order notNil. + self assert: order isNotNil. self assert: order equals: 1 ] @@ -51,7 +52,7 @@ PMEulerStepperTest >> testVectorSystem [ | solver stepper system dt | dt := 0.001. system := PMExplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMHeunStepperTest.class.st b/src/Math-Tests-ODE/PMHeunStepperTest.class.st index 74777b16b..65eef6e56 100644 --- a/src/Math-Tests-ODE/PMHeunStepperTest.class.st +++ b/src/Math-Tests-ODE/PMHeunStepperTest.class.st @@ -86,7 +86,7 @@ PMHeunStepperTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMExplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMImplicitMidpointSolverTest.class.st b/src/Math-Tests-ODE/PMImplicitMidpointSolverTest.class.st index 5322796d8..39aedb5a5 100644 --- a/src/Math-Tests-ODE/PMImplicitMidpointSolverTest.class.st +++ b/src/Math-Tests-ODE/PMImplicitMidpointSolverTest.class.st @@ -12,5 +12,5 @@ PMImplicitMidpointSolverTest >> testSimpleSystem2 [ stepper := PMImplicitMidpointStepper onSystem: system. solver := (PMImplicitMidpointSolver new) stepper: stepper; system: system; dt: dt. self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3) closeTo: 4.9733). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: 0.8242). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: 0.8242) ] diff --git a/src/Math-Tests-ODE/PMImplicitMidpointStepperTest.class.st b/src/Math-Tests-ODE/PMImplicitMidpointStepperTest.class.st index 6c51b73a0..a42fc6000 100644 --- a/src/Math-Tests-ODE/PMImplicitMidpointStepperTest.class.st +++ b/src/Math-Tests-ODE/PMImplicitMidpointStepperTest.class.st @@ -36,7 +36,7 @@ PMImplicitMidpointStepperTest >> testSimpleSystem2 [ stepper := PMImplicitMidpointStepper onSystem: system. solver := (PMImplicitMidpointSolver new) stepper: stepper; system: system; dt: dt. self should: ((solver solve: system startState: 5 startTime: 0 endTime: 1.5) closeTo: 5.9805). - self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: 0.8242). + self should: ((solver solve: system startState: 0 startTime: 1 endTime: 2.5) closeTo: 0.8242) ] { #category : #'tests-stepping' } @@ -63,7 +63,7 @@ PMImplicitMidpointStepperTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMImplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMMidpointSolverTest.class.st b/src/Math-Tests-ODE/PMMidpointSolverTest.class.st index cf22ef05f..4b3090fc5 100644 --- a/src/Math-Tests-ODE/PMMidpointSolverTest.class.st +++ b/src/Math-Tests-ODE/PMMidpointSolverTest.class.st @@ -135,7 +135,7 @@ PMMidpointSolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMExplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMMidpointStepperTest.class.st b/src/Math-Tests-ODE/PMMidpointStepperTest.class.st index 271a113e9..a3d1866ce 100644 --- a/src/Math-Tests-ODE/PMMidpointStepperTest.class.st +++ b/src/Math-Tests-ODE/PMMidpointStepperTest.class.st @@ -113,7 +113,7 @@ PMMidpointStepperTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMExplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMODESystemTest.class.st b/src/Math-Tests-ODE/PMODESystemTest.class.st index 3075495b8..06b7617cf 100644 --- a/src/Math-Tests-ODE/PMODESystemTest.class.st +++ b/src/Math-Tests-ODE/PMODESystemTest.class.st @@ -10,9 +10,11 @@ Class { #category : #'Math-Tests-ODE' } -{ #category : #initialization } +{ #category : #running } PMODESystemTest >> setUp [ "create a dummy system" + + super setUp. sys := PMODESystem new ] diff --git a/src/Math-Tests-ODE/PMRungeKuttaSolverTest.class.st b/src/Math-Tests-ODE/PMRungeKuttaSolverTest.class.st index cc310e1ba..79535a63c 100644 --- a/src/Math-Tests-ODE/PMRungeKuttaSolverTest.class.st +++ b/src/Math-Tests-ODE/PMRungeKuttaSolverTest.class.st @@ -135,7 +135,7 @@ PMRungeKuttaSolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMExplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMRungeKuttaStepperTest.class.st b/src/Math-Tests-ODE/PMRungeKuttaStepperTest.class.st index d1f7a8ec8..be6f10357 100644 --- a/src/Math-Tests-ODE/PMRungeKuttaStepperTest.class.st +++ b/src/Math-Tests-ODE/PMRungeKuttaStepperTest.class.st @@ -86,7 +86,7 @@ PMRungeKuttaStepperTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMExplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMTrapezoidSolverTest.class.st b/src/Math-Tests-ODE/PMTrapezoidSolverTest.class.st index de9e1ed56..0d517af53 100644 --- a/src/Math-Tests-ODE/PMTrapezoidSolverTest.class.st +++ b/src/Math-Tests-ODE/PMTrapezoidSolverTest.class.st @@ -11,7 +11,7 @@ PMTrapezoidSolverTest >> testSimpleSystem2 [ system := PMImplicitSystem block: [:x :t | 3 * (t negated exp) - (0.4 * x)]. stepper := PMTrapezoidStepper onSystem: system. solver := (PMImplicitSolver new) stepper: stepper; system: system; dt: dt. - + self should: ((solver solve: system startState: 5 startTime: 0 endTime: 3) closeTo: 3.1299). self should: ((solver solve: system startState: 0.1 startTime: 1 endTime: 2.5) closeTo: 0.9103) ] @@ -61,7 +61,7 @@ PMTrapezoidSolverTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMImplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-ODE/PMTrapezoidStepperTest.class.st b/src/Math-Tests-ODE/PMTrapezoidStepperTest.class.st index 1f524945a..fc4ac22cc 100644 --- a/src/Math-Tests-ODE/PMTrapezoidStepperTest.class.st +++ b/src/Math-Tests-ODE/PMTrapezoidStepperTest.class.st @@ -60,7 +60,7 @@ PMTrapezoidStepperTest >> testVectorSystem [ | solver stepper system dt | dt := 0.01. system := PMImplicitSystem - block: [ :x :t | + block: [ :x :t | | c | c := PMVector new: 2. c at: 1 put: t sin. diff --git a/src/Math-Tests-Permutation/PMPermutationTest.class.st b/src/Math-Tests-Permutation/PMPermutationTest.class.st index 94cd36b00..60f48f9ea 100644 --- a/src/Math-Tests-Permutation/PMPermutationTest.class.st +++ b/src/Math-Tests-Permutation/PMPermutationTest.class.st @@ -6,63 +6,58 @@ Class { { #category : #'class tests' } PMPermutationTest >> testAllOfSize [ + | p "i w" | "special" - self assert: (PMPermutation allOfSize: 0) equals: #(). - self - assert: (PMPermutation allOfSize: 1) - equals: (Array with: (PMPermutation identity: 1)). + self assert: (PMPermutation allOfSize: 0) equals: #( ). + self assert: (PMPermutation allOfSize: 1) equals: (Array with: (PMPermutation identity: 1)). "odd" p := PMPermutation allOfSize: 3. self assert: p size equals: 3 factorial. self assert: p asSet size equals: 3 factorial. - p - do: [ :per | - self assert: per size equals: 3. - self assert: per class == PMPermutation ]. + p do: [ :per | + self assert: per size equals: 3. + self assert: per class identicalTo: PMPermutation ]. "even" p := PMPermutation allOfSize: 4. self assert: p size equals: 4 factorial. self assert: p asSet size equals: 4 factorial. - p - do: [ :per | - "the following speed-test is indeed randomized and will occasionally fail!therefore it is put into comments, but it is important nevertheless, as, if this last #assert: is not true mostly, one can simplify #allOfSize: this way: + p do: [ :per | "the following speed-test is indeed randomized and will occasionally fail!therefore it is put into comments, but it is important nevertheless, as, if this last #assert: is not true mostly, one can simplify #allOfSize: this way: Permutation class>>allOfSize:anInteger |result| (result := WriteStream on:(Array new: anInteger factorial)). (Permutation identity: anInteger) permutationsDo: [:p|result nextPut: p copy]. - ^result contents" - "Smalltalk garbageCollect. Smalltalk garbageCollect. + ^result contents""Smalltalk garbageCollect. Smalltalk garbageCollect. i := [Permutation allOfSize: 9] timeToRun. w:=WriteStream on: ( Array new: 9 factorial ). Smalltalk garbageCollect. Smalltalk garbageCollect. p := [(Permutation identity: 9) permutationsDo: [:each | w nextPut: each copy]] timeToRun. w:=nil. self assert: i < p." - self assert: per size equals: 4. - self assert: per class == PMPermutation ] + self assert: per size equals: 4. + self assert: per class identicalTo: PMPermutation ] ] { #category : #tests } PMPermutationTest >> testAsCycles [ - self assert: PMPermutation new asCycles isEmpty. - self assert: (PMPermutation identity: 1) asCycles equals: #((1)). - self assert: (PMPermutation identity: 3) asCycles equals: #((1)(2)(3)). - self assert: (PMPermutation ordering: #(3 1 4 2)) asCycles equals: #((1 3 4 2)). - self assert: (PMPermutation ordering: #(2 4 3 6 7 8 5 1)) asCycles equals: #((1 2 4 6 8)(3)(5 7)). - self assert: (PMPermutation ordering: #(5 4 2 3 1)) asCycles equals: #((1 5)(2 4 3)). - self assert: (PMPermutation ordering: #(1 2 5 3 4 6)) asCycles equals: #((1)(2)(3 5 4)(6)). + self assertEmpty: PMPermutation new asCycles. + self assert: (PMPermutation identity: 1) asCycles equals: #( #( 1 ) ). + self assert: (PMPermutation identity: 3) asCycles equals: #( #( 1 ) #( 2 ) #( 3 ) ). + self assert: (PMPermutation ordering: #( 3 1 4 2 )) asCycles equals: #( #( 1 3 4 2 ) ). + self assert: (PMPermutation ordering: #( 2 4 3 6 7 8 5 1 )) asCycles equals: #( #( 1 2 4 6 8 ) #( 3 ) #( 5 7 ) ). + self assert: (PMPermutation ordering: #( 5 4 2 3 1 )) asCycles equals: #( #( 1 5 ) #( 2 4 3 ) ). + self assert: (PMPermutation ordering: #( 1 2 5 3 4 6 )) asCycles equals: #( #( 1 ) #( 2 ) #( 3 5 4 ) #( 6 ) ) ] { #category : #tests } PMPermutationTest >> testAsMatrix [ |p| p:=(PMPermutation newFrom: #(4 2 5 3 1)). -self assert: p asMatrix * (PMPermutation identity: 5)asPMVector +self assert: p asMatrix * (PMPermutation identity: 5)asPMVector equals: p asPMVector. -self assert: p inverse asMatrix * p asPMVector - equals: (PMPermutation identity: 5) asPMVector . +self assert: p inverse asMatrix * p asPMVector + equals: (PMPermutation identity: 5) asPMVector ] { #category : #tests } @@ -74,8 +69,7 @@ self assert: (PMPermutation identity: 4) discriminant equals:0. self assert: (PMPermutation ordering: #(2 1 4 3)) discriminant equals:2. self assert: (PMPermutation ordering: #(5 3 2 4 1)) discriminant equals:2. self assert: (PMPermutation ordering: #(3 5 2 1 6 4)) discriminant equals:5. -self assert: (PMPermutation ordering: #(4 3 1 2 6 7 5)) discriminant equals:5. - +self assert: (PMPermutation ordering: #(4 3 1 2 6 7 5)) discriminant equals:5 ] { #category : #tests } @@ -91,7 +85,7 @@ self deny: (PMPermutation ordering: #(4 3 1 2 6 7 5)) even. a:=PMPermutation allOfSize: 4. self assert: (a select:[:b|b odd])size equals:12. a:=PMPermutation allOfSize: 3. -self assert: (a select:[:b|b even])size equals:3. +self assert: (a select:[:b|b even])size equals:3. ] { #category : #tests } @@ -101,22 +95,22 @@ PMPermutationTest >> testExtendTo [ self assert: ((PMPermutation identity: 3)extendTo: 3) equals: (PMPermutation identity: 3). self assert: ((PMPermutation ordering: #(3 1 4 2))extendTo: 4) equals: #(3 1 4 2). self assert: ((PMPermutation ordering: #(3 1 4 2))extendTo: 5) equals: #(3 1 4 2 5). - self assert: ((PMPermutation ordering: #(3 1 4 2))extendTo: 7) equals: #(3 1 4 2 5 6 7). - + self assert: ((PMPermutation ordering: #(3 1 4 2))extendTo: 7) equals: #(3 1 4 2 5 6 7) ] { #category : #'class tests' } PMPermutationTest >> testFromCycles [ - self assert: (PMPermutation fromCycles: #()) isEmpty. - self assert: (PMPermutation fromCycles: #(#())) isEmpty. - self assert: (PMPermutation fromCycles: #(#(1))) equals: #(1). - self assert: (PMPermutation size: 3 fromCycles: #()) equals: #(1 2 3). - self assert: (PMPermutation size: 3 fromCycles: #(#())) equals: #(1 2 3). - self assert: (PMPermutation fromCycles: #(#(1 3 4 2))) equals: #(3 1 4 2). - self assert: (PMPermutation fromCycles: #(#(1 2 4 6 8) #(5 7))) equals: #(2 4 3 6 7 8 5 1). - self assert: (PMPermutation fromCycles: #(#(1 5) #(2 4 3))) equals: #(5 4 2 3 1). - self assert: (PMPermutation fromCycles: #(#(1) #(3 5 4) #(6) #(2))) equals: #(1 2 5 3 4 6). - self assert: (PMPermutation size: 6 fromCycles: #(#(3 5 4))) equals: #(1 2 5 3 4 6) + + self assertEmpty: (PMPermutation fromCycles: #( )). + self assertEmpty: (PMPermutation fromCycles: #( #( ) )). + self assert: (PMPermutation fromCycles: #( #( 1 ) )) equals: #( 1 ). + self assert: (PMPermutation size: 3 fromCycles: #( )) equals: #( 1 2 3 ). + self assert: (PMPermutation size: 3 fromCycles: #( #( ) )) equals: #( 1 2 3 ). + self assert: (PMPermutation fromCycles: #( #( 1 3 4 2 ) )) equals: #( 3 1 4 2 ). + self assert: (PMPermutation fromCycles: #( #( 1 2 4 6 8 ) #( 5 7 ) )) equals: #( 2 4 3 6 7 8 5 1 ). + self assert: (PMPermutation fromCycles: #( #( 1 5 ) #( 2 4 3 ) )) equals: #( 5 4 2 3 1 ). + self assert: (PMPermutation fromCycles: #( #( 1 ) #( 3 5 4 ) #( 6 ) #( 2 ) )) equals: #( 1 2 5 3 4 6 ). + self assert: (PMPermutation size: 6 fromCycles: #( #( 3 5 4 ) )) equals: #( 1 2 5 3 4 6 ) ] { #category : #'class tests' } @@ -143,7 +137,7 @@ g:=PMPermutation generator: (Array with: (PMPermutation fromCycles: #((1 2 3)))). c:=c select:[:p|p even]. self assert: g asSet equals: c asSet. -self assert: g size equals: c size. +self assert: g size equals: c size ] { #category : #'class tests' } @@ -156,24 +150,23 @@ self assert: p equals: #(1). p:=PMPermutation identity: 4. c:=PMPermutation ordering: #(1 3 2 4). self assert: (p permute: c) equals: c. -self assert: (c permute: p) equals: c. +self assert: (c permute: p) equals: c ] { #category : #tests } PMPermutationTest >> testInverse [ |p| p:=PMPermutation ordering: #(2 4 3 1 5). -self assert: (p inverse permute: p ) - equals: (1 to:5 ). -self assert: (p permute: p inverse) +self assert: (p inverse permute: p ) equals: (1 to:5 ). +self assert: (p permute: p inverse) + equals: (1 to:5 ) ] { #category : #tests } PMPermutationTest >> testIsCollection [ |p| -5 timesRepeat: [p:=PMPermutation randomPermutation: 11.self deny: p isCollection ]. - +5 timesRepeat: [p:=PMPermutation randomPermutation: 11.self deny: p isCollection ] ] { #category : #'class tests' } @@ -191,8 +184,7 @@ self assert: p class equals: PMPermutation. self assert: p first equals: #cc. self assert: p third equals: #b. p reduce. -self assert: p equals: #(2 3 1). - +self assert: p equals: #(2 3 1) ] { #category : #tests } @@ -200,38 +192,37 @@ PMPermutationTest >> testPermute [ |p i| p:=PMPermutation ordering: #(2 4 3 1). i:=PMPermutation identity: 4. -self assert: (p permute: #(10 20 30 '40' 5.6)asOrderedCollection ) +self assert: (p permute: #(10 20 30 '40' 5.6)asOrderedCollection ) equals: #(20 '40' 30 10 5.6)asOrderedCollection . -self assert: (p permute: 'abcD') +self assert: (p permute: 'abcD') equals: 'bDca' . -self assert: (p permute: i) +self assert: (p permute: i) equals: p . -self assert: (i permute: p) +self assert: (i permute: p) equals: p . -self assert: (PMPermutation new permute: p) +self assert: (PMPermutation new permute: p) equals: p . -self assert: (p permute: PMPermutation new) +self assert: (p permute: PMPermutation new) equals: p . -self assert: (p permute: (PMPermutation fromCycles: #((1 3)))) +self assert: (p permute: (PMPermutation fromCycles: #((1 3)))) equals: ((PMPermutation fromCycles: #((4 3))) permute: p) . i:=PMPermutation ordering: #(4 1 2 3). -self assert: (p permute: (i permute: 'aBcD')) +self assert: (p permute: (i permute: 'aBcD')) equals: ((p permute: i) permute: 'aBcD') . self should: [ i permute:'aBc' ] raise: SizeMismatch . "and i would say:" -self should: [ (PMPermutation identity: 4) permute:'aBc' ] raise: SizeMismatch . - +self should: [ (PMPermutation identity: 4) permute:'aBc' ] raise: SizeMismatch ] { #category : #'class tests' } PMPermutationTest >> testRandomGenerator [ -|g| -g:=PMPermutation randomGenerator . -g:=g next:4. -self assert: g size equals: 4. -self deny: g first = g second. -self assert: g third isFloat. + | g | + g := PMPermutation randomGenerator. + g := g next: 4. + self assert: g size equals: 4. + self deny: g first equals: g second. + self assert: g third isFloat ] { #category : #'class tests' } @@ -261,17 +252,17 @@ self assert: p equals: #(2 3 1). p:=PMPermutation newFrom: #(). self assert: p reduce equals: #(). p:=PMPermutation newFrom: #(0.8). -self assert: p reduce equals: #(1). +self assert: p reduce equals: #(1) ] { #category : #tests } PMPermutationTest >> testReversed [ |p| p:=PMPermutation ordering: #(2 4 3 1 5). -self assert: (p reversed ) +self assert: (p reversed ) equals: #(5 1 3 4 2). -self assert: (p class) - equals: PMPermutation . +self assert: (p class) + equals: PMPermutation ] { #category : #tests } @@ -291,7 +282,7 @@ self assert: (PMPermutation size: 5 shift: -2) equals: #(4 5 1 2 3). self assert: (PMPermutation size: 1 shift: 1) equals: #(1). self assert: (PMPermutation size: 0 shift: 2) equals: #(). p:=PMPermutation randomPermutation: 6. -self assert: (p shift: -8) equals: (p shift:4). +self assert: (p shift: -8) equals: (p shift:4) ] { #category : #'class tests' } @@ -304,7 +295,7 @@ self assert: p equals: #(1). p:=PMPermutation size: 4 shift: -1. self assert: p equals: (PMPermutation ordering:#(4 1 2 3)). p:=PMPermutation size: 4 shift: 2. -self assert: p equals: (PMPermutation ordering:#(3 4 1 2)). +self assert: p equals: (PMPermutation ordering:#(3 4 1 2)) ] { #category : #'class tests' } @@ -314,5 +305,5 @@ self assert: (PMPermutation stirling1: 5 over: 3) equals: 35. self assert: (PMPermutation stirling1: 5 over: 2) equals: 50. self assert: (PMPermutation stirling1: 5 over: 1) equals: 24. self assert: (PMPermutation stirling1: 5 over: 0) equals: 0. -self assert: (PMPermutation stirling1: 0 over: 5) equals: 0. +self assert: (PMPermutation stirling1: 0 over: 5) equals: 0 ] diff --git a/src/Math-Tests-Polynomials/PMPolynomialTest.class.st b/src/Math-Tests-Polynomials/PMPolynomialTest.class.st index b9599314e..e3b491811 100644 --- a/src/Math-Tests-Polynomials/PMPolynomialTest.class.st +++ b/src/Math-Tests-Polynomials/PMPolynomialTest.class.st @@ -1,7 +1,7 @@ Class { #name : #PMPolynomialTest, #superclass : #TestCase, - #category : 'Math-Tests-Polynomials' + #category : #'Math-Tests-Polynomials' } { #category : #comparing } @@ -56,11 +56,11 @@ PMPolynomialTest >> testPolynomialDivision [ { #category : #'function evaluation' } PMPolynomialTest >> testPolynomialDivisionBug [ "identify an error when trying to create a zero dividend" - | pol1 pol2 polynomial | - pol1 := PMPolynomial coefficients: #(2 -3 1). - pol2 := PMPolynomial coefficients: #(-6 23 -20 3 -1 1). - self shouldnt: [polynomial := pol1 / pol2] raise: Error. - + + | pol1 pol2 | + pol1 := PMPolynomial coefficients: #( 2 -3 1 ). + pol2 := PMPolynomial coefficients: #( -6 23 -20 3 -1 1 ). + self shouldnt: [ pol1 / pol2 ] raise: Error ] { #category : #arithmetic } diff --git a/src/Math-Tests-PrincipalComponentAnalysis/PMPCAJacobiTransformationTest.class.st b/src/Math-Tests-PrincipalComponentAnalysis/PMPCAJacobiTransformationTest.class.st index 33ed4e4df..eb898f8ef 100644 --- a/src/Math-Tests-PrincipalComponentAnalysis/PMPCAJacobiTransformationTest.class.st +++ b/src/Math-Tests-PrincipalComponentAnalysis/PMPCAJacobiTransformationTest.class.st @@ -9,6 +9,7 @@ Class { { #category : #running } PMPCAJacobiTransformationTest >> setUp [ - pca := PMPrincipalComponentAnalyserJacobiTransformation new - componentsNumber: 2 + + super setUp. + pca := PMPrincipalComponentAnalyserJacobiTransformation new componentsNumber: 2 ] diff --git a/src/Math-Tests-PrincipalComponentAnalysis/PMPCASingularValueDecompositionTest.class.st b/src/Math-Tests-PrincipalComponentAnalysis/PMPCASingularValueDecompositionTest.class.st index 23ae687eb..9678755b3 100644 --- a/src/Math-Tests-PrincipalComponentAnalysis/PMPCASingularValueDecompositionTest.class.st +++ b/src/Math-Tests-PrincipalComponentAnalysis/PMPCASingularValueDecompositionTest.class.st @@ -9,6 +9,8 @@ Class { { #category : #running } PMPCASingularValueDecompositionTest >> setUp [ + + super setUp. pca := PMPrincipalComponentAnalyserSVD new componentsNumber: 2 ] @@ -20,6 +22,6 @@ PMPCASingularValueDecompositionTest >> testPCAwithPCAandJacobiTransformationRetu pca1 fit: m. pca2 := PMPrincipalComponentAnalyserJacobiTransformation new componentsNumber: 2. pca2 fit: m. - + self assert: pca1 transformMatrix abs closeTo: pca2 transformMatrix abs ] diff --git a/src/Math-Tests-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserTest.class.st b/src/Math-Tests-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserTest.class.st index 48cea390c..9bf31137a 100644 --- a/src/Math-Tests-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserTest.class.st +++ b/src/Math-Tests-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserTest.class.st @@ -14,7 +14,7 @@ Class { } { #category : #testing } -PMPrincipalComponentAnalyserTest class >> isAbstract [ +PMPrincipalComponentAnalyserTest class >> isAbstract [ ^ self name = #PMPrincipalComponentAnalyserTest ] @@ -23,9 +23,9 @@ PMPrincipalComponentAnalyserTest >> testTransformMatrix [ | m expected | m := PMMatrix rows: #(#(-1 -1) #(-2 -1) #(-3 -2) #(1 1) #(2 1) #(3 2)). - + pca fit: m. - + expected := (PMMatrix rows: #(#(-0.83849224 -0.54491354) #(0.54491354 -0.83849224))) abs. self assert: pca transformMatrix abs closeTo: expected @@ -35,30 +35,30 @@ PMPrincipalComponentAnalyserTest >> testTransformMatrix [ PMPrincipalComponentAnalyserTest >> testTransformWithMeanCentredMeasurements [ | meanCentredData transformedData expected | meanCentredData := PMMatrix rows: #( - #(0.69 0.49) - #(-1.31 -1.21) - #(0.39 0.99) - #(0.09 0.29) - #(1.29 1.09) - #(0.49 0.79) - #(0.19 -0.31) - #(-0.81 -0.81) - #(-0.31 -0.31) + #(0.69 0.49) + #(-1.31 -1.21) + #(0.39 0.99) + #(0.09 0.29) + #(1.29 1.09) + #(0.49 0.79) + #(0.19 -0.31) + #(-0.81 -0.81) + #(-0.31 -0.31) #(-0.71 -1.01) ). transformedData := pca fitAndTransform: meanCentredData. - + expected := PMMatrix rows: #( - #(-0.827970186 -0.175115307) - #(1.77758033 0.142857227) - #(-0.992197494 0.384374989) - #(-0.274210416 0.130417207) - #(-1.67580142 -0.209498461) - #(-0.912949103 0.175282444) - #(0.0991094375 -0.349824698) - #(1.14457216 0.0464172582) - #(0.438046137 0.0177646297) + #(-0.827970186 -0.175115307) + #(1.77758033 0.142857227) + #(-0.992197494 0.384374989) + #(-0.274210416 0.130417207) + #(-1.67580142 -0.209498461) + #(-0.912949103 0.175282444) + #(0.0991094375 -0.349824698) + #(1.14457216 0.0464172582) + #(0.438046137 0.0177646297) #(1.22382056 -0.162675287)). - self assert: (transformedData abs) closeTo: expected abs. + self assert: (transformedData abs) closeTo: expected abs ] diff --git a/src/Math-Tests-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithmTest.class.st b/src/Math-Tests-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithmTest.class.st index 270a42603..c651d9042 100644 --- a/src/Math-Tests-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithmTest.class.st +++ b/src/Math-Tests-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithmTest.class.st @@ -13,14 +13,14 @@ Class { #category : #'Math-Tests-PrincipalComponentAnalysis' } -{ #category : #initialization } +{ #category : #running } PMSciKitLearnSVDFlipAlgorithmTest >> setUp [ -" We compute a matrix of signs for U with which + " We compute a matrix of signs for U with which we perform a 'dot product' with the original matrix V (by 'dot product' we mean send the dot: message) Example here is taken from Scikit Learn - + U = [[-0.21956688 0.53396977] [-0.35264795 -0.45713538] [-0.57221483 0.07683439] @@ -29,22 +29,18 @@ PMSciKitLearnSVDFlipAlgorithmTest >> setUp [ [ 0.57221483 -0.07683439]] V = [[ 0.83849224 0.54491354] - [ 0.54491354 -0.83849224]] + [ 0.54491354 -0.83849224]] " + super setUp. + - u := PMMatrix rows: #( - #(-0.21956688 0.53396977) - #(-0.35264795 -0.45713538) - #(-0.57221483 0.07683439) - #( 0.21956688 -0.53396977) - #( 0.35264795 0.45713538) - #( 0.57221483 -0.07683439)). - v := PMMatrix rows: #( - #(0.83849224 0.54491354) - #(0.54491354 -0.83849224)). - - flipAlgorithm := PMSciKitLearnSVDFlipAlgorithm flipU: u andV: v. + u := PMMatrix rows: + #( #( -0.21956688 0.53396977 ) #( -0.35264795 -0.45713538 ) #( -0.57221483 0.07683439 ) #( 0.21956688 -0.53396977 ) #( 0.35264795 0.45713538 ) + #( 0.57221483 -0.07683439 ) ). + v := PMMatrix rows: #( #( 0.83849224 0.54491354 ) #( 0.54491354 -0.83849224 ) ). + + flipAlgorithm := PMSciKitLearnSVDFlipAlgorithm flipU: u andV: v ] { #category : #'scikit-learn-example' } @@ -54,7 +50,7 @@ PMSciKitLearnSVDFlipAlgorithmTest >> testComputeSignsFromU [ " | expected signs | - + signs := flipAlgorithm computeSignsFromU. expected := #(-1 1) asPMVector. @@ -65,16 +61,15 @@ PMSciKitLearnSVDFlipAlgorithmTest >> testComputeSignsFromU [ PMSciKitLearnSVDFlipAlgorithmTest >> testSignMatrixForU [ | expected | expected := PMMatrix rows: #(#(-1 1) #(-1 1) #(-1 1) #(-1 1) #(-1 1) #(-1 1)). - - self assert: (flipAlgorithm signMatrixForU) equals: expected + self assert: (flipAlgorithm signMatrixForU) equals: expected ] { #category : #'scikit-learn-example' } PMSciKitLearnSVDFlipAlgorithmTest >> testSignMatrixForV [ | expected | expected := PMMatrix rows: #(#(-1 -1) #(1 1)). - + self assert: (flipAlgorithm signMatrixForV) equals: expected ] @@ -90,8 +85,6 @@ PMSciKitLearnSVDFlipAlgorithmTest >> testUFlipped [ #(-0.57221483 -0.07683439)). self assert: (flipAlgorithm uFlipped) equals: expected - - ] { #category : #'scikit-learn-example' } diff --git a/src/Math-Tests-PrincipalComponentAnalysis/PMScikitLearnSVDFlipAlgorithmSandiaTest.class.st b/src/Math-Tests-PrincipalComponentAnalysis/PMScikitLearnSVDFlipAlgorithmSandiaTest.class.st index 4baa8ec90..3ceabdb49 100644 --- a/src/Math-Tests-PrincipalComponentAnalysis/PMScikitLearnSVDFlipAlgorithmSandiaTest.class.st +++ b/src/Math-Tests-PrincipalComponentAnalysis/PMScikitLearnSVDFlipAlgorithmSandiaTest.class.st @@ -20,29 +20,25 @@ Class { #category : #'Math-Tests-PrincipalComponentAnalysis' } -{ #category : #initialization } +{ #category : #running } PMScikitLearnSVDFlipAlgorithmSandiaTest >> setUp [ - u:= PMMatrix rows: #( - #(-3.37888092e-01 7.97390517e-01 -5.00000000e-01 -7.29361893e-17) - #(-6.39157626e-01 -5.84360787e-01 -5.00000000e-01 -6.37482349e-17) - #(4.88522859e-01 -1.06514865e-01 -5.00000000e-01 -7.07106781e-01) - #(4.88522859e-01 -1.06514865e-01 -5.00000000e-01 7.07106781e-01) - ). - - v := PMMatrix rows: #( - #(0.1480984 0.96040168 0.13728871 0.19195647) - #(0.43936626 -0.13130934 -0.54106008 0.70496038) - #(-0.42589859 0.24444267 -0.8129595 -0.31297767) - #(-0.77693921 -0.02518437 0.16583923 0.60681839) - ). - - flipAlgorithm := PMSciKitLearnSVDFlipAlgorithm flipU: u andV: v. + + super setUp. + u := PMMatrix rows: + #( #( -3.37888092e-01 7.97390517e-01 -5.00000000e-01 -7.29361893e-17 ) #( -6.39157626e-01 -5.84360787e-01 -5.00000000e-01 -6.37482349e-17 ) + #( 4.88522859e-01 -1.06514865e-01 -5.00000000e-01 -7.07106781e-01 ) #( 4.88522859e-01 -1.06514865e-01 -5.00000000e-01 7.07106781e-01 ) ). + + v := PMMatrix rows: + #( #( 0.1480984 0.96040168 0.13728871 0.19195647 ) #( 0.43936626 -0.13130934 -0.54106008 0.70496038 ) #( -0.42589859 0.24444267 -0.8129595 -0.31297767 ) + #( -0.77693921 -0.02518437 0.16583923 0.60681839 ) ). + + flipAlgorithm := PMSciKitLearnSVDFlipAlgorithm flipU: u andV: v ] { #category : #'sandia-example' } PMScikitLearnSVDFlipAlgorithmSandiaTest >> testSignMatrixForU [ | expected | - + expected := PMMatrix rows: #(#(-1 1 -1 -1) #(-1 1 -1 -1) #(-1 1 -1 -1) #(-1 1 -1 -1)). @@ -56,7 +52,7 @@ PMScikitLearnSVDFlipAlgorithmSandiaTest >> testSignMatrixForV [ expected := PMMatrix rows: #(#(-1 -1 -1 -1) #(1 1 1 1) #(-1 -1 -1 -1) #(-1 -1 -1 -1)). - + self assert: flipAlgorithm signMatrixForV equals: expected ] @@ -64,11 +60,11 @@ PMScikitLearnSVDFlipAlgorithmSandiaTest >> testSignMatrixForV [ PMScikitLearnSVDFlipAlgorithmSandiaTest >> testUFlipped [ | expected | expected := PMMatrix rows: #( - #(3.37888092e-01 7.97390517e-01 5.00000000e-01 7.29361893e-17) - #(6.39157626e-01 -5.84360787e-01 5.00000000e-01 6.37482349e-17) - #(-4.88522859e-01 -1.06514865e-01 5.00000000e-01 7.07106781e-01) + #(3.37888092e-01 7.97390517e-01 5.00000000e-01 7.29361893e-17) + #(6.39157626e-01 -5.84360787e-01 5.00000000e-01 6.37482349e-17) + #(-4.88522859e-01 -1.06514865e-01 5.00000000e-01 7.07106781e-01) #(-4.88522859e-01 -1.06514865e-01 5.00000000e-01 -7.07106781e-01)). - + self assert: flipAlgorithm uFlipped equals: expected ] @@ -76,10 +72,10 @@ PMScikitLearnSVDFlipAlgorithmSandiaTest >> testUFlipped [ PMScikitLearnSVDFlipAlgorithmSandiaTest >> testVFlipped [ | expected | expected := PMMatrix rows: #( - #(-0.1480984 -0.96040168 -0.13728871 -0.19195647) - #(0.43936626 -0.13130934 -0.54106008 0.70496038) - #(0.42589859 -0.24444267 0.8129595 0.31297767) + #(-0.1480984 -0.96040168 -0.13728871 -0.19195647) + #(0.43936626 -0.13130934 -0.54106008 0.70496038) + #(0.42589859 -0.24444267 0.8129595 0.31297767) #(0.77693921 0.02518437 -0.16583923 -0.60681839)). - + self assert: flipAlgorithm vFlipped equals: expected ] diff --git a/src/Math-Tests-PrincipalComponentAnalysis/PMStandardizationScalerTest.class.st b/src/Math-Tests-PrincipalComponentAnalysis/PMStandardizationScalerTest.class.st index 06e58fad8..2a559520e 100644 --- a/src/Math-Tests-PrincipalComponentAnalysis/PMStandardizationScalerTest.class.st +++ b/src/Math-Tests-PrincipalComponentAnalysis/PMStandardizationScalerTest.class.st @@ -5,7 +5,7 @@ Class { } { #category : #tests } -PMStandardizationScalerTest >> testMean [ +PMStandardizationScalerTest >> testMean [ | aMatrix t | aMatrix := PMMatrix rows: #((0.0 0.0) #(0.0 0.0) #(1.0 1.0) #(1.0 1.0)). t := PMStandardizationScaler new. @@ -61,7 +61,7 @@ PMStandardizationScalerTest >> testVariance [ PMStandardizationScalerTest >> testZeroScale [ "Tests if PMStandardizationScaler handles case when scale is 0, by changing it to 1. Happens when one feature is constant eg: 8.0 in this test." - + | aMatrix t | aMatrix := PMMatrix rows: #((8.0 0.0) #(8.0 0.0) #(8.0 1.0) #(8.0 1.0)). t := PMStandardizationScaler new. diff --git a/src/Math-Tests-Quantile/PMQuantileTest.class.st b/src/Math-Tests-Quantile/PMQuantileTest.class.st index 3e36e2416..caacd54cd 100644 --- a/src/Math-Tests-Quantile/PMQuantileTest.class.st +++ b/src/Math-Tests-Quantile/PMQuantileTest.class.st @@ -26,11 +26,18 @@ PMQuantileTest >> resultCollect: aSortedColl withProbs: aMethod [ { #category : #running } PMQuantileTest >> setUp [ - a := #(1 3 2 4) asSortedCollection. - c := #(1 3 2 4 5) asSortedCollection. - d := #(1 3 2 4 5 6) asSortedCollection. - b := #(2 4 5 7 8 9 10 12 15 16 18) asSortedCollection. - q := Array with: 0 with: (1 / 4) with: (1 / 2) with: (3 / 4) with: 1 + + super setUp. + a := #( 1 3 2 4 ) asSortedCollection. + c := #( 1 3 2 4 5 ) asSortedCollection. + d := #( 1 3 2 4 5 6 ) asSortedCollection. + b := #( 2 4 5 7 8 9 10 12 15 16 18 ) asSortedCollection. + q := Array + with: 0 + with: 1 / 4 + with: 1 / 2 + with: 3 / 4 + with: 1 ] { #category : #tests } @@ -40,7 +47,6 @@ PMQuantileTest >> testError [ raise: Error whoseDescriptionIncludes: 'SubscriptOutOfBounds' description: 'Wrong error message' - ] { #category : #tests } @@ -60,10 +66,10 @@ PMQuantileTest >> testExtremeCase [ { #category : #tests } PMQuantileTest >> testFloatProbability [ - "tests that input quantile probabilities can be a float" - + "tests that input quantile probabilities can be a float" + self assert: (c quantile: 0.25) equals: 2. - + self assert: (c quantile: 0.27) equals: 2.08 ] diff --git a/src/Math-Tests-Quaternion/PMQuaternionTest.class.st b/src/Math-Tests-Quaternion/PMQuaternionTest.class.st index fc6e8e65b..324c54d87 100644 --- a/src/Math-Tests-Quaternion/PMQuaternionTest.class.st +++ b/src/Math-Tests-Quaternion/PMQuaternionTest.class.st @@ -15,10 +15,12 @@ Class { { #category : #running } PMQuaternionTest >> setUp [ + + super setUp. q1234 := 1 i: 2 j: 3 k: 4. q1 := 1 asQuaternion. - q12 := (1 + 2 i) asQuaternion . - q123 := (1 + 2 i + 3 j). + q12 := (1 + 2 i) asQuaternion. + q123 := 1 + 2 i + 3 j ] { #category : #running } @@ -64,7 +66,7 @@ PMQuaternionTest >> testCos [ | eps | eps := 1.0e-6. self assert: (q1234 cos - ((q1234 real cos * q1234 unreal cos) - (q1234 real sin * q1234 unreal sin))) abs < eps. - self assert: ((1 + 2 i) cos - (1 + 2 j k) cos) abs < eps. + self assert: ((1 + 2 i) cos - (1 + 2 j k) cos) abs < eps ] { #category : #running } @@ -93,14 +95,15 @@ PMQuaternionTest >> testDivision [ { #category : #running } PMQuaternionTest >> testEquality [ + self assert: q1234 equals: q1234 copy. self assert: 1 + 2 i equals: 1 + 2 j k. self assert: 1 + 2 j k equals: 1 + 2 i. - self deny: 1 + 2 j = (1 + 2 i). - self deny: q1234 = 1. + self deny: 1 + 2 j equals: 1 + 2 i. + self deny: q1234 equals: 1. self assert: 1 k k equals: -1. self assert: 1 equals: -1 k k. - self deny: q1234 = nil + self deny: q1234 isNil ] { #category : #running } @@ -165,9 +168,9 @@ PMQuaternionTest >> testMultiplicationByComplexNumberIsNonCommutative [ | quaternion complexNumber | quaternion := 2 + 3 i + 4 j + 5 k. complexNumber := 1 - 1 i. - + self assert: (quaternion * complexNumber) equals: 5 + 1 i - 1 j + 9 k. - self assert: (complexNumber * quaternion) equals: 5 + 1 i + 9 j + 1 k. + self assert: (complexNumber * quaternion) equals: 5 + 1 i + 9 j + 1 k ] { #category : #'testing - arithmetic' } @@ -185,7 +188,7 @@ PMQuaternionTest >> testMultiplicationByIntegersIsCommutative [ quaternion := 1 + 2 i + 3 j + 4 k. self assert: quaternion * 5 equals: 5 + 10 i + 15 j + 20 k. - self assert: 5 * quaternion equals: 5 + 10 i + 15 j + 20 k. + self assert: 5 * quaternion equals: 5 + 10 i + 15 j + 20 k ] { #category : #'testing - arithmetic' } @@ -203,7 +206,7 @@ PMQuaternionTest >> testMultiplicationByTheBasisElements [ | quaternion | quaternion := 1 + 2 i + 3 j + 4 k. - + self assert: quaternion * 1 i equals: (-2 + 1 i + 4 j - 3 k). self assert: quaternion * 1 j equals: (-3 - 4 i + 1 j + 2 k). self assert: quaternion * 1 k equals: (-4 + 3 i - 2 j + 1 k) @@ -222,15 +225,15 @@ PMQuaternionTest >> testMultiplicationByVectorIsCommutative [ "This uses adaptToQuaternion:andSend:" self assert: (quaternion * vec at: 1) equals: 1 + 2 i + 3 j + 4 k. - self assert: (quaternion * vec at: 2) equals: 2 + 4 i + 6 j + 8 k. + self assert: (quaternion * vec at: 2) equals: 2 + 4 i + 6 j + 8 k ] { #category : #'testing - arithmetic' } PMQuaternionTest >> testMultiplicationByZero [ | quaternion | quaternion := 1 + 2 i + 3 j + 4 k. - - self assert: quaternion * 0 equals: 0 + 0 i + 0 j + 0 k. + + self assert: quaternion * 0 equals: 0 + 0 i + 0 j + 0 k ] { #category : #'testing - arithmetic' } @@ -254,7 +257,7 @@ PMQuaternionTest >> testMultiplicationOfBasisElements [ self assert: 1 k i equals: 1 j. self assert: 1 j i equals: -1 k. self assert: 1 k j equals: -1 i. - self assert: 1 i k equals: -1 j. + self assert: 1 i k equals: -1 j ] { #category : #running } @@ -283,16 +286,16 @@ PMQuaternionTest >> testNaturalLogOfQuaternion [ { #category : #running } PMQuaternionTest >> testNaturalLogOfQuaternionWithNoVectorPart [ | expected naturalLogOfQuaternion quaternionWithNoVector | - + quaternionWithNoVector := 5 + 0 i + 0 j + 0 k. - + naturalLogOfQuaternion := quaternionWithNoVector ln. - + expected := 5 ln + 0 i + 0 j + 0 k. self assert: naturalLogOfQuaternion qr equals: expected qr. self assert: naturalLogOfQuaternion qi equals: 0. self assert: naturalLogOfQuaternion qj equals: 0. - self assert: naturalLogOfQuaternion qk equals: 0. + self assert: naturalLogOfQuaternion qk equals: 0 ] { #category : #tests } @@ -335,7 +338,7 @@ PMQuaternionTest >> testPrintOn [ PMQuaternionTest >> testRaisedTo [ | eps | eps := 1.0e-6. - self assert: ((q1234 raisedTo: 3) - (q1234 ln * 3) exp) abs < eps. + self assert: ((q1234 raisedTo: 3) - (q1234 ln * 3) exp) abs < eps ] { #category : #running } @@ -367,7 +370,7 @@ PMQuaternionTest >> testSin [ | eps | eps := 1.0e-6. self assert: (q1234 sin - ((q1234 real sin * q1234 unreal cos) + (q1234 real cos * q1234 unreal sin))) abs < eps. - self assert: ((1 + 2 i) sin - (1 + 2 j k) sin) abs < eps. + self assert: ((1 + 2 i) sin - (1 + 2 j k) sin) abs < eps ] { #category : #running } @@ -396,6 +399,7 @@ PMQuaternionTest >> testSubtractPolynomial [ { #category : #running } PMQuaternionTest >> testSum [ + self assert: 1 + 2 i + 3 j + 4 k equals: q1234. self assert: 1 + 2 i + (3 + 4 i) j equals: q1234. self assert: q1234 + 5 equals: (6 i: 2 j: 3 k: 4). @@ -404,7 +408,7 @@ PMQuaternionTest >> testSum [ self assert: 9 - q1234 equals: (8 i: -2 j: -3 k: -4). self assert: q1234 + q1234 conjugated equals: q1234 real * 2. self assert: q1234 + q1234 negated equals: 0. - self assert: q1234 isZero not. + self deny: q1234 isZero. self assert: (q1234 negated + q1234) isZero ] @@ -433,5 +437,5 @@ PMQuaternionTest >> testUnreal [ { #category : #running } PMQuaternionTest >> testZero [ self assert: PMQuaternion zero isZero. - self assert: PMQuaternion zero abs isZero. + self assert: PMQuaternion zero abs isZero ] diff --git a/src/Math-Tests-TSNE/PMTSNETest.class.st b/src/Math-Tests-TSNE/PMTSNETest.class.st index 3c912d8fd..52d509d7e 100644 --- a/src/Math-Tests-TSNE/PMTSNETest.class.st +++ b/src/Math-Tests-TSNE/PMTSNETest.class.st @@ -10,20 +10,20 @@ Class { { #category : #tests } PMTSNETest >> testComputePValues [ | t | - + t := (PMTSNE new) x: (PMMatrix rows: #(#(1 2 3) #(4 5 6) #(7 8 9))); perplexity: 30.0. self assert: t computePValues closeTo: (PMMatrix rows: (Array - with: (Array with: 0 with: 2/3 with: 2/3) - with: (Array with: 2/3 with: 0 with: 2/3) + with: (Array with: 0 with: 2/3 with: 2/3) + with: (Array with: 2/3 with: 0 with: 2/3) with: (Array with: 2/3 with: 2/3 with: 0))) ] { #category : #tests } PMTSNETest >> testComputePairwiseAffinities [ | t correctAffinities | - + t := (PMTSNE new) x: (PMMatrix rows: #(#(0 0) #(2 2) #(2 0))); perplexity: 30.0. @@ -33,7 +33,7 @@ PMTSNETest >> testComputePairwiseAffinities [ #(0.5 0.5 0) ). self assert: t computePairwiseAffinities closeTo: correctAffinities. - + "This test case has large pairwise distances, which makes exp(-D*beta) = 0" t x: (PMMatrix rows: #(#(1 2 3.14) #(0 4 -43) #(-5 -9 -150) #(120 5 1))). correctAffinities := PMMatrix rows: #( @@ -42,7 +42,7 @@ PMTSNETest >> testComputePairwiseAffinities [ #(0.333333 0.333333 0 0.333333) #(0.333333 0.333333 0.333333 0) ). - self assert: t computePairwiseAffinities closeTo: correctAffinities. + self assert: t computePairwiseAffinities closeTo: correctAffinities ] { #category : #tests } @@ -59,11 +59,10 @@ PMTSNETest >> testEntropyOfAndPRowWithBeta [ | distanceVector pVector entropy | "Input points are (0, 0), (2, 2) and (2, 0)" distanceVector := #(0 8 4) asPMVector. - pVector := PMVector new: (distanceVector size). + pVector := PMVector new: (distanceVector size). entropy := PMTSNE entropyOf: distanceVector andPRow: pVector withBeta: 2.0. self assert: entropy closeTo: 0.003020119571023052. - self assert: pVector closeTo: (Array with: 0.99966454 with: 0.00000011 with: 0.00033535) asPMVector. - + self assert: pVector closeTo: (Array with: 0.99966454 with: 0.00000011 with: 0.00033535) asPMVector ] { #category : #tests } @@ -82,5 +81,5 @@ PMTSNETest >> testreduceXToInputDimsUsing [ t := (PMTSNE new) x: (PMMatrix rows: #(#(0 0) #(2 2) #(2 0))). t reduceXToInputDimsUsing: PMPrincipalComponentAnalyserJacobiTransformation. - self assert: (t x) closeTo: (PMMatrix rows: #(#(-0.5 -1.5) #(-0.5 1.5) #(1 0))). + self assert: (t x) closeTo: (PMMatrix rows: #(#(-0.5 -1.5) #(-0.5 1.5) #(1 0))) ] diff --git a/src/Math-UtilsDataServer/PMMemoryBasedDataServer.class.st b/src/Math-UtilsDataServer/PMMemoryBasedDataServer.class.st index f4e389625..7e0dee6af 100644 --- a/src/Math-UtilsDataServer/PMMemoryBasedDataServer.class.st +++ b/src/Math-UtilsDataServer/PMMemoryBasedDataServer.class.st @@ -9,7 +9,7 @@ Class { 'data', 'position' ], - #category : 'Math-UtilsDataServer' + #category : #'Math-UtilsDataServer' } { #category : #information } @@ -20,7 +20,7 @@ PMMemoryBasedDataServer >> atEnd [ { #category : #initialization } PMMemoryBasedDataServer >> data: anOrderedCollection [ - + data := anOrderedCollection. self reset ] @@ -49,5 +49,5 @@ PMMemoryBasedDataServer >> open [ { #category : #operation } PMMemoryBasedDataServer >> reset [ "Reset the position of the data stream to the beginning." - position := 1. + position := 1 ]