Skip to content

Commit

Permalink
Added CDF
Browse files Browse the repository at this point in the history
  • Loading branch information
smikhalevski committed Aug 29, 2023
1 parent 24d89f1 commit 7223d3d
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/main/all.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Mapper } from './types';

export function all(...fns: Mapper[]): Mapper {
return x => {
for (const fn of fns) {
x = fn(x);
}
return x;
};
}
71 changes: 71 additions & 0 deletions src/main/cdf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Mapper } from './types';
import { abs } from './utils';

/**
* Cumulative distribution function for Gaussian distribution.
*
* @param m Mean of the input value.
* @param d Standard deviation of the input value.
*/
export function cdf(m = 0, d = 1): Mapper {
return x => {
let p;
let z = (x - m) / d;

if (z !== z) {
return NaN;
}
if (z === 0) {
return 0.5;
}
if (z <= -3.5) {
return 0;
}
if (z >= 3.5) {
return 1;
}

p = abs(z);
p = zTable[(p * 10) | 0][((p * 100) | 0) - ((p * 10) | 0) * 10];

return z < 0 ? 1 - p : p;
};
}

const zTable = [
[0.5, 0.504, 0.508, 0.512, 0.516, 0.5199, 0.5239, 0.5279, 0.5319, 0.5359],
[0.5398, 0.5438, 0.5478, 0.5517, 0.5557, 0.5596, 0.5636, 0.5675, 0.5714, 0.5753],
[0.5793, 0.5832, 0.5871, 0.591, 0.5948, 0.5987, 0.6026, 0.6064, 0.6103, 0.6141],
[0.6179, 0.6217, 0.6255, 0.6293, 0.6331, 0.6368, 0.6406, 0.6443, 0.648, 0.6517],
[0.6554, 0.6591, 0.6628, 0.6664, 0.67, 0.6736, 0.6772, 0.6808, 0.6844, 0.6879],
[0.6915, 0.695, 0.6985, 0.7019, 0.7054, 0.7088, 0.7123, 0.7157, 0.719, 0.7224],
[0.7257, 0.7291, 0.7324, 0.7357, 0.7389, 0.7422, 0.7454, 0.7486, 0.7517, 0.7549],
[0.758, 0.7611, 0.7642, 0.7673, 0.7704, 0.7734, 0.7764, 0.7794, 0.7823, 0.7852],
[0.7881, 0.791, 0.7939, 0.7967, 0.7995, 0.8023, 0.8051, 0.8078, 0.8106, 0.8133],
[0.8159, 0.8186, 0.8212, 0.8238, 0.8264, 0.8289, 0.8315, 0.834, 0.8365, 0.8389],
[0.8413, 0.8438, 0.8461, 0.8485, 0.8508, 0.8531, 0.8554, 0.8577, 0.8599, 0.8621],
[0.8643, 0.8665, 0.8686, 0.8708, 0.8729, 0.8749, 0.877, 0.879, 0.881, 0.883],
[0.8849, 0.8869, 0.8888, 0.8907, 0.8925, 0.8944, 0.8962, 0.898, 0.8997, 0.9015],
[0.9032, 0.9049, 0.9066, 0.9082, 0.9099, 0.9115, 0.9131, 0.9147, 0.9162, 0.9177],
[0.9192, 0.9207, 0.9222, 0.9236, 0.9251, 0.9265, 0.9279, 0.9292, 0.9306, 0.9319],
[0.9332, 0.9345, 0.9357, 0.937, 0.9382, 0.9394, 0.9406, 0.9418, 0.9429, 0.9441],
[0.9452, 0.9463, 0.9474, 0.9484, 0.9495, 0.9505, 0.9515, 0.9525, 0.9535, 0.9545],
[0.9554, 0.9564, 0.9573, 0.9582, 0.9591, 0.9599, 0.9608, 0.9616, 0.9625, 0.9633],
[0.9641, 0.9649, 0.9656, 0.9664, 0.9671, 0.9678, 0.9686, 0.9693, 0.9699, 0.9706],
[0.9713, 0.9719, 0.9726, 0.9732, 0.9738, 0.9744, 0.975, 0.9756, 0.9761, 0.9767],
[0.9772, 0.9778, 0.9783, 0.9788, 0.9793, 0.9798, 0.9803, 0.9808, 0.9812, 0.9817],
[0.9821, 0.9826, 0.983, 0.9834, 0.9838, 0.9842, 0.9846, 0.985, 0.9854, 0.9857],
[0.9861, 0.9864, 0.9868, 0.9871, 0.9875, 0.9878, 0.9881, 0.9884, 0.9887, 0.989],
[0.9893, 0.9896, 0.9898, 0.9901, 0.9904, 0.9906, 0.9909, 0.9911, 0.9913, 0.9916],
[0.9918, 0.992, 0.9922, 0.9925, 0.9927, 0.9929, 0.9931, 0.9932, 0.9934, 0.9936],
[0.9938, 0.994, 0.9941, 0.9943, 0.9945, 0.9946, 0.9948, 0.9949, 0.9951, 0.9952],
[0.9953, 0.9955, 0.9956, 0.9957, 0.9959, 0.996, 0.9961, 0.9962, 0.9963, 0.9964],
[0.9965, 0.9966, 0.9967, 0.9968, 0.9969, 0.997, 0.9971, 0.9972, 0.9973, 0.9974],
[0.9974, 0.9975, 0.9976, 0.9977, 0.9977, 0.9978, 0.9979, 0.9979, 0.998, 0.9981],
[0.9981, 0.9982, 0.9982, 0.9983, 0.9984, 0.9984, 0.9985, 0.9985, 0.9986, 0.9986],
[0.9987, 0.9987, 0.9987, 0.9988, 0.9988, 0.9989, 0.9989, 0.9989, 0.999, 0.999],
[0.999, 0.9991, 0.9991, 0.9991, 0.9992, 0.9992, 0.9992, 0.9992, 0.9993, 0.9993],
[0.9993, 0.9993, 0.9994, 0.9994, 0.9994, 0.9994, 0.9994, 0.9995, 0.9995, 0.9995],
[0.9995, 0.9995, 0.9995, 0.9996, 0.9996, 0.9996, 0.9996, 0.9996, 0.9996, 0.9997],
[0.9997, 0.9997, 0.9997, 0.9997, 0.9997, 0.9997, 0.9997, 0.9997, 0.9997, 0.9998],
];
46 changes: 46 additions & 0 deletions src/main/cdfInv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { log, sqrt } from './utils';

