Skip to content

Commit

Permalink
fix: 1d example
Browse files Browse the repository at this point in the history
  • Loading branch information
piercus committed Sep 16, 2020
1 parent 7d82c3e commit 3c9e927
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 13 deletions.
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,29 @@ npm install kalman-filter
```js
const {KalmanFilter} = require('kalman-filter');

const observations = [0, 0.1, 0.5, 0.2];
const observations = [0, 0.1, 0.5, 0.2, 3, 4, 2, 1, 2, 3, 5, 6];
const kFilter = new KalmanFilter();
const res = kFilter.filterAll(observations)

console.log(res);
// res is a list of 1x1 matrices
// [
// [ [ 0 ] ],
// [ [ 0.06666665555510715 ] ],
// [ [ 0.3374999890620582 ] ],
// [ [ 0.25238094852592136 ] ],
// [ [ 1.9509090885288296 ] ],
// [ [ 3.2173611101031616 ] ],
// [ [ 2.4649867370240965 ] ],
// [ [ 1.5595744679428254 ] ],
// [ [ 1.831772445766021 ] ],
// [ [ 2.5537767922925685 ] ],
// [ [ 4.065625882212133 ] ],
// [ [ 5.26113483436549 ] ]
// ]
```
Result is :

![Kalman Filter 1d example](./demo/example-1D.png)

**TO DO** add a screenshot of the resulting curve

## How to instantiate your kalman filter

Expand Down
Binary file added demo/example-1D.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion lib/kalman-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const distanceMat = require('../lib/linalgebra/distance-mat.js');
*@param {ObservationConfig} options.observation
*/

const setupModelsParameters = function ({observation, dynamic}) {
const setupModelsParameters = function ({observation = {name: 'sensors'}, dynamic = {name: 'constant-position', dimension: 1}}) {
if (typeof (observation.name) === 'string') {
observation = modelCollection.buildObservation(observation);
}
Expand Down
30 changes: 30 additions & 0 deletions lib/state.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
const sub = require('../lib/linalgebra/sub.js');
const transpose = require('../lib/linalgebra/transpose.js');
const matMul = require('../lib/linalgebra/mat-mul.js');
const invert = require('../lib/linalgebra/invert.js');
const arrayToMatrix = require('../lib/utils/array-to-matrix.js');

const checkMatrix = function (matrix, shape) {
if (matrix.reduce((a, b) => a.concat(b)).filter(a => Number.isNaN(a)).length > 0) {
throw (new Error('Matrix should not have a NaN'));
Expand Down Expand Up @@ -61,6 +67,30 @@ class State {
// throw (new TypeError('t must be a number'));
// }
}

mahalanobis({kf, observation}) {
const correctlySizedObservation = arrayToMatrix({observation, dimension: observation.length});
const stateProjection = kf.observation.stateProjection();
const diff = sub(matMul(stateProjection, this.mean), correctlySizedObservation);
const diffTransposed = transpose(diff);

const covarianceInObservationSpace = matMul(
matMul(stateProjection, this.covariance),
transpose(stateProjection)
);
// Console.log('covariance in obs space', covarianceInObservationSpace);
const covarianceInvert = invert(covarianceInObservationSpace);
// Console.log('invert cov', covarianceInvert);
return Math.sqrt(
matMul(
matMul(
diffTransposed,
covarianceInvert
),
diff
)
);
}
}

module.exports = State;
4 changes: 4 additions & 0 deletions lib/utils/array-to-matrix.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

module.exports = function ({observation, dimension}) {
if (!Array.isArray(observation)) {
if (dimension === 1 && typeof (observation) === 'number') {
return [[observation]];
}

throw (new TypeError('The observation should be an array'));
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Kalman filter (and Extended Kalman Filter) Multi-dimensional implementation in Javascript",
"main": "index.js",
"scripts": {
"test": "xo && ava test/unit/kalman-filter/*",
"test": "xo && ava",
"build-demo": "browserify -d -r ./demo/src/main.js:main > demo/dist/demo.js"
},
"repository": {
Expand Down
14 changes: 7 additions & 7 deletions test/api/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ const State = require('../../lib/state.js');
const observations = [[0, 2], [0.1, 4], [0.5, 9], [0.2, 12]];

test('Default filter : Constant-position on 1D Data', t => {
const observations = [0, 0.1, 0.5, 0.2];
const observations = [0, 0.1, 0.5, 0.2, 3, 4, 2, 1, 2, 3, 5, 6];
const kFilter = new KalmanFilter();
const res = kFilter.filterAll(observations)
t.true(Array.isArray(res));
t.is(res.length, observations.length);
const result = kFilter.filterAll(observations);
t.true(Array.isArray(result));
t.is(result.length, observations.length);
});

test('Constant-position on 2D Data', t => {
Expand Down Expand Up @@ -134,7 +134,7 @@ test('Sensor observation', t => {
observation: {
sensorDimension: 2, // Observation.dimension == observation.sensorDimension * observation.nSensors
nSensors: 2,
sensorCovariance: [3, 3, 4, 4],
sensorCovariance: [3, 3, 4, 4],
name: 'sensors'
},
dynamic: {
Expand Down Expand Up @@ -192,7 +192,7 @@ test('Model fits ', t => {
},
dynamic: {
name: 'constant-speed', // Observation.sensorDimension == dynamic.dimension
covariance: [3, 4]// Equivalent to diag([3, 4])
covariance: [3, 3, 4, 4]
}
});
const observations = [[0, 2], [0.1, 4], [0.5, 9], [0.2, 12]];
Expand All @@ -205,7 +205,7 @@ test('Model fits ', t => {
previousCorrected
});

const dist = predicted.mahalanobis(observation);
const dist = predicted.mahalanobis({observation, kf: kFilter});

previousCorrected = kFilter.correct({
predicted,
Expand Down

0 comments on commit 3c9e927

Please sign in to comment.