12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460 |
- (function webpackUniversalModuleDefinition(root, factory) {
- if (typeof exports === 'object' && typeof module === 'object')
- module.exports = factory();
- else if (typeof define === 'function' && define.amd)
- define([], factory);
- else if (typeof exports === 'object')
- exports["ecStat"] = factory();
- else
- root["ecStat"] = factory();
- })(this, function () {
- return /******/ (function (modules) { // webpackBootstrap
- /******/ // The module cache
- /******/
- var installedModules = {};
- /******/ // The require function
- /******/
- function __webpack_require__(moduleId) {
- /******/ // Check if module is in cache
- /******/
- if (installedModules[moduleId])
- /******/
- return installedModules[moduleId].exports;
- /******/ // Create a new module (and put it into the cache)
- /******/
- var module = installedModules[moduleId] = {
- /******/
- exports: {},
- /******/
- id: moduleId,
- /******/
- loaded: false
- /******/
- };
- /******/ // Execute the module function
- /******/
- modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
- /******/ // Flag the module as loaded
- /******/
- module.loaded = true;
- /******/ // Return the exports of the module
- /******/
- return module.exports;
- /******/
- }
- /******/ // expose the modules object (__webpack_modules__)
- /******/
- __webpack_require__.m = modules;
- /******/ // expose the module cache
- /******/
- __webpack_require__.c = installedModules;
- /******/ // __webpack_public_path__
- /******/
- __webpack_require__.p = "";
- /******/ // Load entry module and return exports
- /******/
- return __webpack_require__(0);
- /******/
- })
- /************************************************************************/
- /******/
- ([
- /* 0 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- return {
- clustering: __webpack_require__(1),
- regression: __webpack_require__(5),
- statistics: __webpack_require__(6),
- histogram: __webpack_require__(15)
- };
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 1 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var dataProcess = __webpack_require__(2);
- var dataPreprocess = dataProcess.dataPreprocess;
- var array = __webpack_require__(3);
- var arraySize = array.size;
- var sumOfColumn = array.sumOfColumn;
- var arraySum = array.sum;
- var zeros = array.zeros;
- var isArray = array.isArray;
- var mathSqrt = Math.sqrt;
- var mathPow = Math.pow;
- /**
- * KMeans of clustering algorithm
- * @param {Array.<Array.<number>>} data two-dimension array
- * @param {number} k the number of clusters in a dataset
- * @return {Object}
- */
- function kMeans(data, k) {
- var size = arraySize(data);
- // create array to assign data points to centroids, also holds SE of each point
- var clusterAssigned = zeros(size[0], 2);
- var centroids = createRandCent(data, k);
- var clusterChanged = true;
- var minDist;
- var minIndex;
- var distIJ;
- var ptsInClust;
- while (clusterChanged) {
- clusterChanged = false;
- for (var i = 0; i < size[0]; i++) {
- minDist = Infinity;
- minIndex = -1;
- for (var j = 0; j < k; j++) {
- distIJ = distEuclid(data[i], centroids[j]);
- if (distIJ < minDist) {
- minDist = distIJ;
- minIndex = j;
- }
- }
- if (clusterAssigned[i][0] !== minIndex) {
- clusterChanged = true;
- }
- clusterAssigned[i][0] = minIndex;
- clusterAssigned[i][1] = mathPow(minDist, 2);
- }
- //recalculate centroids
- for (var i = 0; i < k; i++) {
- ptsInClust = [];
- for (var j = 0; j < clusterAssigned.length; j++) {
- if (clusterAssigned[j][0] === i) {
- ptsInClust.push(data[j]);
- }
- }
- centroids[i] = meanInColumns(ptsInClust);
- }
- }
- var clusterWithKmeans = {
- centroids: centroids,
- clusterAssigned: clusterAssigned
- };
- return clusterWithKmeans;
- }
- /**
- * Calculate the average of each column in a two-dimensional array
- * and returns the values as an array.
- * @param {Array.<Array>} dataList two-dimensional array
- * @return {Array}
- */
- function meanInColumns(dataList) {
- var size = arraySize(dataList);
- var meanArray = [];
- var sum;
- var mean;
- for (var j = 0; j < size[1]; j++) {
- sum = 0;
- for (var i = 0; i < size[0]; i++) {
- sum += dataList[i][j];
- }
- mean = sum / size[0];
- meanArray.push(mean);
- }
- return meanArray;
- }
- /**
- * The combine of hierarchical clustering and k-means.
- * @param {Array} data two-dimension array.
- * @param {[type]} k the number of clusters in a dataset. It has to be greater than 1.
- * @param {boolean} stepByStep
- * @return {}
- */
- function hierarchicalKMeans(data, k, stepByStep) {
- if (k < 2) {
- return;
- }
- var dataSet = dataPreprocess(data);
- var size = arraySize(dataSet);
- var clusterAssment = zeros(size[0], 2);
- // initial center point
- var centroid0 = meanInColumns(dataSet);
- var centList = [centroid0];
- var squareError;
- for (var i = 0; i < size[0]; i++) {
- squareError = distEuclid(dataSet[i], centroid0);
- clusterAssment[i][1] = mathPow(squareError, 2);
- }
- var lowestSSE;
- var ptsInClust;
- var ptsNotClust;
- var clusterInfo;
- var sseSplit;
- var sseNotSplit;
- var index = 1;
- var result = {
- isEnd: false
- };
- function oneStep() {
- //the existing clusters are continuously divided
- //until the number of clusters is k
- if (index < k) {
- lowestSSE = Infinity;
- var centSplit;
- var newCentroid;
- var newClusterAss;
- for (var j = 0; j < centList.length; j++) {
- ptsInClust = [];
- ptsNotClust = [];
- for (var i = 0; i < clusterAssment.length; i++) {
- if (clusterAssment[i][0] === j) {
- ptsInClust.push(dataSet[i]);
- } else {
- ptsNotClust.push(clusterAssment[i][1]);
- }
- }
- clusterInfo = kMeans(ptsInClust, 2);
- sseSplit = sumOfColumn(clusterInfo.clusterAssigned, 1);
- sseNotSplit = arraySum(ptsNotClust);
- if (sseSplit + sseNotSplit < lowestSSE) {
- lowestSSE = sseNotSplit + sseSplit;
- centSplit = j;
- newCentroid = clusterInfo.centroids;
- newClusterAss = clusterInfo.clusterAssigned;
- }
- }
- for (var i = 0; i < newClusterAss.length; i++) {
- if (newClusterAss[i][0] === 0) {
- newClusterAss[i][0] = centSplit;
- } else if (newClusterAss[i][0] === 1) {
- newClusterAss[i][0] = centList.length;
- }
- }
- centList[centSplit] = newCentroid[0];
- centList.push(newCentroid[1]);
- for (i = 0, j = 0; i < clusterAssment.length && j < newClusterAss.length; i++) {
- if (clusterAssment[i][0] === centSplit) {
- clusterAssment[i][0] = newClusterAss[j][0];
- clusterAssment[i][1] = newClusterAss[j++][1];
- }
- }
- var pointInClust = [];
- for (var i = 0; i < centList.length; i++) {
- pointInClust[i] = [];
- for (var j = 0; j < clusterAssment.length; j++) {
- if (clusterAssment[j][0] === i) {
- pointInClust[i].push(dataSet[j]);
- }
- }
- }
- result.clusterAssment = clusterAssment;
- result.centroids = centList;
- result.pointsInCluster = pointInClust;
- index++;
- } else {
- result.isEnd = true;
- }
- return result;
- }
- var step = {
- next: oneStep
- };
- if (!stepByStep) {
- var result;
- while (!(result = step.next()).isEnd);
- return result;
- } else {
- return step;
- }
- }
- /**
- * Create random centroid of kmeans.
- * @param {Array.<number>} dataSet two-dimension array
- * @param {number} k the number of centroids to be created
- * @return {Array.<number>} random centroids of kmeans
- */
- function createRandCent(dataSet, k) {
- var size = arraySize(dataSet);
- //constructs a two-dimensional array with all values 0
- var centroids = zeros(k, size[1]);
- var minJ;
- var maxJ;
- var rangeJ;
- //create random cluster centers, within bounds of each dimension
- for (var j = 0; j < size[1]; j++) {
- minJ = dataSet[0][j];
- maxJ = dataSet[0][j];
- for (var i = 1; i < size[0]; i++) {
- if (dataSet[i][j] < minJ) {
- minJ = dataSet[i][j];
- }
- if (dataSet[i][j] > maxJ) {
- maxJ = dataSet[i][j];
- }
- }
- rangeJ = maxJ - minJ;
- for (var i = 0; i < k; i++) {
- centroids[i][j] = minJ + rangeJ * Math.random();
- }
- }
- return centroids;
- }
- /**
- * Distance method for calculating similarity
- * @param {Array.<number>} vec1
- * @param {Array.<nnumber>} vec2
- * @return {number}
- */
- function distEuclid(vec1, vec2) {
- if (!isArray(vec1) && !isArray(vec2)) {
- return mathSqrt(mathPow(vec1 - vec2, 2));
- }
- var powerSum = 0;
- //subtract the corresponding elements in the vectors
- for (var i = 0; i < vec1.length; i++) {
- powerSum += mathPow(vec1[i] - vec2[i], 2);
- }
- return mathSqrt(powerSum);
- }
- return {
- kMeans: kMeans,
- hierarchicalKMeans: hierarchicalKMeans
- };
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 2 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var array = __webpack_require__(3);
- var isArray = array.isArray;
- var size = array.size;
- var number = __webpack_require__(4);
- var isNumber = number.isNumber;
- /**
- * Data preprocessing, filter the wrong data object.
- * for example [12,] --- missing y value
- * [,12] --- missing x value
- * [12, b] --- incorrect y value
- * ['a', 12] --- incorrect x value
- * @param {Array.<Array>} data
- * @return {Array.<Array.<number>>}
- */
- function dataPreprocess(data) {
- if (!isArray(data)) {
- throw new Error('Invalid data type, you should input an array');
- }
- var predata = [];
- var arraySize = size(data);
- if (arraySize.length === 1) {
- for (var i = 0; i < arraySize[0]; i++) {
- if (isNumber(data[i])) {
- predata.push(data[i]);
- }
- }
- } else if (arraySize.length === 2) {
- for (var i = 0; i < arraySize[0]; i++) {
- var isCorrect = true;
- for (var j = 0; j < arraySize[1]; j++) {
- if (!isNumber(data[i][j])) {
- isCorrect = false;
- }
- }
- if (isCorrect) {
- predata.push(data[i]);
- }
- }
- }
- return predata;
- }
- /**
- * @param {string|number} val
- * @return {number}
- */
- function getPrecision(val) {
- var str = val.toString();
- // scientific notation is not considered
- var dotIndex = str.indexOf('.');
- return dotIndex < 0 ? 0 : str.length - 1 - dotIndex;
- }
- return {
- dataPreprocess: dataPreprocess,
- getPrecision: getPrecision
- };
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 3 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var objToString = Object.prototype.toString;
- var arrayProto = Array.prototype;
- var nativeMap = arrayProto.map;
- /**
- * Get the size of a array
- * @param {Array} data
- * @return {Array}
- */
- function size(data) {
- var s = [];
- while (isArray(data)) {
- s.push(data.length);
- data = data[0];
- }
- return s;
- }
- /**
- * @param {*} value
- * @return {boolean}
- */
- function isArray(value) {
- return objToString.call(value) === '[object Array]';
- }
- /**
- * constructs a (m x n) array with all values 0
- * @param {number} m the row
- * @param {number} n the column
- * @return {Array}
- */
- function zeros(m, n) {
- var zeroArray = [];
- for (var i = 0; i < m; i++) {
- zeroArray[i] = [];
- for (var j = 0; j < n; j++) {
- zeroArray[i][j] = 0;
- }
- }
- return zeroArray;
- }
- /**
- * Sums each element in the array.
- * Internal use, for performance considerations, to avoid
- * unnecessary judgments and calculations.
- * @param {Array} vector
- * @return {number}
- */
- function sum(vector) {
- var sum = 0;
- for (var i = 0; i < vector.length; i++) {
- sum += vector[i];
- }
- return sum;
- }
- /**
- * Computes the sum of the specified column elements in a two-dimensional array
- * @param {Array.<Array>} dataList two-dimensional array
- * @param {number} n the specified column, zero-based
- * @return {number}
- */
- function sumOfColumn(dataList, n) {
- var sum = 0;
- for (var i = 0; i < dataList.length; i++) {
- sum += dataList[i][n];
- }
- return sum;
- }
- function ascending(a, b) {
- return a > b ? 1 : a < b ? -1 : a === b ? 0 : NaN;
- }
- /**
- * Binary search algorithm --- this bisector is specidfied to histogram, which every bin like that [a, b),
- * so the return value use to add 1.
- * @param {Array.<number>} array
- * @param {number} value
- * @param {number} start
- * @param {number} end
- * @return {number}
- */
- function bisect(array, value, start, end) { //移出去
- if (start == null) {
- start = 0;
- }
- if (end == null) {
- end = array.length;
- }
- while (start < end) {
- var mid = Math.floor((start + end) / 2);
- var compare = ascending(array[mid], value);
- if (compare > 0) {
- end = mid;
- } else if (compare < 0) {
- start = mid + 1;
- } else {
- return mid + 1;
- }
- }
- return start;
- }
- /**
- * 数组映射
- * @memberOf module:zrender/core/util
- * @param {Array} obj
- * @param {Function} cb
- * @param {*} [context]
- * @return {Array}
- */
- function map(obj, cb, context) {
- if (!(obj && cb)) {
- return;
- }
- if (obj.map && obj.map === nativeMap) {
- return obj.map(cb, context);
- } else {
- var result = [];
- for (var i = 0, len = obj.length; i < len; i++) {
- result.push(cb.call(context, obj[i], i, obj));
- }
- return result;
- }
- }
- return {
- size: size,
- isArray: isArray,
- zeros: zeros,
- sum: sum,
- sumOfColumn: sumOfColumn,
- ascending: ascending,
- bisect: bisect,
- map: map
- };
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 4 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- /**
- * Test whether value is a number.
- * @param {*} value
- * @return {boolean}
- */
- function isNumber(value) {
- value = value === null ? NaN : +value;
- return typeof value === 'number' && !isNaN(value);
- }
- /**
- * Test if a number is integer.
- * @param {number} value
- * @return {boolean}
- */
- function isInteger(value) {
- return isFinite(value) && value === Math.round(value);
- }
- return {
- isNumber: isNumber,
- isInteger: isInteger
- };
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 5 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var dataProcess = __webpack_require__(2);
- var dataPreprocess = dataProcess.dataPreprocess;
- var regreMethods = {
- /**
- * Common linear regression algorithm
- * @param {Array.<Array.<number>>} data two-dimensional array
- * @return {Object}
- */
- linear: function (data) {
- var predata = dataPreprocess(data);
- var sumX = 0;
- var sumY = 0;
- var sumXY = 0;
- var sumXX = 0;
- var len = predata.length;
- for (var i = 0; i < len; i++) {
- sumX += predata[i][0];
- sumY += predata[i][1];
- sumXY += predata[i][0] * predata[i][1];
- sumXX += predata[i][0] * predata[i][0];
- }
- var gradient = ((len * sumXY) - (sumX * sumY)) / ((len * sumXX) - (sumX * sumX));
- var intercept = (sumY / len) - ((gradient * sumX) / len);
- var result = [];
- for (var j = 0; j < predata.length; j++) {
- var coordinate = [predata[j][0], gradient * predata[j][0] + intercept];
- result.push(coordinate);
- }
- var string = 'y = ' + Math.round(gradient * 100) / 100 + 'x + ' + Math.round(intercept * 100) / 100;
- return {
- points: result,
- parameter: {
- gradient: gradient,
- intercept: intercept
- },
- expression: string
- };
- },
- /**
- * If the raw data include [0,0] point, we should choose linearThroughOrigin
- * instead of linear.
- * @param {Array.<Array>} data two-dimensional number array
- * @return {Object}
- */
- linearThroughOrigin: function (data) {
- var predata = dataPreprocess(data);
- var sumXX = 0;
- var sumXY = 0;
- for (var i = 0; i < predata.length; i++) {
- sumXX += predata[i][0] * predata[i][0];
- sumXY += predata[i][0] * predata[i][1];
- }
- var gradient = sumXY / sumXX;
- var result = [];
- for (var j = 0; j < predata.length; j++) {
- var coordinate = [predata[j][0], predata[j][0] * gradient];
- result.push(coordinate);
- }
- var string = 'y = ' + Math.round(gradient * 100) / 100 + 'x';
- return {
- points: result,
- parameter: {
- gradient: gradient
- },
- expression: string
- };
- },
- /**
- * Exponential regression
- * @param {Array.<Array.<number>>} data two-dimensional number array
- * @return {Object}
- */
- exponential: function (data) {
- var predata = dataPreprocess(data);
- var sumX = 0;
- var sumY = 0;
- var sumXXY = 0;
- var sumYlny = 0;
- var sumXYlny = 0;
- var sumXY = 0;
- for (var i = 0; i < predata.length; i++) {
- sumX += predata[i][0];
- sumY += predata[i][1];
- sumXY += predata[i][0] * predata[i][1];
- sumXXY += predata[i][0] * predata[i][0] * predata[i][1];
- sumYlny += predata[i][1] * Math.log(predata[i][1]);
- sumXYlny += predata[i][0] * predata[i][1] * Math.log(predata[i][1]);
- }
- var denominator = (sumY * sumXXY) - (sumXY * sumXY);
- var coefficient = Math.pow(Math.E, (sumXXY * sumYlny - sumXY * sumXYlny) / denominator);
- var index = (sumY * sumXYlny - sumXY * sumYlny) / denominator;
- var result = [];
- for (var j = 0; j < predata.length; j++) {
- var coordinate = [predata[j][0], coefficient * Math.pow(Math.E, index * predata[j][0])];
- result.push(coordinate);
- }
- var string = 'y = ' + Math.round(coefficient * 100) / 100 + 'e^(' + Math.round(index * 100) / 100 + 'x)';
- return {
- points: result,
- parameter: {
- coefficient: coefficient,
- index: index
- },
- expression: string
- };
- },
- /**
- * Logarithmic regression
- * @param {Array.<Array.<number>>} data two-dimensional number array
- * @return {Object}
- */
- logarithmic: function (data) {
- var predata = dataPreprocess(data);
- var sumlnx = 0;
- var sumYlnx = 0;
- var sumY = 0;
- var sumlnxlnx = 0;
- for (var i = 0; i < predata.length; i++) {
- sumlnx += Math.log(predata[i][0]);
- sumYlnx += predata[i][1] * Math.log(predata[i][0]);
- sumY += predata[i][1];
- sumlnxlnx += Math.pow(Math.log(predata[i][0]), 2);
- }
- var gradient = (i * sumYlnx - sumY * sumlnx) / (i * sumlnxlnx - sumlnx * sumlnx);
- var intercept = (sumY - gradient * sumlnx) / i;
- var result = [];
- for (var j = 0; j < predata.length; j++) {
- var coordinate = [predata[j][0], gradient * Math.log(predata[j][0]) + intercept];
- result.push(coordinate);
- }
- var string =
- 'y = ' +
- Math.round(intercept * 100) / 100 +
- ' + ' +
- Math.round(gradient * 100) / 100 + 'ln(x)';
- return {
- points: result,
- parameter: {
- gradient: gradient,
- intercept: intercept
- },
- expression: string
- };
- },
- /**
- * Polynomial regression
- * @param {Array.<Array.<number>>} data two-dimensional number array
- * @param {number} order order of polynomials
- * @return {Object}
- */
- polynomial: function (data, order) {
- var predata = dataPreprocess(data);
- if (typeof order === 'undefined') {
- order = 2;
- }
- //coefficient matrix
- var coeMatrix = [];
- var lhs = [];
- var k = order + 1;
- for (var i = 0; i < k; i++) {
- var sumA = 0;
- for (var n = 0; n < predata.length; n++) {
- sumA += predata[n][1] * Math.pow(predata[n][0], i);
- }
- lhs.push(sumA);
- var temp = [];
- for (var j = 0; j < k; j++) {
- var sumB = 0;
- for (var m = 0; m < predata.length; m++) {
- sumB += Math.pow(predata[m][0], i + j);
- }
- temp.push(sumB);
- }
- coeMatrix.push(temp);
- }
- coeMatrix.push(lhs);
- var coeArray = gaussianElimination(coeMatrix, k);
- var result = [];
- for (var i = 0; i < predata.length; i++) {
- var value = 0;
- for (var n = 0; n < coeArray.length; n++) {
- value += coeArray[n] * Math.pow(predata[i][0], n);
- }
- result.push([predata[i][0], value]);
- }
- var string = 'y = ';
- for (var i = coeArray.length - 1; i >= 0; i--) {
- if (i > 1) {
- string += Math.round(coeArray[i] * Math.pow(10, i + 1)) / Math.pow(10, i + 1) + 'x^' + i + ' + ';
- } else if (i === 1) {
- string += Math.round(coeArray[i] * 100) / 100 + 'x' + ' + ';
- } else {
- string += Math.round(coeArray[i] * 100) / 100;
- }
- }
- return {
- points: result,
- parameter: coeArray,
- expression: string
- };
- }
- };
- /**
- * Gaussian elimination
- * @param {Array.<Array.<number>>} matrix two-dimensional number array
- * @param {number} number
- * @return {Array}
- */
- function gaussianElimination(matrix, number) {
- for (var i = 0; i < matrix.length - 1; i++) {
- var maxColumn = i;
- for (var j = i + 1; j < matrix.length - 1; j++) {
- if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][maxColumn])) {
- maxColumn = j;
- }
- }
- // the matrix here is the transpose of the common Augmented matrix.
- // so the can perform the primary column transform, in fact, equivalent
- // to the primary line changes
- for (var k = i; k < matrix.length; k++) {
- var temp = matrix[k][i];
- matrix[k][i] = matrix[k][maxColumn];
- matrix[k][maxColumn] = temp;
- }
- for (var n = i + 1; n < matrix.length - 1; n++) {
- for (var m = matrix.length - 1; m >= i; m--) {
- matrix[m][n] -= matrix[m][i] / matrix[i][i] * matrix[i][n];
- }
- }
- }
- var data = new Array(number);
- var len = matrix.length - 1;
- for (var j = matrix.length - 2; j >= 0; j--) {
- var temp = 0;
- for (var i = j + 1; i < matrix.length - 1; i++) {
- temp += matrix[i][j] * data[i];
- }
- data[j] = (matrix[len][j] - temp) / matrix[j][j];
- }
- return data;
- }
- var regression = function (regreMethod, data, order) {
- return regreMethods[regreMethod](data, order);
- };
- return regression;
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 6 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var statistics = {};
- statistics.max = __webpack_require__(7);
- statistics.deviation = __webpack_require__(8);
- statistics.mean = __webpack_require__(10);
- statistics.median = __webpack_require__(12);
- statistics.min = __webpack_require__(14);
- statistics.quantile = __webpack_require__(13);
- statistics.sampleVariance = __webpack_require__(9);
- statistics.sum = __webpack_require__(11);
- return statistics;
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 7 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var number = __webpack_require__(4);
- var isNumber = number.isNumber;
- /**
- * Is a method for computing the max value of a list of numbers,
- * which will filter other data types.
- * @param {Array.<number>} data
- * @return {number}
- */
- function max(data) {
- var maxData = -Infinity;
- for (var i = 0; i < data.length; i++) {
- if (isNumber(data[i]) && data[i] > maxData) {
- maxData = data[i];
- }
- }
- return maxData;
- }
- return max;
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 8 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var variance = __webpack_require__(9);
- /**
- * Computing the deviation
- * @param {Array.<number>} data
- * @return {number}
- */
- return function (data) {
- var squaredDeviation = variance(data);
- return squaredDeviation ? Math.sqrt(squaredDeviation) : squaredDeviation;
- };
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 9 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var number = __webpack_require__(4);
- var isNumber = number.isNumber;
- var mean = __webpack_require__(10);
- /**
- * Computing the variance of list of sample
- * @param {Array.<number>} data
- * @return {number}
- */
- function sampleVariance(data) {
- var len = data.length;
- if (!len || len < 2) {
- return 0;
- }
- if (data.length >= 2) {
- var meanValue = mean(data);
- var sum = 0;
- var temple;
- for (var i = 0; i < data.length; i++) {
- if (isNumber(data[i])) {
- temple = data[i] - meanValue;
- sum += temple * temple;
- }
- }
- return sum / (data.length - 1);
- }
- }
- return sampleVariance;
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 10 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var sum = __webpack_require__(11);
- /**
- * Is a method for computing the mean value of a list of numbers,
- * which will filter other data types.
- * @param {Array.<number>} data
- * @return {number}
- */
- function mean(data) {
- var len = data.length;
- if (!len) {
- return 0;
- }
- return sum(data) / data.length;
- }
- return mean;
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 11 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var number = __webpack_require__(4);
- var isNumber = number.isNumber;
- /**
- * Is a method for computing the sum of a list of numbers,
- * which will filter other data types.
- * @param {Array.<number>} data
- * @return {number}
- */
- function sum(data) {
- var len = data.length;
- if (!len) {
- return 0;
- }
- var sumData = 0;
- for (var i = 0; i < len; i++) {
- if (isNumber(data[i])) {
- sumData += data[i];
- }
- }
- return sumData;
- }
- return sum;
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 12 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var quantile = __webpack_require__(13);
- /**
- * Is a method for computing the median value of a sorted array of numbers
- * @param {Array.<number>} data
- * @return {number}
- */
- function median(data) {
- return quantile(data, 0.5);
- }
- return median;
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 13 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- /**
- * Estimating quantiles from a sorted sample of numbers
- * @see https://en.wikipedia.org/wiki/Quantile#Estimating_quantiles_from_a_sample
- * R-7 method
- * @param {Array.<number>} data sorted array
- * @param {number} p
- */
- return function (data, p) {
- var len = data.length;
- if (!len) {
- return 0;
- }
- if (p <= 0 || len < 2) {
- return data[0];
- }
- if (p >= 1) {
- return data[len - 1];
- }
- // in the wikipedia's R-7 method h = (N - 1)p + 1, but here array index start from 0
- var h = (len - 1) * p;
- var i = Math.floor(h);
- var a = data[i];
- var b = data[i + 1];
- return a + (b - a) * (h - i);
- };
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 14 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var number = __webpack_require__(4);
- var isNumber = number.isNumber;
- /**
- * Is a method for computing the min value of a list of numbers,
- * which will filter other data types.
- * @param {Array.<number>} data
- * @return {number}
- */
- function min(data) {
- var minData = Infinity;
- for (var i = 0; i < data.length; i++) {
- if (isNumber(data[i]) && data[i] < minData) {
- minData = data[i];
- }
- }
- return minData;
- }
- return min;
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 15 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var max = __webpack_require__(7);
- var min = __webpack_require__(14);
- var quantile = __webpack_require__(13);
- var deviation = __webpack_require__(8);
- var dataProcess = __webpack_require__(2);
- var dataPreprocess = dataProcess.dataPreprocess;
- var getPrecision = dataProcess.getPrecision;
- var array = __webpack_require__(3);
- var ascending = array.ascending;
- var map = array.map;
- var range = __webpack_require__(16);
- var bisect = array.bisect;
- var tickStep = __webpack_require__(17);
- /**
- * Compute bins for histogram
- * @param {Array.<number>} data
- * @param {string} threshold
- * @return {Object}
- */
- function computeBins(data, threshold) {
- if (threshold == null) {
- threshold = thresholdMethod.squareRoot;
- } else {
- threshold = thresholdMethod[threshold];
- }
- var values = dataPreprocess(data);
- var maxValue = max(values);
- var minValue = min(values);
- var binsNumber = threshold(values, minValue, maxValue);
- var step = tickStep(minValue, maxValue, binsNumber);
- var precision = -Math.floor(Math.log(Math.abs(maxValue - minValue) / binsNumber) / Math.LN10);
- // return the xAxis coordinate for each bins, except the end point of the value
- var rangeArray = range(
- // use function toFixed() to avoid data like '0.700000001'
- +((Math.ceil(minValue / step) * step).toFixed(precision)),
- +((Math.floor(maxValue / step) * step).toFixed(precision)),
- step,
- precision
- );
- var len = rangeArray.length;
- var bins = new Array(len + 1);
- for (var i = 0; i <= len; i++) {
- bins[i] = {};
- bins[i].sample = [];
- bins[i].x0 = i > 0 ?
- rangeArray[i - 1] :
- (rangeArray[i] - minValue) === step ?
- minValue :
- (rangeArray[i] - step);
- bins[i].x1 = i < len ?
- rangeArray[i] :
- (maxValue - rangeArray[i - 1]) === step ?
- maxValue :
- rangeArray[i - 1] + step;
- }
- for (var i = 0; i < values.length; i++) {
- if (minValue <= values[i] && values[i] <= maxValue) {
- bins[bisect(rangeArray, values[i], 0, len)].sample.push(values[i]);
- }
- }
- var data = map(bins, function (bin) {
- // use function toFixed() to avoid data like '6.5666638489'
- return [+((bin.x0 + bin.x1) / 2).toFixed(precision), bin.sample.length];
- });
- var customData = map(bins, function (bin) {
- return [bin.x0, bin.x1, bin.sample.length];
- });
- return {
- bins: bins,
- data: data,
- customData: customData
- };
- }
- /**
- * Four kinds of threshold methods used to
- * compute how much bins the histogram should be divided
- * @see https://en.wikipedia.org/wiki/Histogram
- * @type {Object}
- */
- var thresholdMethod = {
- squareRoot: function (data) {
- var bins = Math.ceil(Math.sqrt(data.length));
- return bins > 50 ? 50 : bins;
- },
- scott: function (data, min, max) {
- return Math.ceil((max - min) / (3.5 * deviation(data) * Math.pow(data.length, -1 / 3)));
- },
- freedmanDiaconis: function (data, min, max) {
- data.sort(ascending);
- return Math.ceil(
- (max - min) / (2 * (quantile(data, 0.75) - quantile(data, 0.25)) * Math.pow(data.length, -1 / 3))
- );
- },
- sturges: function (data) {
- return Math.ceil(Math.log(data.length) / Math.LN2) + 1;
- }
- };
- return computeBins;
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 16 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- var dataProcess = __webpack_require__(2);
- var getPrecision = dataProcess.getPrecision;
- /**
- * Computing range array.
- * Adding param precision to fix range value, avoiding range[i] = 0.7000000001.
- * @param {number} start
- * @param {number} end
- * @param {number} step
- * @param {number} precision
- * @return {Array.<number>}
- */
- return function (start, end, step, precision) {
- var len = arguments.length;
- if (len < 2) {
- end = start;
- start = 0;
- step = 1;
- } else if (len < 3) {
- step = 1;
- } else if (len < 4) {
- step = +step;
- precision = getPrecision(step);
- } else {
- precision = +precision;
- }
- var n = Math.ceil(((end - start) / step).toFixed(precision));
- var range = new Array(n + 1);
- for (var i = 0; i < n + 1; i++) {
- range[i] = +(start + i * step).toFixed(precision);
- }
- return range;
- };
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- }),
- /* 17 */
- /***/
- (function (module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_RESULT__;
- !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
- /**
- * Computing the length of step
- * @see https://github.com/d3/d3-array/blob/master/src/ticks.js
- * @param {number} start
- * @param {number} stop
- * @param {number} count
- */
- return function (start, stop, count) {
- var step0 = Math.abs(stop - start) / count;
- var precision = Math.floor(Math.log(step0) / Math.LN10);
- var step1 = Math.pow(10, precision);
- var error = step0 / step1;
- if (error >= Math.sqrt(50)) {
- step1 *= 10;
- } else if (error >= Math.sqrt(10)) {
- step1 *= 5;
- } else if (error >= Math.sqrt(2)) {
- step1 *= 2;
- }
- return +((stop >= start ? step1 : -step1).toFixed(-precision));
- };
- }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- /***/
- })
- /******/
- ])
- });;
|