Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,47 @@ Convert between Celsius (°C), Fahrenheit (°F), and Kelvin (K).
- **PI**
Math.PI constant (≈3.14159).

### 📊 Interpoolation and regression

- **interpolation(input: { function: (number) => number, value: number, points: number[] })**
Interpolates a set of data points from a function and value through Newton Interpolation.

```js
interpolation({
function: Math.log,
value: 2,
points: [1, 4, 6]
})

➔ 0.5658443469009827
```

- **regression(input: number[])**
Computes the linear and polynomial regression from a set of data points.

```js
regression([
[-2, -1],
[1, 2],
[4, 59],
[-1, 4],
[3, 24],
[-4, -53]
]);

➔ {
linear: {
m: 10.97864768683274,
b: 4.00355871886121
},
polynomial: {
a: 6.689189189189188,
b: 11.060810810810809,
c: -0.34459459459459435
}
}
```

### 📊 Population Statistics

- **populationDensity(population, area)**
Expand Down
34 changes: 19 additions & 15 deletions src/area.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,50 @@ import { PI, squared } from './numbers.js';
*/
export const area = {
/**
* @param base Size of the base of the rectangle
* @param height The height of the rectangle
* @param {number} base Size of the base of the rectangle
* @param {number} height The height of the rectangle
*
* @returns base * height
* @returns {number} base * height
*/
rect: (base: number, height: number): number => {
return Math.floor(base * height);
},

/**
* @param base Size of the base of the triangle
* @param height The height of the triangle
* @param {number} base Size of the base of the triangle
* @param {number} height The height of the triangle
*
* @returns (base * height) / 2
* @returns {number} (base * height) / 2
*/
triangle: (base: number, height: number): number => {
return Math.floor((base * height) / 2);
},

/**
* @param D larger diagonal
* @param d smaller diagonal
* @param {number} D larger diagonal
* @param {number} d smaller diagonal
*
* @returns (D * d) / 2
* @returns {number} (D * d) / 2
*/
rhombus: (D: number, d: number): number => {
return Math.floor((D * d) / 2);
},

/**
* @param B Larger base
* @param b Smaller base
* @param height Trapezoid height
* @param {number} B Larger base
* @param {number} b Smaller base
* @param {number} height Trapezoid height
*
* @returns ((B + b) * height) / 2
* @returns {number} ((B + b) * height) / 2
*/
trapezoid: (B: number, b: number, height: number): number => {
return Math.floor(((B + b) * height) / 2);
},

/**
* @param radius Circle radius
* @param {number} radius Circle radius
*
* @returns π * (radius * radius)
* @returns {number} π * (radius * radius)
*/
circle: (radius: number): number => {
return Math.floor(PI * squared(radius));
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export * from './temperatures.js';
export * from './numbers.js';
export * from './area.js';
export * from './population.js';
export * from './interpolation.js';
export * from './regression.js';
49 changes: 49 additions & 0 deletions src/interpolation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export interface InterpolationInput {
function: (input: number) => number;
value: number;
points: number[];
}

function getNewtonInterpolationB(
input: InterpolationInput,
end: number,
start: number,
): number {
if (end == start) {
return input.function(input.points[start]!);
}

return (
(getNewtonInterpolationB(input, end, start + 1) -
getNewtonInterpolationB(input, end - 1, start)) /
(input.points[end]! - input.points[start]!)
);
}

/**
* @param {InterpolationInput} input Interpolation input
*
* @returns {number} Interpolation result through Newton Interpolation
*/
export function interpolation(input: InterpolationInput): number {
if (input.points.length < 1) {
throw new Error('Points array must not be empty.');
}

let multiplier,
output = input.function(input.points[0]!);

for (let multiplierIndex, index = 1; index < input.points.length; index++) {
for (
multiplier = 1, multiplierIndex = 0;
multiplierIndex < index;
multiplierIndex++
) {
multiplier *= input.value - input.points[multiplierIndex]!;
}

output += multiplier * getNewtonInterpolationB(input, multiplierIndex, 0);
}

return output;
}
39 changes: 24 additions & 15 deletions src/numbers.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,58 @@
export const PI = Math.PI;

/**
* @param number The value of the number
* @returns boolean
* If it is even
* @param {number} number The value of the number
*
* @returns {boolean} If it is even
*/
export function isEven(number: number): boolean {
return number % 2 == 0;
}

/**
* @param number The value of the number
* @returns boolean
* If it is odd
* @param {number} number The value of the number
*
* @returns {boolean} If it is odd
*/
export function isOdd(number: number): boolean {
return !isEven(number);
}

/**
* @param x First number
* @param y Second number
* @returns The difference value between X and Y
* @param {number} x First number
* @param {number} y Second number
*
* @returns {number} The difference value between X and Y
*/
export function difference(x: number, y: number): number {
return Math.max(x - y);
}

/**
* @param x Target value
* @param times Times that the value can be multiplied by itself
* @returns The squared value
* @param {number} x Target value
* @param {number} [times] Times that the value can be multiplied by itself
*
* @returns {number} The squared value
*/
export function squared(x: number, times?: number): number {
return Math.pow(x, times ?? 2);
}

/**
* @param C Adjacent Cathetus
* @param c Opposite Cathetus
* @returns Value of the Hypotenuse
* @param {number} C Adjacent Cathetus
* @param {number} c Opposite Cathetus
*
* @returns {number} Value of the Hypotenuse
*/
export function hypotenuse(C: number, c: number): number {
var h = squared(C) + squared(c);

return Math.sqrt(h);
}

export function cathetus(H: number, C: number): number {
if (H <= C)
throw new Error('Cathetus cannot be greater or equal than Hypotenuse.');

return Math.sqrt(squared(H) - squared(C));
}
112 changes: 112 additions & 0 deletions src/regression.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
export interface LinearRegressionOutput {
m: number;
b: number;
}

export interface PolynomialRegressionOutput {
a: number;
b: number;
c: number;
}

export interface RegressionOutput {
linear: LinearRegressionOutput;
polynomial: PolynomialRegressionOutput;
}

function computePolynomialRegressionMatrix(matrix: number[]) {
let pivot, eliminationPivot;

for (let i = 0, j, k; i < 3; i++) {
const pivotStartIndex = i * 4;
pivot = matrix[pivotStartIndex + i]!;

for (j = 0; j < 4; j++) {
matrix[pivotStartIndex + j]! /= pivot;
}

for (j = 0; j < 3; j++) {
if (j == i) {
continue;
}

const nonPivotStartIndex = j * 4;
eliminationPivot = matrix[nonPivotStartIndex + i]!;

for (k = i; k < 4; k++) {
matrix[nonPivotStartIndex + k]! -=
eliminationPivot * matrix[pivotStartIndex + k]!;
}
}
}
}

/**
* @param {number[][]} input Regression input, must be an array of [x, y]
*
* @returns {RegressionOutput} Regression result for both linear and polynomial regression
*/
export function regression(input: number[][]): RegressionOutput {
if (input.length === 0) {
throw new Error('Input array must not be empty.');
}

let x,
y,
mDivisor,
sumX = 0,
sumY = 0,
sumXY = 0,
sumXSquared = 0,
sumXCubed = 0,
sumXPower4 = 0,
sumXSquaredY = 0;

for (let index = 0; index < input.length; index++) {
x = input[index]![0]!;
y = input[index]![1]!;

sumX += x;
sumY += y;
sumXY += x * y;
sumXSquared += x * x;
sumXCubed += x * x * x;
sumXPower4 += x * x * x * x;
sumXSquaredY += x * x * y;
}

const m =
(mDivisor = input.length * sumXSquared - sumX * sumX) === 0
? 0
: (input.length * sumXY - sumX * sumY) / mDivisor;
const b = (sumY - m * sumX) / input.length;

const polMatrix = [
input.length,
sumX,
sumXSquared,
sumY,
sumX,
sumXSquared,
sumXCubed,
sumXY,
sumXSquared,
sumXCubed,
sumXPower4,
sumXSquaredY,
];

computePolynomialRegressionMatrix(polMatrix);

return {
linear: {
m,
b,
},
polynomial: {
a: polMatrix[3]!,
b: polMatrix[7]!,
c: polMatrix[11]!,
},
};
}
Loading