diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..76add87 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist \ No newline at end of file diff --git a/README.md b/README.md index 125d80d..7d0f5b2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# math -Mathematical algorithm +# Math +### Mathematical algorithm diff --git a/package.json b/package.json new file mode 100644 index 0000000..52b98a8 --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "@types/node": "^14.11.10" + }, + "scripts": { + "build":"tsc", + "dev":"tsc --watch" + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..dcc3066 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,14 @@ +import median from "./lib/median"; +import average from "./lib/average"; +import leastSquareMethod from "./lib/least-square-method"; +import mode from "./lib/mode"; +import variance from "./lib/variance"; +import standardDeviation from "./lib/standard-deviation"; +export default { + median, + average, + leastSquareMethod, + mode, + variance, + standardDeviation +} \ No newline at end of file diff --git a/src/lib/average.ts b/src/lib/average.ts new file mode 100644 index 0000000..b1bccde --- /dev/null +++ b/src/lib/average.ts @@ -0,0 +1,14 @@ +import sum from "./tools/sum"; +export default function average(list: list, weight?: list): number | null { + if (list.length >= 2) { + if (weight && weight.length === list.length) { + return sum(list.map((number, index) => number * weight[index])) / sum(weight); + } else { + return sum(list) / list.length; + } + } else if (list.length < 1) { + return null + } else { + return list[0]; + } +} \ No newline at end of file diff --git a/src/lib/least-square-method.ts b/src/lib/least-square-method.ts new file mode 100644 index 0000000..17308bf --- /dev/null +++ b/src/lib/least-square-method.ts @@ -0,0 +1,30 @@ +import average from "./average"; +interface res { + k: number | null + b: number | null +} +export default function leastSquareMethod(xyPair: xyList): res { + if (xyPair.length >= 2) { + let xs: list = [], ys: list = [], xys: list = [], xxs: list = [], averagedX: number, averagedY: number, averagedXY: number, averagedXX: number, k: number; + xyPair.forEach(xy => { + xs.push(xy.x); + ys.push(xy.y); + xys.push(xy.x * xy.y); + xxs.push(xy.x * xy.x); + }); + averagedX = average(xs)!; + averagedY = average(ys)!; + averagedXY = average(xys)!; + averagedXX = average(xxs)!; + k = (averagedXY - averagedX * averagedY) / (averagedXX - averagedX * averagedX); + return { + k, + b: averagedY - averagedX * k + } + } else { + return { + k: null, + b: null + } + } +} \ No newline at end of file diff --git a/src/lib/median.ts b/src/lib/median.ts new file mode 100644 index 0000000..e420da3 --- /dev/null +++ b/src/lib/median.ts @@ -0,0 +1,16 @@ +export default function median(list: list): number | null { + if (list.length > 0) { + let sortedList: list = list.sort(); + if (sortedList.length < 2) { + return sortedList[0]; + } else { + if (sortedList.length % 2 === 0) { + return (sortedList[sortedList.length / 2 - 1] + sortedList[sortedList.length / 2]) / 2; + } else { + return sortedList[Math.floor(sortedList.length / 2)] + } + } + } else { + return null + } +} \ No newline at end of file diff --git a/src/lib/mode.ts b/src/lib/mode.ts new file mode 100644 index 0000000..92f1c89 --- /dev/null +++ b/src/lib/mode.ts @@ -0,0 +1,16 @@ +import unique from "./tools/unique"; +interface xvPair { + n: number, + f: number +} +export default function mode(list: list): list | null { + if (list.length >= 2) { + let uniqueList: list = unique(list); + let valueList: list = uniqueList.map(number => list.join(' ').match(new RegExp(number.toString(), 'g'))!.length).map(v => Number(v)); + return valueList.filter(v => v === Math.max(...valueList)).map(v => Number(uniqueList[valueList.indexOf(v)])); + } else if (list.length === 1) { + return [list[0]]; + } else { + return null; + } +} \ No newline at end of file diff --git a/src/lib/standard-deviation.ts b/src/lib/standard-deviation.ts new file mode 100644 index 0000000..b714a96 --- /dev/null +++ b/src/lib/standard-deviation.ts @@ -0,0 +1,8 @@ +import variance from "./variance"; +export default function standardDeviation(list:list):number{ + if(list.length > 1){ + return Math.sqrt(variance(list)); + }else{ + return 0; + } +} \ No newline at end of file diff --git a/src/lib/tools/sum.ts b/src/lib/tools/sum.ts new file mode 100644 index 0000000..942aabc --- /dev/null +++ b/src/lib/tools/sum.ts @@ -0,0 +1,13 @@ +export default function sum(list: list): number { + if (list.length < 1) { + return 0; + } else if (list.length < 2) { + return list[0]; + } else { + let res = 0; + list.forEach(number => { + res += number + }); + return res; + } +} \ No newline at end of file diff --git a/src/lib/tools/unique.ts b/src/lib/tools/unique.ts new file mode 100644 index 0000000..1848758 --- /dev/null +++ b/src/lib/tools/unique.ts @@ -0,0 +1,7 @@ +export default function unique(list: list): list { + if (list.length > 1) { + return [...(new Set(list))]; + } else { + return list; + } +} \ No newline at end of file diff --git a/src/lib/variance.ts b/src/lib/variance.ts new file mode 100644 index 0000000..74ce35a --- /dev/null +++ b/src/lib/variance.ts @@ -0,0 +1,9 @@ +import average from "./average"; +import sum from "./tools/sum"; +export default function variance(list:list):number{ + if(list.length > 1){ + return sum(list.map(number=>Math.pow(number - average(list)!,2))) / list.length; + }else{ + return 0; + } +} \ No newline at end of file diff --git a/src/test/index.ts b/src/test/index.ts new file mode 100644 index 0000000..0370aa3 --- /dev/null +++ b/src/test/index.ts @@ -0,0 +1,8 @@ +import math from "../index"; +console.log('start tests...') +console.assert(math.median([1, 2, 3]) === 2, "check median"); +console.assert(math.average([1, 2, 3], [3, 2, 1]) === 10 / 6,"check weight average"); +console.assert(math.mode([2,4,4,3,3,3])!.toString() === [3].toString(),"check mode"); +console.assert(math.variance([1,2]) === (Math.pow(1-1.5,2)+Math.pow(2-1.5,2))/2,"check variance"); +console.assert(math.standardDeviation([1,2]) === Math.sqrt((Math.pow(1-1.5,2)+Math.pow(2-1.5,2))/2),"check standard deviation") +console.log('all done'); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5c04666 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,70 @@ +{ + "typeAcquisition": { + "enable": false + }, + "include": [ + "src/**/*", + "types/**/*" + ], + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + /* Basic Options */ + "incremental": true, /* Enable incremental compilation */ + "target": "ES5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + "allowJs": true, /* Allow javascript files to be compiled. */ + "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + //"outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "dist", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./BUILDINFO", /* Specify file to store incremental compilation information */ + "removeComments": true, /* Do not emit comments to output. */ + "suppressImplicitAnyIndexErrors": true, + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": ["types/*.d.ts"], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + /* Advanced Options */ + "skipLibCheck": true, /* Skip type checking of declaration files. */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +} \ No newline at end of file diff --git a/types/list.d.ts b/types/list.d.ts new file mode 100644 index 0000000..a51a37a --- /dev/null +++ b/types/list.d.ts @@ -0,0 +1 @@ +declare type list = number[]; \ No newline at end of file diff --git a/types/xyList.d.ts b/types/xyList.d.ts new file mode 100644 index 0000000..e00757f --- /dev/null +++ b/types/xyList.d.ts @@ -0,0 +1,6 @@ +interface xyPair{ + x:number + y:number +} + +declare type xyList = xyPair[]; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..7df5bb7 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,8 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@^14.11.10": + version "14.11.10" + resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-14.11.10.tgz?cache=0&sync_timestamp=1602874323764&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.11.10.tgz#8c102aba13bf5253f35146affbf8b26275069bef" + integrity sha1-jBAquhO/UlPzUUav+/iyYnUGm+8=