Skip to content

Commit

Permalink
update cochran test
Browse files Browse the repository at this point in the history
  • Loading branch information
aozisik committed Jan 12, 2023
1 parent e7f3b1a commit 76c19a0
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 43 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "labkar-algorithms",
"version": "4.0.0",
"version": "5.0.0",
"description": "Labkar Algorithms",
"main": "dist/lib.js",
"author": "ODTÜ PAL",
Expand Down
46 changes: 31 additions & 15 deletions src/algorithms/cochran.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,27 @@ import { CochranResult } from '../types';
import { sampleStandardDeviation } from 'simple-statistics';
import cochranCriticalValues from './cochranCriticalValues';

type CochranOptions = {
alpha: number;
originalIndexes?: number[];
outlierIndexes?: number[];
}

export function Cochran(
values: Array<number[]>,
options: { alpha: number } = { alpha: 0.05 }
options: CochranOptions = { alpha: 0.05 }
): CochranResult | null {

// Keep track of original indexes of values at the beginning
// When we return indexes of outliers, this will be useful.
const originalIndexes = options.originalIndexes
? options.originalIndexes
: values.map((_, i) => i);

// This is where we store outlier indexes across all iterations.
// The indexes are relative to the original array.
const outlierIndexes = options.outlierIndexes ? options.outlierIndexes : [];

/* p -> numune sayısı */
const pValue = values.length;

Expand All @@ -33,25 +50,24 @@ export function Cochran(

// These are the values used to calculate max deviation
const cPairIndex = squareDeviations.indexOf(maxDeviation);
const cPair = values[squareDeviations.indexOf(maxDeviation)];

const cValue = maxDeviation / sumOfSquareDeviations;

if (cValue < criticalValue) {
return {
outlier: false,
cValue,
cPair,
cPairIndex: cPairIndex,
maxDeviation,
outlierIndexes,
hasOutliers: outlierIndexes.length > 0,
};
}

return {
outlier: true,
cValue,
cPair,
cPairIndex,
maxDeviation,
};
outlierIndexes.push(originalIndexes[cPairIndex]);
originalIndexes.splice(cPairIndex, 1);

return Cochran(
values.filter((_, i) => i !== cPairIndex),
{
alpha: options.alpha,
originalIndexes,
outlierIndexes
}
)
}
18 changes: 3 additions & 15 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,11 @@ export type AResult = {
};

export type CochranResult = {
outlier: boolean;
hasOutliers: boolean;
/**
* Value used to compare to the elected critical value
* Indexes of outliers across all tests
*/
cValue: number;
/**
* The pair used to calculate the max deviation
*/
cPair: number[];
/**
* Index of the pair used to calculate the max deviation
*/
cPairIndex: number;
/**
* Maximum value among (stdDev(pair) ^ 2)
*/
maxDeviation: number;
outlierIndexes: number[];
};

export type ReferenceResult = {
Expand Down
35 changes: 25 additions & 10 deletions tests/cochran.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,15 @@ describe('Cochran Algorithm', () => {
];

let output = Cochran(samples, { alpha: 0.05 });
expect(output?.maxDeviation).toBeCloseTo(31.205, 3);
expect(output?.cPairIndex).toBe(11);
expect(output?.cPair).toEqual([91, 83.1]);
expect(output?.outlier).toBe(true);
expect(output?.hasOutliers).toBe(true);
expect(output?.outlierIndexes).toEqual([11]);

output = Cochran(samples, { alpha: 0.01 });
expect(output?.outlier).toBe(true);
expect(output?.hasOutliers).toBe(true);
expect(output?.outlierIndexes).toEqual([11]);
});

it.only('Cochran Algorithm Test (Straggler)', () => {
it('Cochran Algorithm Test (Straggler)', () => {
const samples = [
[9.9, 10.2],
[10.4, 9.5],
Expand All @@ -45,10 +44,10 @@ describe('Cochran Algorithm', () => {
];

let output = Cochran(samples);
expect(output?.outlier).toBe(true);
expect(output?.hasOutliers).toBe(true);

output = Cochran(samples, { alpha: 0.01 });
expect(output?.outlier).toBe(false);
expect(output?.hasOutliers).toBe(false);
});

it('Cochran Algorithm Test (Null)', () => {
Expand All @@ -58,7 +57,23 @@ describe('Cochran Algorithm', () => {
expect(output).toBe(null);
});

it.todo('Cochran Algorithm Test (Straggler)');
it('Repeats test until there are no outliers', () => {

//TODO: Any value considered as straggler
const samples = [
[0.135, 0.194], // index=0 = outlier
[0.187, 0.189],
[0.182, 0.186],
[0.188, 0.196],
[0.191, 0.181],
[0.188, 0.018], // index=5 = outlier
[0.187, 0.196],
[0.177, 0.186],
[0.179, 0.187],
[0.188, 0.196],
]

const output = Cochran(samples, { alpha: 0.01 });
expect(output?.outlierIndexes).toContain(0);
expect(output?.outlierIndexes).toContain(5);
})
});

0 comments on commit 76c19a0

Please sign in to comment.