Skip to content

[RFC]: develop C and Javascript implementation for base special mathematical functions #188

@nirmaljb

Description

@nirmaljb

Full name

Nirmal Jyoti Biswas

University status

Yes

University name

Pondicherry University, Pondicherry

University program

Bachelor of Technology in Computer Science and Engineering

Expected graduation

May, 2028

Short biography

I am a second-year B.Tech Computer Science student at Pondicherry University, currently completing my sophomore year and entering my junior year by the time the program begins. I maintain a strong academic record and have received the highest grade in courses such as Data Structures and Algorithms.

I have been programming since middle school, where I spent time building small applications, automation scripts, and experimenting with simple programs. My first exposure to open source was through Google Code-In, where I completed few tasks and received a participation badge and merchandise.

I have also worked with a professor to develop a full-stack hall management system intended for use across the university, designed to handle large concurrent request loads. I was primarily responsible for the backend and infrastructure, using TypeScript and Hono. In addition, I have participated in and won multiple university hackathons and was awarded Best Model at the National Science Day event hosted by my university.

Technically, I am comfortable working with C/C++, JavaScript, TypeScript, and Python. My primary interests lie in backend systems, DevOps, and agentic AI systems, and I am currently exploring machine learning to better design and build such systems.

Timezone

Indian Standard Time ( IST ), UTC+05:30

Contact details

email: nirmaljyotib@gmail.com, github: nirmaljb, x: nirmalnjb

Platform

Mac

Editor

My preferred code editor is VSCode. I find it very productive for large codebases due to its strong support for JavaScript and TypeScript tooling, good keyboard shortcuts, integrated debugging, and extensions that make navigating repositories easier.

I also make regular use of its built-in Git integration, terminal, and extensions such as ESLint and Prettier, which help maintain consistent code formatting and quickly catch issues during development.

Programming experience

My first line of code was a small batch script in 5th grade that printed “You’ve been hacked!” on the screen. It did nothing useful, but seeing something I typed actually run was enough to hook me into programming.

For a while, I simply built whatever seemed interesting, such as small landing pages, todo apps, Java pattern programs, a YouTube statistics scraper, and experiments analysing datasets like the Titanic dataset. Around that time, I discovered Google Code-In with only a few hours left before the program ended. I managed to submit a few tasks, and sometime later, unexpectedly received Google Code-In merchandise in the mail. That became an important memory for me.

After finishing high school, I began studying software development more seriously and focused on backend and full-stack systems. During this time, I worked with technologies such as JavaScript/TypeScript, Node.js, MongoDB, PostgreSQL, Prisma, Hono, Cloudflare Workers, AWS, and GitHub CI/CD. I also started practising algorithmic problem solving on Codeforces and LeetCode using C++, which helped me develop a stronger intuition for time and space complexities.

Some projects that represent my work include:

  1. Cue — An AR glasses simulation designed as a cognitive prosthetic for dementia patients, integrating LLMs to provide contextual assistance. Built using TypeScript and Python.
  2. Hall Management System — A hall and room booking platform designed for Pondicherry University with a focus on handling high concurrency and large request volumes. I was responsible for the backend architecture, database design, and deployment using Hono, Prisma, PostgreSQL, and Cloudflare Workers.
  3. CampusGPT (ongoing) — A multi-agent AI system designed to analyse and interact with public data related to Pondicherry University using Next.js (TypeScript) and Python.

Over time, my interests have shifted from simply building applications to understanding how systems behave under scale, performance constraints, and numerical correctness, which naturally led me toward working with projects like stdlib.

JavaScript experience

Most of my programming experience has been in JavaScript, primarily through building web applications, APIs, and backend services. I regularly work with JavaScript, TypeScript and Python for server-side development, database interactions through ORMs, and deploying services on cloud platforms.

My favourite aspect of JavaScript is its ecosystem. While the language itself is relatively small, the surrounding tooling, libraries, and frameworks make it extremely productive for building real-world systems. Being able to work across frontend, backend, and infrastructure using the same language has been especially valuable in my projects.

My least favourite aspect is the limited support for numerical computing in the ecosystem. Compared to languages commonly used for scientific computing, JavaScript lacks a robust and standardised collection of well-tested numerical routines. This gap is one of the reasons I became interested in contributing to stdlib.

Node.js experience

I have extensive experience working with Node.js while building backend services and APIs. Much of my project work involves designing server-side systems that handle database interactions, authentication, and request processing. I have worked with ORMs and schema design, implemented authentication flows, and added production concerns such as rate limiting and request validation.

