site-libsoc/Server/public/js/libraries/mathTools.js

146 lines
3.4 KiB
JavaScript
Raw Permalink Normal View History

2023-06-15 01:41:54 +07:00
// Broadcast array on array
export function bAr(fun,ar1,ar2) {
var result = new Array(ar1.length)
for (var i = 0;i<ar1.length;i++) {
result[i] = fun(ar1[i],ar2[i])
}
return(result)
}
// Broadcast array on a number
export function b(fun,ar1,val) {
var result = new Array(ar1.length)
for (var i = 0;i<ar1.length;i++) {
result[i] = fun(ar1[i],val)
}
return(result)
}
// Broadcast array on a function
export function bFun(fun,ar1) {
var result = new Array(ar1.length)
for (var i = 0;i<ar1.length;i++) {
result[i] = fun(ar1[i])
}
return(result)
}
export function multiply(num1, num2) {
let result = num1 * num2;
return result;
}
export function sum(ar) {
return ar.reduce((a, b) => a + b, 0)
}
export function prod(ar) {
return ar.reduce((a, b) => a * b, 1)
}
export function mean(ar) {
return ar.reduce((a, b) => a + b, 0)/ar.length
}
export function median(values){
if(values.length ===0) throw new Error("No inputs");
values.sort(function(a,b){
return a-b;
});
var half = Math.floor(values.length / 2);
if (values.length % 2)
return values[half];
return (values[half - 1] + values[half]) / 2.0;
}
export function range(start,end, step = start<end ? 1 : -1) {
var arr = []
if (step>0) {
for (var i = start; i <= end; i += step) {
arr.push(i)
}
}
else {
for (var i = start; i >= end; i += step) {
arr.push(i)
}
}
return arr
}
export function numericallyIntegrate(f, a, b, dx) {
// calculate the number of trapezoids
let n = (b - a) / dx
// define the variable for area
let Area = 0
//loop to calculate the area of each trapezoid and sum.
for (let i = 1; i <= n; i++) {
//the x locations of the left and right side of each trapezpoid
let x0 = a + (i-1)*dx
let x1 = a + i*dx
// the area of each trapezoid
let Ai = dx * (f(x0) + f(x1))/ 2.
// cumulatively sum the areas
Area = Area + Ai
}
return Area
}
const randomNormals = () => {
let u1 = 0, u2 = 0;
//Convert [0,1) to (0,1)
while (u1 === 0) u1 = Math.random();
while (u2 === 0) u2 = Math.random();
const R = Math.sqrt(-2.0 * Math.log(u1));
const Θ = 2.0 * Math.PI * u2;
return [R * Math.cos(Θ), R * Math.sin(Θ)];
};
export function randomSkewNormal(ξ, ω, α = 0) {
const [u0, v] = randomNormals();
if (α === 0) {
return ξ + ω * u0;
}
const 𝛿 = α / Math.sqrt(1 + α * α);
const u1 = 𝛿 * u0 + Math.sqrt(1 - 𝛿 * 𝛿) * v;
const z = u0 >= 0 ? u1 : -u1;
return ξ + ω * z;
};
export function percentile(arr, p) {
arr.sort(function(a,b){
return a-b;
});
if (arr.length === 0) return 0;
if (typeof p !== 'number') throw new TypeError('p must be a number');
if (p <= 0) return arr[0];
if (p >= 1) return arr[arr.length - 1];
var index = (arr.length - 1) * p,
lower = Math.floor(index),
upper = lower + 1,
weight = index % 1;
if (upper >= arr.length) return arr[lower];
return arr[lower] * (1 - weight) + arr[upper] * weight;
}
export function smooth(ar,window) {
let windowHalf = window/2
let windowHalf1 = Math.floor(windowHalf)
let windowHalf2 = Math.ceil(windowHalf)
for (let i=windowHalf1;i<ar.length-windowHalf2;i++) {
ar[i] = mean(ar.slice(i-windowHalf1,i+windowHalf2))
}
}