From 4a88acae66c8e4dd45ede015d90a782698473dc5 Mon Sep 17 00:00:00 2001 From: Roman Galochkin Date: Tue, 25 Feb 2020 13:08:16 +0300 Subject: [PATCH] Adds integral function --- __tests__/CDF__Test.re | 11 +++++++++++ src/utility/lib/CDF.re | 15 ++++++++++++++- src/utility/lib/continuousDistribution.spec.js | 16 ++++++++-------- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/__tests__/CDF__Test.re b/__tests__/CDF__Test.re index f5605b68..cfe74694 100644 --- a/__tests__/CDF__Test.re +++ b/__tests__/CDF__Test.re @@ -165,4 +165,15 @@ describe("CDF", () => { expect(xs2[2]) |> toBe(70.) }); }); + + describe("integral", () => { + module Dist = + CDF.Make({ + let shape = + CDF.order({xs: [|0., 1., 2., 4.|], ys: [|0.0, 1.0, 2.0, 2.0|]}); + }); + test("with regular inputs", () => { + expect(Dist.integral()) |> toBe(6.) + }); + }); }); diff --git a/src/utility/lib/CDF.re b/src/utility/lib/CDF.re index b5f9221e..cbfefa6c 100644 --- a/src/utility/lib/CDF.re +++ b/src/utility/lib/CDF.re @@ -90,5 +90,18 @@ module Make = (Config: Config) => { let sampleSingle = (): float => Js.Math.random() |> findY; let sample = (size: int): array(float) => Belt.Array.makeBy(size, i => sampleSingle()); - 1; + let integral = () => { + Belt.Array.reduceWithIndex(ys, 0., (integral, y, i) => { + switch (i) { + | 0 => integral + | _ => + let thisY = y; + let lastY = get(ys, i - 1); + let thisX = get(xs, i); + let lastX = get(xs, i - 1); + let sectionInterval = (thisY +. lastY) /. 2. *. (thisX -. lastX); + integral +. sectionInterval; + } + }); + }; }; diff --git a/src/utility/lib/continuousDistribution.spec.js b/src/utility/lib/continuousDistribution.spec.js index 75831fb5..114caf58 100644 --- a/src/utility/lib/continuousDistribution.spec.js +++ b/src/utility/lib/continuousDistribution.spec.js @@ -66,45 +66,45 @@ describe('ContinuousDistribution Class', () => { describe('integral()', () => { it('with regular inputs', () => { - const xs = [0,1,2,4]; + const xs = [0, 1, 2, 4]; const ys = [0.0, 1.0, 2.0, 2.0]; const cdf = new ContinuousDistribution(xs, ys); const integral = cdf.integral(); expect(integral).toEqual(6); }); it('with an infinity', () => { - const xs = [0,1,2,4]; + const xs = [0, 1, 2, 4]; const ys = [0.0, 1.0, Infinity, 2.0]; const cdf = new ContinuousDistribution(xs, ys); const integral = cdf.integral(); expect(integral).toEqual(Infinity); }); it('with negative infinity', () => { - const xs = [0,1,2,4]; + const xs = [0, 1, 2, 4]; const ys = [0.0, 1.0, -Infinity, 2.0]; const cdf = new ContinuousDistribution(xs, ys); const integral = cdf.integral(); expect(integral).toEqual(-Infinity); }); it('with both positive and negative infinities', () => { - const xs = [0,1,2,4]; + const xs = [0, 1, 2, 4]; const ys = [0.0, 1.0, -Infinity, Infinity]; const cdf = new ContinuousDistribution(xs, ys); const integral = cdf.integral(); expect(integral).toEqual(NaN); }); it('with a NaN and filterOutNaNs set to false', () => { - const xs = [0,1,2,4]; + const xs = [0, 1, 2, 4]; const ys = [0.0, 1.0, 2.0, NaN]; const cdf = new ContinuousDistribution(xs, ys); - const integral = cdf.integral({filterOutNaNs: false}); + const integral = cdf.integral({ filterOutNaNs: false }); expect(integral).toEqual(NaN); }); it('with a NaN and filterOutNaNs set to true', () => { - const xs = [0,1,2,4]; + const xs = [0, 1, 2, 4]; const ys = [0.0, 1.0, 2.0, NaN]; const cdf = new ContinuousDistribution(xs, ys); - const integral = cdf.integral({filterOutNaNs: true}); + const integral = cdf.integral({ filterOutNaNs: true }); expect(integral).toEqual(2); }); })