Beyond application logic, I have also worked with deployment and infrastructure around Node.js services. This includes containerizing applications with Docker, managing database connections, and running services on cloud infrastructure and Kubernetes-based environments.

C/Fortran experience

My Data Structures and Algorithms course was taught entirely in C, which gave me a good understanding of pointers, structures, and multidimensional arrays. Writing and debugging code in C helped me become comfortable with how data and memory are handled at a lower level.

I also solve algorithmic problems in C++ on platforms like LeetCode and Codeforces, which has helped me think more carefully about performance and memory.

I don’t have Fortran experience yet, but I’m open to learning it if needed.

Interest in stdlib

I still remember trying to do some basic data analysis in 7th grade using JavaScript. I wanted to plot graphs and analyze a small dataset, but after searching around, I realized most resources pointed to NumPy. That meant learning Python first, so I spent a few months taking a Python course. By the time I finished, I had forgotten a good part of the JavaScript I originally knew. That experience stayed with me and made me realize how fragmented numerical computing support on the web was.

While randomly scrolling through the last year GSoC organisations, I first came across stdlib, what stood out immediately was how approachable the project was. The issues were clearly labeled and easy to navigate, which made it straightforward to pick something up and start contributing. My first contribution was surprisingly smooth, and the maintainers were incredibly helpful and supportive, even when I made small mistakes along the way.

What interests me most about stdlib is its long-term vision. Building a comprehensive, well-tested numerical computing library for JavaScript something comparable in spirit to what NumPy provides for Python feels both important and exciting. Having such a foundation could significantly expand what is possible for scientific and statistical computing in the JavaScript ecosystem.

Version control

Yes

Contributions to stdlib

Merged Pull requests: Link

Open Pull requests:

Some of these functions are blocked, simply because they depend on external functions like expf. But tackling these functions felt worthy; they ended up teaching me everything that I need to know in order to handle any other special functions.

  1. Mathematics special functions: Link
  2. Distribution functions: Link
  3. NaN Incremental accumulators: Link
  4. Code Reviews: Reviews

stdlib showcase

The sole reason for needing to learn Python in my 7th grade was that there was not enough support for data analysis and numerical computing tools, and that is why I built a simulation of a bifurcation diagram. A simulation something that is paramount to science, medicine, economics, politics, sports, etc. A simulation is extremely crucial, but because of javascript lacking the support for numerical computing tools, Python took the lead and dominated the industry.

Why a bifurcation diagram exactly?

While going through past years' GSoC proposals for inspiration, Gunj Joshi's proposal struck me the most. It was simple a image transformation tool, which used stdlib math’s function to perform image transformation like rotate, blur, etc. The thing that struck me was how common the product is, something that we use from day to day, yet we often overlook the complexity behind it. Similarly how the water drops from a loose tap on a sink, which looks unsurprising and common, but the pattern of the drops might lead to but the pattern of the drops might lead to something far less ordinary; the edge of chaos itself.

Showcase
Functions used are: linspace, mean, variance, ln, abs

Goals

The goal is to implement the remaining missing functions in math/base/special and moving the package towards to using ulpdiff-based testing.

I've based my entire study on this Detailed Dependency spreadsheet: dependency

