xddxdd/nix-math
{ "createdAt": "2023-09-05T04:09:17Z", "defaultBranch": "master", "description": "Experimental mathematical library in pure Nix, using no external library.", "fullName": "xddxdd/nix-math", "homepage": "", "language": "Nix", "name": "nix-math", "pushedAt": "2025-11-24T21:26:27Z", "stargazersCount": 40, "topics": [], "updatedAt": "2025-09-01T13:09:16Z", "url": "https://github.com/xddxdd/nix-math"}nix-math
Section titled “nix-math”Experimental mathematical library in pure Nix, using no external library.
- Because I can.
- Because I want to approximate the network latency between my servers using their latitudes/longitudes. No, I don’t want to run
traceroutebetween my servers every now and then.
Limitations
Section titled “Limitations”-
Nix does not provide some lower level operations, such as bit operation on floating point numbers. This leads to computation inaccuracies, and it’s impossible to get the exact same result as GLibC or
numpy, even if I have their code as reference. For functions where getting exact same results are impossible, I target for error within 0.0001%. -
This library does not support these features. ALthough I added exceptions for some situations, this is by no means comprehensive. Please consider these as undefined behaviors, and submit an issue when you encounter one.
- Floating point infinity (+inf, -inf)
- NaN
- Floating power overflow and underflow
- Operations where the value is extremely small (around
1e-38) or extremely large (around1e38) - Imaginary numbers
{ inputs = { nix-math.url = "github:xddxdd/nix-math"; };
outputs = inputs: let math = inputs.nix-math.lib.math; in{ value = math.sin (math.deg2rad 45); };}Provided functions
Section titled “Provided functions”abs [x]: Absolute value ofxarange [min] [max] [step]: Create a list of numbers frommin(inclusive) tomax(exclusive), addingstepeach time.arange2 [min] [max] [step]: Same asarange, but includesmaxas well.atan [x]: Arctangent function. Returns radian.cos [x]: Trigonometric function. Takes radian as input.deg2rad [x]: Degrees to radian.div [a] [b]: Divideabybwith no remainder.exp [x]: Exponential function. Returnse^x.fabs [x]: Absolute value ofxfactorial [x]: Returns factorial ofx.xis an integer,x >= 0.haversine [lat1] [lon1] [lat2] [lon2]: Returns distance of two points on Earth for the given latitude/longitude. Uses 6371km as Earth radius.haversine' [radius] [lat1] [lon1] [lat2] [lon2]: Returns distance of two points on sphere for the given radius/latitude/longitude.int [x]: Integer part ofx.ln [x]: Logarithmetic function. Returnslog_e x.log [a] [b]: Logarithmetic function. Returnslog_a b.log10 [x]: Logarithmetic function. Returnslog_10 x.log2 [x]: Logarithmetic function. Returnslog_2 x.mod [a] [b]: Modulos of dividingabyb.pow [a] [b]: Returnsato the power ofb. Now supports floating pointb.round [x]: Roundxto the nearest integer. For input ending with.5, will round to the nearest even number (same logic asnp.round).sin [x]: Trigonometric function. Takes radian as input.sqrt [x]: Square root ofx.x >= 0.tan [x]: Trigonometric function. Takes radian as input.
Implementation Details
Section titled “Implementation Details”sinfunction is implemented with its Taylor series: forx >= 0,sin(x) = x - x^3/3! + x^5/5!. Calculation is repeated until the next value in series is less than epsilon (1e-10).cosiscos(x) = sin (pi/2 - x).tanistan(x) = sin x / cos x.- For
sin,cosandtan, result error is within 0.0001% as checked by unit test.
- For
atanis implemented by approximating to polynomial function. This is faster and more accurate than using its Taylor series, because its Taylor series does not converge fast enough, and may cause “max-call-depth exceeded” error.- For
atan, result error is within 0.0001%.
- For
sqrtis implemented with Newtonian method. Calculation is repeated until the next value is less than epsilon (1e-10).- For
sqrt, result error is within1e-10.
- For
expis implemented by approximating to polynomial function. This is faster and more accurate than using its Taylor series, because its Taylor series does not converge fast enough, and may cause “max-call-depth exceeded” error.- For
exp, result error is within 0.0001%.
- For
logis implemented with its Taylor series:- For
1 <= x <= 1.9,log(x) = (x-1)/1 - (x-1)^2/2 + (x-1)^3/3. Calculation is repeated until the next value in series is less than epsilon (1e-10). - For
x >= 1.9,log(x) = 2 * log(sqrt(x)) - For
0 < x < 1,log(x) = -log(1/x) - Although the Taylor series applies to
0 <= x <= 2, calculation outside1 <= x <= 1.9is very slow and may cause max-call-depth exceeded error. - For
log, result error is within 0.0001%.
- For
powispow(x, y) = exp(y * log(x)).lnisln(x, y) = log(y) / log(x).log2islog2(x) = log(x) / log(2).log10islog10(x) = log(x) / log(10).- For
pow,ln,log2,log10, result error is within 0.0001%.
- For
haversineis implemented based on https://stackoverflow.com/a/27943.
Unit test
Section titled “Unit test”Unit test is defined in tests/test.py. It invokes tests/test.nix which tests the mathematical functions with a range of inputs, and compares the output to the same function from Numpy.
To run the unit test:
nix run .License
Section titled “License”MIT.