/**
* Inverse cumulative distribution function for Gaussian distribution.
*
* @param x The value in range (0, 1).
*/
export function cdfInv(x: number): number {
let q, r;

if (x <= 0) {
return -Infinity;
}

if (x >= 1) {
return Infinity;
}

if (x < 0.02425 || x > 0.97575) {
q = sqrt(-2 * log(x > 0.97575 ? 1 - x : x));

const c =
(((((-0.00778489400243029 * q + -0.322396458041136) * q + -2.40075827716184) * q + -2.54973253934373) * q +
4.37466414146497) *
q +
2.93816398269878) /
((((0.00778469570904146 * q + 0.32246712907004) * q + 2.445134137143) * q + 3.75440866190742) * q + 1);

return x > 0.97575 ? -c : c;
}

q = x - 0.5;
r = q * q;

return (
((((((-39.6968302866538 * r + 220.946098424521) * r + -275.928510446969) * r + 138.357751867269) * r +
-30.6647980661472) *
r +
2.50662827745924) *
q) /
(((((-54.4760987982241 * r + 161.585836858041) * r + -155.698979859887) * r + 66.8013118877197) * r +
-13.2806815528857) *
r +
1)
);
}
5 changes: 5 additions & 0 deletions src/main/decay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Mapper } from './types';

export function decay(fn: Mapper): Mapper {
return x => 1 - fn(x);
}
2 changes: 2 additions & 0 deletions src/main/easing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export function easeLog(q = 1): Mapper {
return x => (q === 0 ? x : log(x * (exp(q) - 1) + 1) / q);
}

export const easeLinear: Mapper = x => x;

/**
* @group Easing
*/
Expand Down
17 changes: 17 additions & 0 deletions src/main/gauss.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Mapper } from './types';
import { exp, PI, sqrt } from './utils';

/**
* Gaussian distribution.
*
* @param m Mean.
* @param d Standard deviation.
*/
export function gauss(m = 0, d = 1): Mapper {
const q = d * sqrt(2 * PI);

return x => {
x = (x - m) / d;
return exp(-0.5 * x * x) / q;
};
}
24 changes: 24 additions & 0 deletions src/main/gaussDist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { mapRange } from './mapRange';
import { cdfInv } from './cdfInv';

/**
* Distributes `n` numbers normally from `min` to `max`.
*
* @param n The number of numbers to distribute.
* @param a The minimum value.
* @param b The maximum value.
*/
export function gaussDist(n: number, a: number, b: number): number[] {
const arr = [];
const q = n + 1;

const gMin = cdfInv(1 / q);
const gMax = cdfInv(n / q);

const v = mapRange(gMin, gMax, a, b);

for (let i = 1; i < q; i++) {
arr.push(v(cdfInv(i / q)));
}
return arr;
}
5 changes: 5 additions & 0 deletions src/main/mapRange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Mapper } from './types';

export function mapRange(a1: number, b1: number, a2 = 0, b2 = 1): Mapper {
return x => a2 + ((b2 - a2) * (x - a1)) / (b1 - a1);
}
13 changes: 13 additions & 0 deletions src/test/cdf.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { cdf } from '../main/cdf';

describe('cdf', () => {
test('', () => {
expect(cdf(0, 1)(2)).toBe(0.9772);
expect(cdf(0, 1)(0)).toBe(0.5);
expect(cdf(4, 2)(-1)).toBe(0.006199999999999983);

expect(cdf(NaN, 0)(0)).toBe(NaN);
expect(cdf(0, NaN)(0)).toBe(NaN);
expect(cdf(0, 1)(NaN)).toBe(NaN);
});
});

0 comments on commit 7223d3d

Please sign in to comment.