flowchart TD
    bessely1f["bessely1f"] --> besselj1f["besselj1f"]
    betaincf["betaincf"] --> betaf["betaf"]
    betaincf["betaincf"] --> gamma_delta_ratiof["gamma-delta-ratiof"]
    betaincf["betaincf"] --> gammaf["gammaf"]
    betaincf["betaincf"] --> gammaincf["gammaincf"]
    betaincf["betaincf"] --> gammalnf["gammalnf"]
    betaincf["betaincf"] --> kernel_betaincf["kernel-betaincf"]
    betaincinvf["betaincinvf"] --> betaf["betaf"]
    betaincinvf["betaincinvf"] --> betaincf["betaincf"]
    betaincinvf["betaincinvf"] --> gamma_delta_ratiof["gamma-delta-ratiof"]
    betaincinvf["betaincinvf"] --> gammaincinvf["gammaincinvf"]
    betaincinvf["betaincinvf"] --> kernel_betaincf["kernel-betaincf"]
    betaincinvf["betaincinvf"] --> kernel_betaincinvf["kernel-betaincinvf"]
    betalnf["betalnf"] --> gammaf["gammaf"]
    betalnf["betalnf"] --> gammalnf["gammalnf"]
    binomcoeflnf["binomcoeflnf"] --> betalnf["betalnf"]
    dirichlet_etaf["dirichlet-etaf"] --> riemann_zetaf["riemann-zetaf"]
    falling_factorialf["falling-factorialf"] --> gamma_delta_ratiof["gamma-delta-ratiof"]
    gamma1pm1f["gamma1pm1f"] --> gammaf["gammaf"]
    gamma_delta_ratiof["gamma-delta-ratiof"] --> gammaf["gammaf"]
    gammaincf["gammaincf"] --> gamma1pm1f["gamma1pm1f"]
    gammaincf["gammaincf"] --> gammaf["gammaf"]
    gammaincf["gammaincf"] --> gammalnf["gammalnf"]
    gammaincinvf["gammaincinvf"] --> gammaf["gammaf"]
    gammaincinvf["gammaincinvf"] --> gammaincf["gammaincf"]
    gammaincinvf["gammaincinvf"] --> gammalnf["gammalnf"]
    kernel_betaincf["kernel-betaincf"] --> betaf["betaf"]
    kernel_betaincf["kernel-betaincf"] --> gamma_delta_ratiof["gamma-delta-ratiof"]
    kernel_betaincf["kernel-betaincf"] --> gammaf["gammaf"]
    kernel_betaincf["kernel-betaincf"] --> gammaincf["gammaincf"]
    kernel_betaincf["kernel-betaincf"] --> gammalnf["gammalnf"]
    kernel_betaincinv["kernel-betaincinv"] --> kernel_betainc["kernel-betainc"]
    kernel_betaincinvf["kernel-betaincinvf"] --> betaf["betaf"]
    kernel_betaincinvf["kernel-betaincinvf"] --> betaincf["betaincf"]
    kernel_betaincinvf["kernel-betaincinvf"] --> gamma_delta_ratiof["gamma-delta-ratiof"]
    kernel_betaincinvf["kernel-betaincinvf"] --> gammaincinvf["gammaincinvf"]
    kernel_betaincinvf["kernel-betaincinvf"] --> kernel_betaincf["kernel-betaincf"]
    polygammaf["polygammaf"] --> gammalnf["gammalnf"]
    polygammaf["polygammaf"] --> riemann_zetaf["riemann-zetaf"]
    riemann_zetaf["riemann-zetaf"] --> gammaf["gammaf"]
    riemann_zetaf["riemann-zetaf"] --> gammalnf["gammalnf"]
    rising_factorialf["rising-factorialf"] --> falling_factorialf["falling-factorialf"]
    rising_factorialf["rising-factorialf"] --> gamma_delta_ratiof["gamma-delta-ratiof"]
Loading

This diagram shows the internal dependency structure for visual clarity (based on the dependency spreadsheet)

Core objective:

There are about 103 missing functions, out of which:

  1. Functions with no existing PRs: 47
  2. Functions with open PRs (but failing CI/CD): 10 (this may vary slightly)
  3. Functions with draft PRs: 16

A. Firstly, my primary focus would be to implement and complete these 47 functions, strictly following their numerical references for both implementation and test cases. This process will also help identify any inconsistencies or potential bugs in the existing double-precision implementations as well.

B. Secondly, all newly implemented functions will use ULP diff-based testing as the default testing methodology. For existing merged functions, ULP diff tests will be added where time permits, prioritizing functions in the gamma and beta families.

