-
-
Notifications
You must be signed in to change notification settings - Fork 456
GSoC 2024 ‐ Gunj Joshi
Hello 👋. I am Gunj Joshi, from Banswara, Rajasthan, India. I am a pre-final year undergraduate at Indian Institute of Information Technology, Kottayam, Kerala, India. It has been an year since I started my open-source journey, and believe me, it has been a great ride! Apart from stdlib, my interests include mathematics (which might be evident from my GSoC project) and sports.
The goals of my project included adding C implementations for various base special mathematical functions. Along with that, I also worked on adding single-precision variants for pre-existing functions. To achieve this, I followed certain reference implementations, some of which include:
The approach for developing a certain C implementation from the reference implementation to its stdlib equivalent included quite a few things, out of which some are as follows:
-
Using a relevant
napi
function, in order to match the function signature.For instance,
binomcoef
, has the following signature:double stdlib_base_binomcoef( const int64_t n, const int64_t k ) {
It takes in two
64-bit
integers, and gives a number of typedouble
as output.In order to achieve this, I worked on adding
LL_D
inmath/base/napi/binary
, which was as follows:napi_value stdlib_math_base_napi_ll_d( napi_env env, napi_callback_info info, double (*fcn)( double, int64_t, int64_t ) )
-
Replacing certain functions used in reference implementations with their stdlib equivalents. For instance, replacing
scalbn
inFreeBSD
implementation forrempio2
byldexp
, which is the appropriate stdlib equivalent. -
...and a few more tweaks to follow the conventions used in stdlib.
In order to develop single-precision implementations, certain conventions and methods were followed, some of which include:
-
Choosing an appropriate reference implementation.
-
Modifying tests to suit single-precision calculations, along with changing the range of the test fixtures.
For example, inmath/base/special/ln
, for testing subnormal inputs, we use the range as:x = range( 1.0e-309, stop = 1.0e-312, length = 500 );
But, in
math/base/special/lnf
, we use a smaller range, as it is only for single-precision values.x = range( 1.0e-39, stop = 1.40129846e-45, length = 500 );
-
Modifying the algorithm to align with single-precision arithmetic, whether it is casting expressions to
float32
after each arithmetic operation in JavaScript usingfloat64ToFloat32
, or using a suffixf
for every decimal number in C. For example,Double-precision in JavaScript:
var a = 2.5; var b = 1.5e3; var c = a + b;
Single-precision in JavaScript:
var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); var a = 2.5; var b = 1.5e3; var c = float64ToFloat32( float64ToFloat32( a ) + float64ToFloat32( b ) );
Double-precision in C:
double a = 2.5; double b = 1.5e3; double c = a + b;
Single-precision in C:
float a = 2.5f; float b = 1.5e3f; float c = a + b;
Along with these, some updates were also made in existing packages to make sure they are up to the mark.
I started out with adding the C implementations for various base special mathematical functions. I generated a topological sort using:
node ./lib/node_modules/@stdlib/_tools/pkgs/toposort/bin/cli $PWD/lib/node_modules/@stdlib/math/base
to identify all the dependencies, with the help of which I made this dependency diagram. With the help of this diagram, I was able to work on those packages first, which could unlock several others. For instance, most of the trigonometric functions were dependent on rempio2
, and thus it was among the first ones to be focused upon. After I completed most of the C implementations, I moved towards adding single-precision variants for the packages whose double-precision variants we already had.
In order to develop the C implementations or to add single-precision packages, I followed the steps which were explained in the previous section.
Everything that I did until now can be categorized in four major categories:
- Adding C implementations for various base special mathematical functions.
- Adding single-precision variants of pre-existing functions.
- Adding new packages.
- Various other maintenance work.
Let us have an overview for each one of them:
- feat: add C implementation for
math/base/special/bessely0
- feat: add C implementation for
math/base/special/besselj0
- feat: add C implementation for
math/base/special/binomcoefln
- feat: add C implementation for
math/base/special/trigamma
- feat: add C implementation for
math/base/special/betaln
- feat: add C implementation for
math/base/special/gamma1pm1
- feat: add C implementation for
math/base/special/factorialln
- feat: add C implementation for
math/base/special/binomcoef
- feat: add C implementation for
math/base/special/sinc
- feat: add C implementation for
math/base/special/fresnel
- feat: add C implementation for
math/base/special/sincospi
- feat: add C implementation for
math/base/special/fresnelc
- feat: add C implementation for
math/base/special/besselj1
- feat: add C implementation for
math/base/special/fresnels
- feat!: add C implementation for
math/base/special/truncsd
- feat: add C implementation for
math/base/special/truncb
- feat: add C implementation for
math/base/special/gamma-delta-ratio
- feat: add C implementation for
math/base/special/powm1
- feat: add C implementation for
math/base/special/binet
- feat: add C implementation for
math/base/special/cosm1
- feat: add C implementation for
math/base/special/sincos
- feat: add C implementation for
math/base/special/gammaln
- feat!: add C implementation for
math/base/special/ceilsd
- feat: add C implementation for
math/base/special/ceilb
- feat: add C implementation for
math/base/special/ceil10
- feat: add C implementation for
math/base/special/floorb
- feat: add C implementation for
math/base/special/floor10
- feat: add C implementation for
math/base/special/factorial
- feat: add C implementation for
math/base/special/cospi
- feat: add C implementation for
math/base/special/sinpi
- feat: add C implementation for
math/base/special/floorsd
- feat: add C implementation for
math/base/special/ceil2
- feat: add C implementation for
math/base/special/truncn
- feat: add C implementation for
math/base/special/roundb
- feat: add C implementation for
math/base/special/round10
- feat: add C implementation for
math/base/special/round2
- feat: add C implementation for
math/base/special/digamma
- feat: add C implementation for
math/base/special/beta
- feat: add C implementation for
math/base/special/gamma
- feat: add C implementation for
math/base/special/floor2
- feat: add C implementation for
math/base/special/trunc10
- feat: add C implementation for
math/base/special/cotd
- feat: add C implementation for
math/base/special/trunc2
- feat: add C implementation for
math/base/special/tand
- feat: add C implementation for
math/base/special/havercos
- feat: add C implementation for
math/base/special/haversin
- feat: add C implementation for
math/base/special/secd
- feat: add C implementation for
math/base/special/versin
- feat: add C implementation for
math/base/special/vercos
- feat: add C implementation for
math/base/special/cosd
- feat: add C implementation for
math/base/special/hacovercos
- feat: add C implementation for
math/base/special/hacoversin
- feat: add C implementation for
math/base/special/cscd
- feat: add C implementation for
math/base/special/covercos
- feat: add C implementation for
math/base/special/cot
- feat: add C implementation for
math/base/special/tan
- feat: add C implementation for
math/base/special/csc
- feat: add C implementation for
math/base/special/coversin
- feat: add C implementation for
math/base/special/cos
- feat: add C implementation for
math/base/special/sin
- feat: add C implementation for
math/base/special/spence
- feat: add C implementation for
math/base/special/rempio2
- feat: add C implementation for
math/base/special/exp2
- feat: add C implementation for
math/base/special/lcm
- feat: add C implementation for
math/base/special/fibonacci-index
- feat: add C implementation for
math/base/special/gamma-lanczos-sum-expg-scaled
- feat: add C implementation for
math/base/special/modf
- feat: add C implementation for
math/base/special/fast/pow-int
- feat: add C implementation for
math/base/special/fast/hypot
- feat: add C implementation for
math/base/special/fast/acosh
- feat: add C implementation for
math/base/special/fast/abs
- feat: add C implementation for
math/base/special/boxcox1p
- feat: add C implementation for
math/base/special/asecd
- feat: add C implementation for
math/base/special/acotd
- feat: add C implementation for
math/base/special/acosd
- feat: add C implementation for
math/base/special/boxcox
- feat: add C implementation for
math/base/special/bernoulli
- feat: add C implementation for
math/base/special/gammasgn
- feat: add C implementation for
math/base/special/gamma-lanczos-sum
- feat: add C implementation for
math/base/special/csch
- feat: add C implementation for
math/base/special/negafibonacci
- feat: add C implementation for
math/base/assert/is-nonnegative-integer
- feat: add C implementation for
math/base/special/ellipe
- feat: add C implementation for
math/base/special/riemann-zeta
- feat: add
math/base/assert/is-integerf
- feat: add
math/base/special/roundf
- feat: add
math/base/special/lnf
- feat: add
math/base/special/asecdf
- feat: add
math/base/special/rcbrtf
- feat: add
math/base/special/acscdf
- feat: add
math/base/special/asindf
- feat: add
math/base/special/rad2degf
- feat: add
math/base/special/asecf
- feat: add
math/base/special/acotf
- feat: add
math/base/special/acscf
- feat: add
math/base/special/acosf
- feat: add
math/base/special/atanf
- feat: add
math/base/special/asinf
- feat: add
math/base/special/minf
- feat: add
math/base/special/maxf
- feat: add
math/base/special/xlogyf
- feat: add
math/base/special/logf
- feat: add
math/base/special/ldexpf
- feat: add
math/base/special/acotdf
- feat: add
F_I
inmath/base/napi/unary
- feat: add
constants/float32/min-base2-exponent-subnormal
- feat: add
constants/float32/max-base2-exponent-subnormal
- feat: add
constants/float32/max-base2-exponent
- feat: add
LL_D
inmath/base/napi/binary
- feat: add
constants/float64/max-safe-nth-factorial
- feat: add
math/base/special/fmod
- feat: add a function for
dii_d
inmath/base/napi/ternary
- feat: add
constants/float32/phi
- feat: add
math/base/special/kernel-log1p
- feat: add
constants/float32/two-pi
- feat: add
constants/float32/fourth-pi
- feat: add
constants/float32/pi
- feat: add
constants/float32/half-pi
- feat: add
assert/is-well-formed-string
- feat: add
assert/is-negative-finite
- feat: add
constants/float32/max-safe-nth-factorial
- docs: update function description in
math/base/special/log
- fix: correct include directory name for
constants/float32/max-base2-exponent-subnormal
- fix: correct include directory name for
constants/float32/max-base2-exponent
- fix: correct include directory name for constants/float32/min-base2-exponent-subnormal
- docs: add comment, revert to previous tolerance in math/base/special/factorialln
- feat!: fix function name and update docs
- bench: remove irrelevant benchmark, update
boost
link inmath/base/special/gamma-delta-ratio
- docs: compare
n
withinteger
, not adouble
inmath/base/special/binomcoefln
- docs: update function description comments in
math/base/special/betaln
- docs: update license header and remove
stdlib
include inmath/base/special/trigamma
- docs: update license header in
math/base/special/gamma1pm1
- bench: update sample value in
math/base/assert/is-integer
- bench: use
float
instead ofdouble
in benchmarks formath/base/special/truncf
- docs: update comment to use 8 bits in
constants/float32/max-base2-exponent-subnormal
- refactor: use
int64_t
, check last bit, cast todouble
inmath/base/special/binomcoef
- docs: remove comments, set
isNegative
touint8_t
inmath/base/special/gammaln
- docs: add missing
stdint
includes in examples inmath/base/napi/binary
- docs: use native in
benchmark.native.js
inmath/base/special/gcd
- refactor: correct return value in math/base/special/sincos
- test: add missing tests, return
NaN
inmath/base/special/powm1
- style: correct spacing and return format in
math/base/special/fresnel
- docs: remove
stdint
include, return Float64Array
inmath/base/special/sincospi
- docs: remove unused include from example in
math/base/special/gamma/README.md
- refactor: use
max-safe-nth-factorial
package inmath/base/special/factorial
- docs: add
@private
tag inmath/base/special/sincos/lib/native.js
- docs: use correct comments for variables in
math/base/special/cosm1/test
- refactor: perform explicit cast
- test: fix tests for native implementation in
math/base/special/ceilsd
- refactor: remove extra
if
block, useb
instead of base inmath/base/special/floorsd
- fix: remove unused include in
math/base/special/factorial
- docs: use correct notes in
math/base/special/cospi
function descriptions - refactor: make base argument compulsory in
math/base/special/floorsd
- test: add tests for negative values in
math/base/special/fmod
- docs: use correct function name in
math/base/special/gamma-lanczos-sum-expg-scaled/README.md
- docs: use correct function name in
math/base/special/gamma-lanczos-sum/README.md
- docs: update
boost
version inmath/base/special/digamma
- refactor: use stdlib equivalent of
pow
inmath/base/special/roundn
- docs: add missing
@private
inmath/base/special/round/lib/native.js
- docs: use correct function name for
math/base/special/gamma_lanczos_sum
- test: add missing test for
math/base/special/cotd
- test: add missing tests for
math/base/special/cosd
- test: add missing tests for
math/base/special/tand
- docs: use correct function name in example in
math/base/special/hacoversin
- docs: use descriptive variable names for
math/base/special/sin
- docs: use significand mask in
math/base/special/rempio2
- docs: remove long comment from
math/base/special/coversin
- refactor: reduce tolerance, correct castings for
math/base/special/lnf
- refactor: use constant packages, remove
stdint
- docs: style corrections for
math/base/special/lcm
- refactor: use signed integers for
math/base/special/log2
, as perFreeBSD
- refactor: use signed integers for
math/base/special/log10
, as perFreeBSD
- refactor: update
math/base/special/log10
to followFreeBSD
version12.2.0
- refactor: update
math/base/special/rcbrt
- docs: fix example return value in
math/base/special/rcbrt
- refactor: update
math/base/special/log10
tofreeBSD
version12.2.0
- refactor: update
math/base/special/log2
to followFreeBSD
version12.2.0
- refactor: decrease tolerance and clean-up
math/base/special/asind
- refactor: generated fixtures using
asec
, updatedpackage.json
- fix: correctly handle signed zeroes in
math/base/special/atanf
- fix: corrected include directory name for
constants/float32/half-pi
- refactor: add support for ratios evaluating as
infinity
inmath/base/tools/evalrational-compile-c
- refactor: update
blas/ext/base/sapxsum
to follow current project conventions - fix: remove invalid examples in
native.js
forstdlib/math/base/special/fibonacci
- chore: added message for successful initialization
- refactor: use
stdlib_base_fmod
instead of built-in inmath/base/special/gcd
- refactor: use stdlib
fmod
andDDD_D
napi
function inmath/base/special/wrap
- refactor: use stdlib equivalent instead of built-in, fix indentation in
math/base/special/ldexp
As of now, except a few, most of the base special mathematical functions have their C implementations. The single-precision variants for some of them have also been developed.
Some of the packages have yet to get their C implementations. Also, the single-precision implementations of some of them also remains.
This tracking issue lists every package, indicating what has been already done and what remains.
Apart from these, some automation and scaffolding work also waits for getting started.
Hopefully, I would be continuing all this (and much more) even after the GSoC program ends!
Indeed, there were some challenges, but also a lot of lessons that I learned from them. Challenges such as replicating the exact workflow of the reference implementations, adjusting tolerance levels, and checking the intermediate values at every step when the intended results didn't came always had my back. Along with that, some minor mistakes always found their way into my PRs.
But all this changed with time. Today, when I look back at my first-ever PR to stdlib, I realize that I've came a long way in a few months. I believe this was one of the most important lessons that I learned. I didn't know much about the working of stdlib, just as any other new contributor. However, being consistent and always learning from past mistakes always helps!
All of this would not have been possible without project mentors, Athan Reines and Philipp Burckhardt. The journey that I talked about, when I was a new contributor, and now, that I have made some progress - credits go to both of them as well. Whether it was explaining things and concepts that I was confused about, or patiently listening to my questions and queries every time, they always had my back. Thanks to Pranav Goswami as well, for helping out.
Overall, I had a wonderful experience, and would be more than happy to keep working for the development of stdlib. Thanks!