gnss_solutions
Version:
Javascript GNSS solution analysis library
252 lines (222 loc) • 13.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.OnlineStatistics = exports.OnlineHistogram = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
* Copyright (c) 2016 Swift Navigation Inc.
* Contact: engineering@swiftnav.com
*
* This source is subject to the license found in the file 'LICENSE' which must
* be be distributed together with this source. All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
*/
exports.updateDigest = updateDigest;
var _immutable = require("immutable");
var Immutable = _interopRequireWildcard(_immutable);
var _lodash = require("lodash");
var _ = _interopRequireWildcard(_lodash);
var _tdigest = require("tdigest");
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* Streaming, immutable histogram. Intended for use with categorical random
* variables.
*
* Example:
* ```
* let histogram = new acc.OnlineHistogram();
* histogram = histogram.update("foo");
* histogram = histogram.update("bar");
* console.log(histogram.getValue()); => {foo: 1, bar: 1};
* ```
*/
var OnlineHistogram = exports.OnlineHistogram = function () {
/**
* Construct an online histogram
*
* @param {string} name - Human readable name
* @return {OnlineHistogram} - Constructed histogram
*/
function OnlineHistogram(name) {
_classCallCheck(this, OnlineHistogram);
this.name = name;
this.store = Immutable.Map();
}
/**
* Set backing store from another histogram.
*
* @param {OnlineHistogram} obj - Histogram to copy
* @return {OnlineHistogram}
*/
_createClass(OnlineHistogram, [{
key: "setStore",
value: function setStore(obj) {
this.store = obj.store;
return this;
}
/**
* Update histogram, returning new histogram.
*
* @param {string} item - Categorical variable to update with
* @return {OnlineHistogram} - New histogram
*/
}, {
key: "update",
value: function update(item) {
var update = new OnlineHistogram(this.name);
update.store = this.store.update(item, 0, function (value) {
return ++value;
});
return update;
}
/**
* Get the histogram.
*
* @return {Object} - Shallow copy of backing histogram
*/
}, {
key: "getValue",
value: function getValue() {
return this.store.toObject();
}
}]);
return OnlineHistogram;
}();
/**
* Update a digest tracking quantiles, returning "new" t-digest.
*
* HACK (mookerji): Stop-gap HACK until we can do real immutable digest updates.
*
* @param {TDigest} digest - t-digest
* @param {number} value - Value to update with
* @return {TDigest} - "New" digest.
*/
function updateDigest(digest, value) {
var digest_ = digest;
digest_.push(value);
return digest_;
}
/**
* Streaming, immutable statistical aggregator (i.e., quantile, min/max
* calculator). Intended for use with calculating summaries of real random
* variables: (approximate) quantiles, min/max, etc.
*
* Example:
* ```
* let stats = new acc.OnlineStatistics();
* stats = stats.update(1);
* stats = stats.update(2);
* console.log(stats.getPercentiles([0.50])); => {"50" : 1.5}
* ```
*/
var OnlineStatistics = exports.OnlineStatistics = function () {
/**
* Construct an online statistics object
*
* @param {string} name - Human readable name
* @return {OnlineStatistics} - Constructed quantile object
*/
function OnlineStatistics(name) {
_classCallCheck(this, OnlineStatistics);
this.name = name;
this.store = new _tdigest.TDigest();
this.max = NaN;
this.min = NaN;
}
/**
* Set backing store from another quantile object
*
* @param {OnlineStatistics} obj - Quantile object to copy
* @return {OnlineStatistics}
*/
_createClass(OnlineStatistics, [{
key: "setStore",
value: function setStore(obj) {
this.store = obj.store;
this.max = obj.max;
this.min = obj.min;
return this;
}
/**
* Update quantile calculator, returning new object.
*
* @param {number} item - Categorical variable to update
* @return {OnlineStatistics} - New OnlineStatistics
*/
}, {
key: "update",
value: function update(item) {
// Don't update if value is actually NaN.
if (isNaN(item)) {
return this;
}
var update = new OnlineStatistics(this.name);
update.store = updateDigest(this.store, item);
update.max = this.max;
update.min = this.min;
if (isNaN(this.max)) {
update.max = item;
}
if (isNaN(this.min)) {
update.min = item;
}
if (!isNaN(this.max) && item > this.max) {
update.max = item;
} else if (!isNaN(this.min) && item < this.min) {
update.min = item;
}
return update;
}
/**
* Get quantiles of underlying data.
*
* @param {Array<number> | number} percentiles - Percentile or list of
* percentiles, with each element between 0 and 1.
* @return {Object} Object of percentile values keyed by a string percentile
* value.
*/
}, {
key: "getPercentiles",
value: function getPercentiles(p_or_plist) {
var ps = Array.isArray(p_or_plist) ? p_or_plist : [p_or_plist];
var strKeys = _.map(ps, function (v) {
return Math.round(100 * v).toString();
});
var vals = this.store.percentile(ps);
return _.zipObject(strKeys, vals);
}
/**
* Return an approximate CDF of the underlying data
*
* @return {Object} Approximate CDF, with buckets from 0.1 to 0.9, 0.95, 0.99.
*/
}, {
key: "getCDF",
value: function getCDF() {
var ps = _.range(0, 1, 0.1);
ps.push(0.95, 0.99);
return this.getPercentiles(ps);
}
/**
* @return {number} The current minimum.
*/
}, {
key: "getMin",
value: function getMin() {
return this.min;
}
/**
* @return {number} The current maximum.
*/
}, {
key: "getMax",
value: function getMax() {
return this.max;
}
}]);
return OnlineStatistics;
}();