From 878dddea775763af1f6e62a794113bde563aaff0 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Thu, 29 Feb 2024 22:06:33 +0800 Subject: [PATCH] bahaghari/lib: init math subset In preparation for implementing the colorspace library subset. --- subprojects/bahaghari/lib/default.nix | 4 +- subprojects/bahaghari/lib/math.nix | 108 ++++++++++++++++++ subprojects/bahaghari/lib/trivial.nix | 21 ---- subprojects/bahaghari/tests/lib/default.nix | 1 + subprojects/bahaghari/tests/lib/math.nix | 58 ++++++++++ .../bahaghari/tests/lib/trivial/default.nix | 5 - 6 files changed, 170 insertions(+), 27 deletions(-) create mode 100644 subprojects/bahaghari/lib/math.nix create mode 100644 subprojects/bahaghari/tests/lib/math.nix diff --git a/subprojects/bahaghari/lib/default.nix b/subprojects/bahaghari/lib/default.nix index d831b430..24e589a7 100644 --- a/subprojects/bahaghari/lib/default.nix +++ b/subprojects/bahaghari/lib/default.nix @@ -15,13 +15,15 @@ pkgs.lib.makeExtensible { trivial = callLibs ./trivial.nix; hex = callLibs ./hex.nix; + math = callLibs ./math.nix; # Dedicated module sets are not supposed to have any of its functions as # a top-level attribute. tinted-theming = callLibs ./tinted-theming.nix; inherit (self.trivial) importYAML toYAML toBaseDigitsWithGlyphs - generateGlyphSet generateConversionTable generateBaseDigitType pow; + generateGlyphSet generateConversionTable generateBaseDigitType; inherit (self.hex) isHexString; + inherit (self.math) abs pow percentage; }) diff --git a/subprojects/bahaghari/lib/math.nix b/subprojects/bahaghari/lib/math.nix new file mode 100644 index 00000000..a0fd6d84 --- /dev/null +++ b/subprojects/bahaghari/lib/math.nix @@ -0,0 +1,108 @@ +# A little math utility for common operations. Don't expect any high-level +# mathematical operations nor godly optimizations expected from a typical math +# library, it's just basic high school type of shit in all aspects. +{ pkgs, lib }: + +rec { + /* Returns the absolute value of the given number. + + Type: abs :: Int -> Int + + Example: + abs -4 + => 4 + + abs (1 / 5) + => 0.2 + */ + abs = number: + if number < 0 then -(number) else number; + + /* Exponentiates the given base with the exponent. + + Type: pow :: Int -> Int -> Int + + Example: + pow 2 3 + => 8 + + pow 6 4 + => 1296 + */ + pow = base: exponent: + # I'll just make this as a tail recursive function instead. + let + absValue = abs exponent; + iter = product: counter: max-count: + if counter > max-count + then product + else iter (product * base) (counter + 1) max-count; + value = iter 1 1 absValue; + in + if exponent < 0 then (1 / value) else value; + + /* Given a number, make it grow by given amount of percentage. + A value of 100 should make the number doubled. + + Type: grow :: Number -> Number -> Number + + Example: + grow 4 50.0 + => 2 + + grow 55.5 100 + => 111 + */ + grow = number: value: + number + (percentage number value); + + /* Given a number, make it smaller by given amount of percentage. + A value of 100 should zero the number. + + Type: shrink :: Number -> Number -> Number + + Example: + shrink 4 50.0 + => 2 + + shrink 55.5 100 + => 0 + */ + shrink = number: value: + number - (percentage number value); + + /* Given a number, return its value by the given percentage. + + Type: percentage :: Number -> Number -> Number + + Example: + percentage 4 100.0 + => 4 + + percentage 5 200.0 + => 10 + */ + percentage = number: value: + number / (100.0 / value); + + /* Given a number, round up (or down) its number to the nearest integer. + + Type: round :: Number -> Number + + Example: + round 3.5 + => 4 + + round 2.3 + => 2 + + round 2.7 + => 3 + */ + round = number: + let + number' = builtins.floor number; + difference = number - number'; + in + if difference >= 0.5 then (number' + 1) else number'; +} diff --git a/subprojects/bahaghari/lib/trivial.nix b/subprojects/bahaghari/lib/trivial.nix index 9baba075..fc2c67de 100644 --- a/subprojects/bahaghari/lib/trivial.nix +++ b/subprojects/bahaghari/lib/trivial.nix @@ -142,25 +142,4 @@ rec { in pkgs.lib.foldl (sum: v: sum + v) 0 convertDigitToDec; }; - - /* Exponentiates the given base with the exponent. - - Type: pow :: Int -> Int -> Int - - Example: - pow 2 3 - => 8 - - pow 6 4 - => 1296 - */ - pow = base: exponent: - # I'll just make this linearly recursive instead. - let - iter = product: counter: max-count: - if counter > max-count - then product - else iter (product * base) (counter + 1) max-count; - in - iter 1 1 exponent; } diff --git a/subprojects/bahaghari/tests/lib/default.nix b/subprojects/bahaghari/tests/lib/default.nix index 54c06c4c..9d5f91df 100644 --- a/subprojects/bahaghari/tests/lib/default.nix +++ b/subprojects/bahaghari/tests/lib/default.nix @@ -5,6 +5,7 @@ let in { hex = import ./hex.nix { inherit pkgs lib; }; + math = import ./math.nix { inherit pkgs lib; }; trivial = import ./trivial { inherit pkgs lib; }; tinted-theming = import ./tinted-theming { inherit pkgs lib; }; } diff --git a/subprojects/bahaghari/tests/lib/math.nix b/subprojects/bahaghari/tests/lib/math.nix new file mode 100644 index 00000000..f8e137c4 --- /dev/null +++ b/subprojects/bahaghari/tests/lib/math.nix @@ -0,0 +1,58 @@ +{ pkgs, lib }: + +pkgs.lib.runTests { + testMathPowPositive = { + expr = lib.math.pow 2 8; + expected = 256; + }; + + testMathPowNegative = { + expr = lib.math.pow 2.0 (-1); + expected = 0.5; + }; + + testMathPowZero = { + expr = lib.math.pow 34 0; + expected = 1; + }; + + testMathAbsoluteValue = { + expr = lib.math.abs 5493; + expected = 5493; + }; + + testMathAbsoluteValue2 = { + expr = lib.math.abs (-435354); + expected = 435354; + }; + + testMathPercentage = { + expr = lib.math.percentage 100 50; + expected = 50; + }; + + testMathPercentage2 = { + expr = lib.math.percentage 453 13; + expected = 58.89; + }; + + testMathGrow = { + expr = lib.math.grow 12 500; + expected = 72; + }; + + testMathGrow2 = { + expr = lib.math.grow 5.5 55.5; + expected = 8.5525; + }; + + testMathRoundDown = { + expr = lib.math.round 2.3; + expected = 2; + }; + + testMathRoundUp = { + expr = lib.math.round 2.8; + expected = 3; + }; +} diff --git a/subprojects/bahaghari/tests/lib/trivial/default.nix b/subprojects/bahaghari/tests/lib/trivial/default.nix index e6c3be4e..97b37d2f 100644 --- a/subprojects/bahaghari/tests/lib/trivial/default.nix +++ b/subprojects/bahaghari/tests/lib/trivial/default.nix @@ -210,9 +210,4 @@ pkgs.lib.runTests { expr = lib.trivial.toYAML { } { hello = "there"; }; expected = "{\"hello\":\"there\"}"; }; - - testPow = { - expr = lib.trivial.pow 2 8; - expected = 256; - }; }