Lokasi ngalangkungan proxy:   [ UP ]  
[Ngawartoskeun bug]   [Panyetelan cookie]                
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 19 additions & 21 deletions src/Math-KolmogorovSmirnov/PMKolmogorovSmirnov1Sample.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -32,43 +32,41 @@ PMKolmogorovSmirnov1Sample class >> data: aCollection [
^self new data: aCollection ;yourself
]

{ #category : #accessing }
PMKolmogorovSmirnov1Sample >> cdf: aBlock [
"the cumulative distribution function to be used. can also be set via #populationDistribution:"
popDistribution:=nil.
compareWith := aBlock
]

{ #category : #accessing }
PMKolmogorovSmirnov1Sample >> data: aCollection [
distribution := PMKolmogorovsDistribution exampleSize: aCollection size.
^data := aCollection asSortedCollection .
distribution := PMKolmogorovsDistribution
exampleSize: aCollection size.
^ data := aCollection asSortedCollection
]

{ #category : #accessing }
PMKolmogorovSmirnov1Sample >> ksStatistic [
"the kolmogorov-smirnov statistic D"
|s d|
self testDataComplete .
s:=data size.
d:=(1 to:s) collect: [:i||f| f:=compareWith value:(data at:i).(f -((i-1)/s))max: ((i/s)-f)].
^d max.
"the kolmogorov-smirnov statistic D"

| s d |
s := data size.
d := (1 to: s)
collect: [ :i |
| f |
f := compareWith value: (data at: i).
f - ((i - 1) / s) max: i / s - f ].
^ d max
]

{ #category : #accessing }
PMKolmogorovSmirnov1Sample >> pValue [
"the probability of getting a ksStatistic <= the actual one"
^distribution distributionValue: self ksStatistic .
"the probability of getting a ksStatistic <= the actual one"

^ distribution distributionValue: self ksStatistic
]

{ #category : #accessing }
PMKolmogorovSmirnov1Sample >> populationDistribution: aDistribution [
"utility, a simple alternative method to set cdf."
popDistribution:=aDistribution.
popDistribution distributionValue: 0.95."just a test whether it understands #distributionValue:, to raise a dnu early enough because of this block:"
compareWith :=[:x|popDistribution distributionValue:x ]
"utility, a simple alternative method to set cdf."

popDistribution := aDistribution.
popDistribution distributionValue: 0.95. "just a test whether it understands #distributionValue:, to raise a dnu early enough because of this block:"
compareWith := [ :x | popDistribution distributionValue: x ]
]

{ #category : #printing }
Expand Down
129 changes: 82 additions & 47 deletions src/Math-KolmogorovSmirnov/PMKolmogorovSmirnov2Sample.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -38,91 +38,126 @@ PMKolmogorovSmirnov2Sample class >> compareData: aCollection withData: anotherCo
]

{ #category : #private }
PMKolmogorovSmirnov2Sample >> cFrom:i and:j [
"needs ksStatistic!"
^ (i/smallSize -(j/bigSize))abs < ksStatistic ifTrue:[1]ifFalse:[0]
PMKolmogorovSmirnov2Sample >> cFrom: i and: j [
"needs ksStatistic!"

^ (i / smallSize - (j / bigSize)) abs < ksStatistic
ifTrue: [ 1 ]
ifFalse: [ 0 ]
]

{ #category : #accessing }
PMKolmogorovSmirnov2Sample >> data: aCollection [
ksStatistic:=nil.
^self makeCDFOf: aCollection intoFirst: true .
ksStatistic := nil.
^ self makeCDFOf: aCollection intoFirst: true
]

{ #category : #initialization }
PMKolmogorovSmirnov2Sample >> initCachedUCalculation [
"recursive calc, slow without memoization"
uCalcBlock:=[:iandj||cij i j|
i:=iandj first.j:=iandj second.
cij:=self cFrom: i and: j.
i*j=0
ifTrue:[ cij]
ifFalse:[cij * ((uCalcBlock value:{i.j-1})+(uCalcBlock value:{i-1.j}))]]memoized.
"recursive calc, slow without memoization"

uCalcBlock := [ :iandj |
| cij i j |
i := iandj first.
j := iandj second.
cij := self cFrom: i and: j.
i * j = 0
ifTrue: [ cij ]
ifFalse: [ cij
*
((uCalcBlock
value:
{i.
(j - 1)})
+
(uCalcBlock
value:
{(i - 1).
j})) ] ] memoized
]

{ #category : #initialization }
PMKolmogorovSmirnov2Sample >> initKSStatistic [
| t |
ksStatistic :=0.
self initCachedUCalculation. "needs to be set lately, iow here"
ksStatistic := 0.
self initCachedUCalculation. "needs to be set lately, iow here"
smallSize := data size.
bigSize := compareWith size.
smallSize > bigSize ifFalse: [ ^ self ].
smallSize > bigSize
ifFalse: [ ^ self ].
t := smallSize.
smallSize := bigSize.
bigSize := t.

bigSize := t
]

{ #category : #accessing }
PMKolmogorovSmirnov2Sample >> ksStatistic [
"the kolmogorov-smirnov statistic D"
|c1 c2 cdfs s|
self testDataComplete .
self initKSStatistic .
c1:=0. c2:=0.
s:=smallSize + bigSize.
cdfs := (SortedCollection new:s) addAll: data; addAll: compareWith; yourself.
cdfs 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 ]
ifFalse:[ c1 := (cdfs at: i+1) value first ] ].
ksStatistic := ksStatistic max: (a value second
ifTrue:[c1:=a value first. c1-c2]
ifFalse:[c2:=a value first. c2-c1])].
^ksStatistic
"the kolmogorov-smirnov statistic D"

| c1 c2 cdfs s |
self testDataComplete.
self initKSStatistic.
c1 := 0.
c2 := 0.
s := smallSize + bigSize.
cdfs := (SortedCollection new: s)
addAll: data;
addAll: compareWith;
yourself.
cdfs
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 ]
ifFalse: [ c1 := (cdfs at: i + 1) value first ] ].
ksStatistic := ksStatistic
max:
(a value second
ifTrue: [ c1 := a value first.
c1 - c2 ]
ifFalse: [ c2 := a value first.
c2 - c1 ]) ].
^ 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->{cdf.aBoolean})"
|cd s result|
cd:=0.
s:=aCollection size.
result:=aCollection asBag sortedElements do:[:a|
cd:=a value/s+cd.
a value: {cd. aBoolean}].
^aBoolean ifTrue: [ data:=result ]
ifFalse:[compareWith :=result]

| cd s result |
cd := 0.
s := aCollection size.
result := aCollection asBag sortedElements
do: [ :a |
cd := a value / s + cd.
a
value:
{cd.
aBoolean} ].
^ aBoolean
ifTrue: [ data := result ]
ifFalse: [ compareWith := result ]
]

{ #category : #accessing }
PMKolmogorovSmirnov2Sample >> otherData: aCollection [
ksStatistic:=nil.
^self makeCDFOf: aCollection intoFirst: false .
ksStatistic := nil.
^ self makeCDFOf: aCollection intoFirst: false
]

{ #category : #accessing }
PMKolmogorovSmirnov2Sample >> pValue [
"uses procedure explained in:
"uses procedure explained in:
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)."
ksStatistic ifNil: [self ksStatistic ].
^ (uCalcBlock value: {smallSize.bigSize})/ ((smallSize + bigSize) take:smallSize)

ksStatistic ifNil: [ self ksStatistic ].
^ (uCalcBlock
value:
{smallSize.
bigSize}) / (smallSize + bigSize take: smallSize)
]

{ #category : #printing }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Class {
'distribution',
'n'
],
#category : 'Math-KolmogorovSmirnov'
#category : #'Math-KolmogorovSmirnov'
}

{ #category : #information }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ PMKolmogorovSmirnov1SampleTest >> numberOfRejectionsFor: aDistribution [
^ n
]

{ #category : #initialization }
{ #category : #running }
PMKolmogorovSmirnov1SampleTest >> setUp [
super setUp .
nd := PMNormalDistribution new.
ks := PMKolmogorovSmirnov1Sample new
]
Expand All @@ -37,10 +38,16 @@ PMKolmogorovSmirnov1SampleTest >> testCorrectPopulationProbabilistic [

{ #category : #tests }
PMKolmogorovSmirnov1SampleTest >> testRejectOfEqualityHypothesesForSampleVersusDistribution [
nd := PMNormalDistribution new. "--> Normal distribution( 0, 1)"
ks := PMKolmogorovSmirnov1Sample compareData: ((1 to: 100) collect: [ :i | nd random ]) withDistribution: nd. "-->
a KolmogorovSmirnov(dataSize: 100 cdf: distributionValue of Normal distribution( 0, 1))"
self assert: (ks rejectEqualityHypothesisWithAlpha: 0.05) equals: false
| 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).
ks := PMKolmogorovSmirnov1Sample
compareData: sample
withDistribution: nd.

self
assert: (ks rejectEqualityHypothesisWithAlpha: 0.05)
equals: false
]

{ #category : #tests }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,26 @@ Class {
#category : #'Math-Tests-KolmogorovSmirnov'
}

{ #category : #initialization }
{ #category : #running }
PMKolmogorovSmirnov2SampleTest >> setUp [
super setUp .
k := PMKolmogorovSmirnov2Sample new
]

{ #category : #tests }
PMKolmogorovSmirnov2SampleTest >> testRejectOfEqualityHypothesesForTwoSamples [
| nd ks |
nd := PMNormalDistribution new.
"The data below are taken from http://www.stats.ox.ac.uk/~massa/Lecture%2013.pdf
According to that paper Dn = 0.6 and Dcrit = 0.645 so the null hypothesis is retained.
"

| ks |
ks := PMKolmogorovSmirnov2Sample
compareData: ((1 to: 100) collect: [ :i | nd random ])
withData: ((1 to: 100) collect: [ :i | nd random ]).
ks ksStatistic.
ks pValue asFloat.
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: false
equals: true
]

{ #category : #tests }
Expand Down