Additional objective:

  1. Review the functions that have an active PR with a failed status, followed by draft status and then passed status. This would include checking for implementation validity, code standards, test coverage, documentation, etc. And if needed and time persists, even a complete rework from scratch.
  2. Add tests to verify IEEE-754 compliance to applicable functions, as discussed in [issue #365](Add tests for IEEE 754-2019 compliance stdlib#365).
  3. Update implementations where upstream libraries have introduced bug fixes or improvements to their algorithms.

Why this project?

While implementing functions in the stats packages, I repeatedly came across implementations that were blocked because they depended on mathematical special functions such as betainc and gammaincinv.

Some of the functions are:

  1. [RFC]: Add C implementation for @stdlib/stats/base/dists/t/logcdf stdlib#3872 (depends on betainc)
  2. [RFC]: Add C implementation for @stdlib/stats/base/dists/negative-binomial/cdf stdlib#3760 (depends on betainc)
  3. [RFC]: Add C implementation for @stdlib/stats/base/dists/beta/cdf stdlib#3423 (depends on betainc)
  4. [RFC]: Add C implementation for @stdlib/stats/base/dists/negative-binomial/quantile stdlib#3767 (indirectly depends on betainc)
  5. [RFC]: Add C implementation for @stdlib/stats/base/dists/invgamma/quantile stdlib#3677 (depends on gammaincinv)
  6. [RFC]: Add C implementation for @stdlib/stats/base/dists/f/quantile stdlib#3600 (depends on kernel-betaincinv)

That naturally led me to explore the math/base/special functions and start working on removing some of these roadblocks. Through this process, I became aware of the massive internal dependency chain of the beta and gamma families. I've discussed it in the Zulip (#dev-questions > implementation of @stdlib/math/base/special/kernel-betainc) as well.

The functions are very heavy implementation and testing-wise, require a lot of time and are prone to mistakes, which is why there is not enough initiation for them. And that is what drove me to implement these foundational functions step by step, unlocking a much larger set of packages across the library.

Qualifications

My qualifications for this project are primarily grounded in my existing contributions to the stdlib codebase. Over the past few months, I have been consistently working within math/base/special, implementing functions of varying difficulty, and becoming familiar with how numerical routines are structured in the project.

I get bored easily by simple issues and push myself out of my comfort zone to take increasingly challenging issues. Working on functions such as gammaf and kernel-betainc has been particularly formative. Implementing gammaf taught me that single-precision implementations require more than simply adapting float64 code; as a matter of fact, the reference code is completely different from the gamma (double-precision version), approximation strategies, acceptable error bounds, and edge-case handling often need to be reconsidered specifically for float32.

Implementing kernel-betainc helped understand how arrays handle values in stdlib; it also strengthened my understanding of how to write a huge coverage of test cases, considering all constraints and edge cases. As a result, I am clear about writing cases for complete coverage of the function, following the IEEE 754 standards.

Beyond the technical aspects, I have taken a course in discrete mathematics and am currently taking a course on Probability and Statistics at my University. I am also familiar with the stdlib’s coding conventions, documentation style, and review process. Having already worked through multiple pull requests and iterations with maintainers, I am comfortable navigating the codebase and confident in my ability to execute this project independently.

Prior art

Many of the functions proposed in this project are well studied and already implemented in several numerical computing libraries, such as Cephes, FreeBSD, Go, Boost, Julia, FDlibm, SLATEC, and SciPy, which provide reliable implementations and test references used across scientific computing ecosystems.

Within stdlib itself, stdlib-js/stdlib#649, related work has already been carried out in previous GSoC projects. In particular, Gunj Joshi and Karan Anand implemented several numerical routines and special functions that form part of the current foundation in math/base/special. Their work provides useful references for implementation, numerical techniques, and testing approaches used within the project.

Commitment

I plan to commit to the full 350-hour schedule for this project. During the coding period, I expect to work approximately 35–40 hours per week.

My university exams finish on 16th May, after which I will be fully available to focus on the project. From that point onward, I will be able to dedicate consistent full-time effort throughout the main development period.

I also plan to stay involved with the project beyond the official GSoC period and continue contributing to stdlib after the program concludes.

Schedule

I already have experience with working on math/base/special, so it would not be difficult for me to get started with it right away, but the issue is that a lot of packages are interdependent, and they need to be slowly addressed and cleared; otherwise, progress would be completely halted.

Constraints

These are the things that I kept in mind while designing the weekly plan (the weekly plan pdf goes into greater detail):

  1. Parallelise work
  2. Merging time
  3. Dependency chains
  4. Uncertainty
  5. Consistency and Burnout

Implementation plan

The implementation is meticulously thought out based on these two pieces of information:

  1. Dependency spreadsheet- contains a detailed map of the remaining 47 functions, their dependency functions, topological ordering, complexity (based on loc and files count), weekly plan and stats dependencies.
  2. Weekly plan - outlines the implementation work week-by-week with detailed reasoning considering all the parameters and constraints.

Assuming 12 weeks,

Community Bonding Period (W1 - W3):

During this period, I plan to finish implementing functions without any internal or external dependencies. This will give time to the maintainers to review and merge those external dependencies. I would also look into implementing ulpdiff test cases for the existing functions.

  • Week C1: gammalnf, cfloornf, truncnf

  • Week C2: polygamma, besselj1f, floorbf

  • Week C3: fresnelcf, fresnelsf, floorsdf

Development Period:

Phase 1 (Week 1 - Week 4): During this period, I plan to work on high impact functions (gammaf, gamma-delta-ratiof, gamma1pm1f) that unlock large portions of the dependency chain and only have internal dependency. This gives the control onto us and even further time for the external dependencies to get reviewed and merged

  • Week 1: bessely1f, betalnf, gamma1pm1f, cschf

  • Week 2: gamma-delta-ratiof, betaf, cothf, expitf

  • Week 3: riemann-zetaf, boxcox1pf, boxcox1pinvf, boxcoxinvf

  • Week 4: falling-factorialf, binomcoeflnf, dirichlet-etaf, log1pexpf

Phase 2 (Weeks 5-7): During this period, I would work on deep chain functions and heavy implementations (gammaincf, kernel-betaincinv, gammaincinvf). By this point, the maintainers have had 8+ weeks to merge external dependencies like expf, expm1f, factorialf.

  • Week 5: kernel-betaincinv, rising-factorialf, logaddexpf, expm1relf

  • Week 6: gammaincf, ccisf, ceilbf, log1mexpf

  • Week 7: gammaincinvf, polygammaf, trunc2f, ceilsdf

Phase 3 (Weeks 8-10): During this period, I would work on the betainc chain completion (kernel-betaincf -> betaincf -> kernel-betaincinvf) plus some remaining functions.

  • Week 8: kernel-betaincf, bessely0f, truncsdf

  • Week 9: betaincf, ellipef, ellipjf

  • Week 10: kernel-betaincinvf

Phase 4 Buffer (Weeks 11-12): During this period, I plan to work on the final chain link (betaincinvf). It must be in a different week than kernel-betaincinvf (W10) to allow PR review and merge time. Remaining time handles any review feedback, reviewing the other 57 PRs, implementing ulpdiff test cases for the existing function and for rework from earlier weeks.

  • Week 11: betaincinvf

  • Week 12: No functions scheduled

Final Week: I’ll wrap up the project, along with working on additional things based on the suggestions and feedback that I’d receive.
Post GSoC: I will continue working, reviewing the remaining 57 functions (mentioned below) and take on statistics packages to finish the now unblocked functions, and further tackle more challenging issues.

Note

  1. Handling uncertainty

It’s good to be optimistic, but we need to account for uncertainties such as merging latency, CI/CD failures, testing complexities, etc. Merging latency could learn to dependency chain blockage as well, which would cause a traffic wave.
So, in such cases, during this given time, I would work on updating the test coverage of existing functions, considering the reference implementation and IEEE 754 standards, helping transition to ulpdiff tests and fixing implementation mistakes, reviewing PRs and such.

  1. Remaining 57 functions (out of 104)

The remaining 57 functions have PRs with varying status (open, draft, failed, passed). Although this plan is entirely focused on targeting the 47 functions that don't have any PR, I'd still review them and, if needed, implement them as well.
Here is the dependency spreadsheet for these 57 functions, containing the dependency list and topological ordering.

Notes:

  • The community bonding period is a 3 week period built into GSoC to help you get to know the project community and participate in project discussion. This is an opportunity for you to setup your local development environment, learn how the project's source control works, refine your project plan, read any necessary documentation, and otherwise prepare to execute on your project proposal.
  • Usually, even week 1 deliverables include some code.
  • By week 6, you need enough done at this point for your mentor to evaluate your progress and pass you. Usually, you want to be a bit more than halfway done.
  • By week 11, you may want to "code freeze" and focus on completing any tests and/or documentation.
  • During the final week, you'll be submitting your project.

Huge thanks to Karan's GSoC issue and Gunj Joshi's GSoC issues, I took a lot of inspiration from them.

Related issues

GSoC 34
stdlib-js/stdlib#649
stdlib-js/stdlib#365

Checklist

  • I have read and understood the Code of Conduct.
  • I have read and understood the application materials found in this repository.
  • I understand that plagiarism will not be tolerated, and I have authored this application in my own words.
  • I have read and understood the patch requirement which is necessary for my application to be considered for acceptance.
  • I have read and understood the stdlib showcase requirement which is necessary for my application to be considered for acceptance.
  • The issue name begins with [RFC]: and succinctly describes your proposal.
  • I understand that, in order to apply to be a GSoC contributor, I must submit my final application to https://summerofcode.withgoogle.com/ before the submission deadline.

Metadata

Metadata

Assignees

No one assigned

    Labels

    20262026 GSoC proposal.received feedbackA proposal which has received feedback.rfcProject proposal.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions