Full name
Abdul Kaium
University status
Yes
University name
Jahangirnagar University
University program
B.Sc. in Computer Science and Engineering
Expected graduation
2027
Short biography
I’m a 3rd-year (soon to be 4th-year) undergraduate in Computer Science & Engineering at Jahangirnagar University, Bangladesh. I primarily work with C/C++ and JavaScript/TypeScript, along with some experience in Python, Java, Rust, Bash, and Fortran. I enjoy writing efficient, performance-oriented code and have a strong interest in low-level optimization, numerical methods, and building systems from scratch. I also participated in competitive programming contests and have achieved 8th place in ICPC Dhaka Regional and also participated in ICPC Asia West Championship. My interests include high-performance computing, GPU computation, game development, and color science, along with building technically detailed frontend applications.
Timezone
Bangladesh Standard Time (UTC+06:00)
Contact details
email: abdulkaium1024@gmail.com, github: impawstarlight, linkedin: abdulkaium1024
Platform
Linux
Editor
VSCode, for its rich set of features, built-in Git integration, and extensive support for extensions.
Programming experience
I started programming in 8th grade (2017) out of curiosity, learning C, C++, and Java while solving math-focused problems from Project Euler, including large primes and factorials. As a challenge, I implemented my own arbitrary-precision integer routines in C for multiplication and factorial computation, albeit not very sophisticated but I tried my best.
In 2021, I picked up JavaScript and CSS and began building personal projects. Two of my favorite projects from this period are:
Up until then, I did not have access to a computer and worked entirely on a mobile device, which pushed me to develop a habit of writing efficient, performance-conscious code from scratch without relying on external libraries.
I began competitive programming in 2023 after enrolling in university and have since participated in 7 nation-wide contests, achieving rankings of 8th, 15th, 16th, and 23rd among others, competing against hundreds of participants. I also participated in the recent ICPC Asia West Championship, representing my university at a multi-national competition.
I also worked on a paid part-time project developing web-based math games for children, collaborating under supervision and gaining experience with real-world development practices and teamwork.
JavaScript experience
JavaScript is my go-to language for personal projects and the one I’m most comfortable with. I’ve worked extensively with vanilla JS, handling everything from DOM manipulation to complex algorithm implementation, and I also have practical experience with frontend and backend libraries.
The best part of JavaScript for me is its portability across different devices along with its ability to easily create GUI applications which made it accessible to me even without a computer.
On the downside, I find JavaScript's lack of static typing a bit limiting, and its lack of support for 64-bit integer arithmetic is a very awkward handicap.
Node.js experience
I’m familiar with Node.js, from frontend and backend development. I have experience with async/await, ESM and CJS modules, and building event-driven, real-time applications.
C/Fortran experience
C was my first programming language, and I’ve spent a significant amount of time with it, particularly for competitive programming. I’m very comfortable with its core concepts including pointers, dynamic memory management, and meta-programming.
As for Fortran, I started learning it last year while working on stdlib and am now familiar with its syntax and core concepts, though I’m not fully proficient yet.
Interest in stdlib
stdlib stands out as a powerful JavaScript alternative to Python’s NumPy, offering efficient utilities for data manipulation, statistics, and mathematical computations. I’m fascinated by its motivation and architecture, particularly its modular design, which allows developers to import and use only the specific parts they need. I’m excited about contributing to a project with the potential to become the standard library for high-performance math in JavaScript.
My favorite feature of stdlib is its REPL environment which helped me a lot with debugging while working on my contributions to stdlib as it enables us to quickly run stdlib modules from the command line. Another thing I particularly appreciate about stdlib is its large collection of assertion and utility functions that help keep the codebase clean, readable and meaningful.
Version control
Yes
Contributions to stdlib
I have successfully contributed to stdlib with simple patches as well as complex features that are directly related to this project. In particular, I've implemented 2 new PRNG packages and a 64-bit unsigned integer constructor that are close to being merged.
Merged PRs:
Open PRs:
All PRs:
stdlib showcase
HackenneTwister19937
I created a small observable notebook to demonstrate how Mersenne Twister can be set up to produce arbitrary sequence of numbers (and make it sing!) as a fun demo. I utilized stdlib's PRNG API to manually control the state of the MT19937.
Goals
Abstract
Currently, stdlib's PRNG collection is limited to only 3 underlying algorithms (minstd, minstd-shuffle, and mt19937), which restricts users' ability to choose appropriate algorithms for their specific use cases. Many modern scientific computing workflows, data science libraries, and numerical simulations depend on access to high-quality, widely-adopted PRNGs for reproducibility across ecosystems. As JavaScript gains adoption in numerical computing and data science, the lack of contemporary PRNG options creates a significant gap compared to NumPy, Julia, R, etc. Additionally, many users migrating workflows between languages require the same PRNG implementations to ensure reproducible results, which is currently difficult with stdlib's limited selection.
To address these limitations, this project aims to implement at least 11 new PRNGs in both JavaScript and C within the @stdlib/random namespace. This will include base implementations and corresponding higher-level wrappers in the array, iter, stream, and strided namespaces.
This work will directly improve cross-ecosystem reproducibility with major data science libraries by implementing many widespread and default PRNGs, helping users from different ecosystems find the PRNG they need for reproducible results in stdlib.
As a prerequisite of this project, basic support for 64-bit and 128-bit unsigned integers will be added to stdlib, since many high-impact modern PRNGs require 64-bit and 128-bit arithmetic that is not natively available in JavaScript.
Additionally, a key focus throughout the project will be on identifying the best overall PRNG among the newly implemented ones to potentially serve as the new default in stdlib. However, this would be a breaking change for downstream libraries so it will be carefully weighed against its benefits and drawbacks.
Selected PRNGs
The selection prioritizes generators with broad adoption across major data science ecosystems (NumPy, Julia, R, etc.), proven statistical quality, and suitability for specialized use cases (Monte Carlo simulations, machine learning, physics simulations). The generators span modern high-quality designs, parallel-friendly counter-based architectures, simulation-grade options with stream support, and historically significant legacy algorithms.
Some 64-bit PRNGs are selected as high-priority even though JavaScript lacks a standard way to expose 64-bit integer outputs. But they can still provide clear value by supporting high-quality 53-bit float generation for scientific workloads, bringing stdlib close to NumPy/Julia compatibility.
For effective scoping, the list is organized into priority-based tiers, with the first 11 PRNGs as the project's core objectives. The remaining PRNGs are optional stretch goals to be pursued if time permits.
Tier 1: Modern Defaults (Highest Priority)
- PCG64 (Widely used in scientific Python workflows, default in NumPy since 2019)
- Xoshiro256++ (High-performance modern scientific generator, default in Julia since 2021)
- Philox4x32-10 (First choice in major ML workflows, default in PyTorch and TensorFlow since 2019)
Tier 2: Modern 32-bit (High Priority)
- PCG32 (Widely used in game development, default in Godot since 2018)
- Xoshiro128** (Best quality 32-bit Xoshiro variant)
- Threefry4x32-20 (Widely used in ML and parallel simulation environments)
- SFC32 (Fast, JS-friendly generator with strong statistical quality)
Tier 3: Specialized Simulation (High Priority)
- MRG32k3a (L'Ecuyer CMRG used in R for parallel Monte Carlo)
- Ranlux48 (Long-standing simulation-grade generator used in high-energy physics)
Tier 4: Additional Modern 32-bit (High/Normal Priority)
- Xoshiro128++ (Fast modern 32-bit Xoshiro variant with strong practical quality)
- JSF32 (Lightweight, fast 32-bit generator popular in performance-oriented code)
- PCG32 RXS-M-XS (Small-state PCG variant optimized for memory-constrained environments)
Tier 5: Additional Modern Defaults (Normal Priority)
- PCG64 DXSM (NumPy's recommended PCG64 upgrade for large-scale parallel workloads)
- Xoshiro256** (Highest-quality 64-bit Xoshiro variant, default in GFortran, Lua, and .NET since 2020/21)
- SplitMix64 (Java's SplittableRandom, recommended seeder for Xoshiro-family)
Tier 6: Legacy (Normal/Low Priority)
- Taus113 (Combined Tausworthe variant with longer period for legacy simulation reproducibility)
- Taus2 (Older, compact Tausworthe variant used in legacy GPU and simulation code)
- Wichmann-Hill (Legacy option in R, historical Python default before Mersenne Twister)
Go to details
Intentionally Excluded PRNGs
Several widely discussed PRNGs were also considered but ultimately excluded due to the specified reasons:
- WELL (Well Equidistributed Long-period Linear): Although statistically superior to Mersenne Twister, it lacks visible adoption in scientific computing ecosystems.
- Xorwow: Default in cuRAND, but the proprietary and undocumented seeding procedure makes reproducible cross-ecosystem implementation infeasible. Otherwise it's not much relevant outside CUDA ecosystem.
- KISS (Marsaglia): Multiple incompatible variants exist, with no authoritative reference implementation or canonical seeding specification, leading to many fragmented variants.
Uint64/128 Requirements
Among the selected PRNGs, several require higher-precision integer arithmetic than JavaScript natively provides, including all Tier 1 generators. Specifically:
- PCG64 requires 128-bit addition and multiplication to advance its internal LCG state.
- Xoshiro256 variants, PCG32, and SplitMix64 require 64-bit addition and multiplication.
So it seems that implementing 64-bit and 128-bit integer arithmetic support must precede the implementation of these specific PRNGs. But doing so sequentially can potentially block and delay the Tier 1 PRNGs as implementing dedicated high-precision integer support requires thorough discussions about API design, use case patterns, and performance overhead. These are high-impact design decisions for stdlib and many future packages, so they must be given enough time and depth instead of being rushed.
To prevent the dependency block and keep both workstreams progressing steadily, I will develop higher-precision integer support and PRNG implementations in parallel instead of strictly sequencing them. I'll start with 32-bit PRNGs to allow some grace period for Uint64/128 packages to be completed first.
In case the Uint64/128 packages require significantly more time and effort that has the potential to delay the PRNG delivery timeline, I'll focus on only the necessary arithmetic packages or helpers instead of comprehensive Uint64/128 support since PRNG implementations are more important milestones in this project. As a result, early PRNG versions may use local high-precision arithmetic helpers where needed, which will later be refactored to use the newly implemented Uint64/128 utilities once they are finalized.
This is very much feasible as the core logic behind higher-precision arithmetic routines is not that complex and can be easily included inside specific PRNG packages. I have already implemented and used 64-bit unsigned addition and multiplication routines inside my PCG32 PR as a proof of concept so this will help accelerate subsequent work.
For implementation strategy, I am more inclined toward double-word emulation (quad-word for 128-bit) rather than BigInt. My independent experiments suggest BigInt is still significantly slower and its performance varies across runs and engines, while double-word emulation is faster and more consistent.
Seeding and Compatibility
stdlib PRNG APIs already support both single integer seeds and array seeds as seen in existing PRNG packages such as mt19937 and minstd. So the required APIs for passing both kinds of seeds are already in place. The key task is matching ecosystem-specific seed processing for high-value compatibility targets.
For example, the PCG64 variant is included in this project mainly because it has been NumPy's default PRNG since 2019. Including a NumPy-compatible PRNG in stdlib would be a major plus for stdlib adoption. But to achieve perfect reproducibility, we also need to implement NumPy's SeedSequence logic which is used for expanding a user-provided seed into arbitrary number of words. It is functionally similar to the SplitMix64 PRNG which is suggested for seeding Xoshiro PRNGs by original authors.
Hence, to support NumPy compatibility for PCG64, I'll implement SeedSequence logic inside stdlib. I plan to do this by creating a separate package for SeedSequence, since it will also be useful for seeding other PRNGs. Furthermore, I will create two separate packages for PCG64 as below:
pcg64: Using manual seeding.
pcg64-npy: Using SeedSequence for reproducibility with NumPy.
Similarly, the Xoshiro256++ variant was chosen because of its status as Julia's default PRNG since 2021. While Julia uses custom seeding logic, the official documentation explicitly states that reproducibility is not guaranteed between minor releases even with identical seeds, making ecosystem-compatible seeding infeasible. Therefore, I will not pursue Julia-specific reproducibility targeting. Instead, Xoshiro256++ will use the original authors' manual seeding approach, with optional SplitMix64 support for maximum flexibility. Xoshiro256++ remains high-priority because it is computationally lightweight for a high-quality 64-bit PRNG, requiring only 64-bit addition as its most complex operation, which is favorable for JS performance.
Other Xoshiro variants, such as Xoshiro256** in GFortran, Lua, and .NET, all use different seeding approaches. I will only implement the original manual seeding version in this project since there is very little gain from targeting these specific platforms.
The remaining PRNGs mostly follow one standard implementation but each one will still be evaluated on a case-by-case basis. Where divergent variants exist, the best course of action will be determined after discussing with mentors.
Jump-Ahead and Stream Support
Many of the selected PRNGs support jump-ahead, which advances the generator state by an arbitrary (or sometimes fixed) number of steps without iterating through each intermediate state. In practice, this can reduce skip cost from O(n) to O(log n) and is important for deterministic parallel workloads, where each worker needs a reproducible, non-overlapping stream segment.
While stdlib does not yet expose a jump API in existing PRNG packages, this project provides a strong opportunity to add one. However, jump semantics vary across PRNG families, so designing a unified API involves challenges relating to API consistency. For example:
-
The PCG family supports arbitrary jump lengths in both forward and backward directions with O(log n) complexity, where n is the jump distance. It uses binary exponentiation over affine transformations, which is functionally equivalent to general matrix exponentiation but optimized for an LCG's simple transition function.
-
For the Xoshiro family, the original authors provide two fixed-size jump methods. A shorter jump advances the generator state by 2(n/2) steps, where n is the number of state bits. A longer jump advances by 2(3n/4) steps. The implementation is mostly bitwise operations, so it is relatively straightforward even for 64-bit variants, and both methods have time complexity of O(the number of state bits). Also there's a third party implementation that provides arbitrary jump feature which is linked in the original author's website.
-
MRG32k3a also supports arbitrary jump in theory via matrix exponentiation, but in practice only two fixed-size jumps are commonly implemented: 276 and 2127 steps. This may require 64-bit integer arithmetic inside matrix multiplication because intermediate multiplications can exceed JavaScript's 53-bit integer precision.
-
Counter-based PRNGs such as Philox and Threefry provide effectively zero-cost arbitrary jump, because their state is fundamentally a counter. Time complexity is O(1).
For now, I will treat this section as an optional goal, with room for adjustments after further observation of the project's progress and pacing.
Higher-Level Wrappers
As discussed in structured package metadata, stdlib already has an established path for generating higher-level wrappers from base packages using scaffold metadata under the __stdlib__ field in package.json and generation tooling under @stdlib/_tools/scaffold. I will extend this workflow for the PRNGs.
Concretely, each base PRNG package will include scaffold metadata (alias, descriptions, parameter schema, example values, and benchmark random ranges), and wrapper-generation scripts will consume that metadata to produce random/array, random/iter, random/stream, and random/strided variants with consistent README/docs/tests/benchmarks.
To control timeline risk, I will start this work early (rather than after finishing all base PRNGs) and run a pilot with 1-2 PRNGs first. The pilot milestone will be a fully reproducible scaffold run that can generate and validate all four wrapper families from a single base metadata source. Once the pipeline is stable, adding new PRNG wrappers becomes mostly metadata-driven instead of hand-writing 40+ packages.
Initial setup will include template adaptation for random namespaces, metadata-schema alignment for PRNG-specific options, runner wiring, and regeneration-safe validation checks. I currently estimate this scaffolding setup phase at about 1-2 weeks, after which per-PRNG wrapper expansion should be significantly faster and lower risk.
Testing and Benchmarking
Evaluation workflow:
-
Correctness validation
For each PRNG, I will maintain deterministic test vectors from authoritative sources (reference implementations and/or ecosystem targets such as NumPy/Julia/R when applicable). Validation will be performed at multiple levels: raw integer output sequences, float output sequences, seeding behavior, and jump-ahead behavior (when supported). JS and C implementations will be cross-checked to ensure output parity.
-
Statistical quality
Before default-candidate evaluation, each implementation must pass baseline quality checks and reproduce known reference behavior. This stage is mainly to catch implementation defects (state transition bugs, seeding inconsistencies, output permutation errors) before performance conclusions are drawn.
-
Performance benchmarking
I will benchmark both throughput and setup overhead under realistic usage patterns:
- Bulk random generation throughput
- Initialization/seeding cost
- Short-lived instance cost (important for task-parallel workflows)
- Memory/state footprint impact
- Comparative reporting
Results will be summarized in a side-by-side comparison table for all primary candidates, including quality notes, reproducibility status, and performance across representative workloads. This report will serve as the basis for mentor discussion and default-candidate selection.
New Default and Migration
A critical objective is to identify the best-performing PRNG among those implemented to serve as the new default in stdlib. While Mersenne Twister is widely adopted, it has significant limitations:
- Massive state (624×32-bit) hogs CPU cache, degrading performance in tight loops and large-scale simulations
- High initialization overhead poorly suited for frequent short-lived or per-task instances
- Unpredictable memory access patterns and branch mispredictions limit JIT optimization
- Known statistical weaknesses despite its large state and period
The new default will be chosen to address these shortcomings by evaluating the following factors for each new PRNG:
- Statistical quality and documented limitations
- Runtime performance (steady-state + initialization)
- State size and cache friendliness
- Reproducibility value across ecosystems
After evaluating, I will shortlist the top candidate(s) and review trade-offs with mentors before proposing any default change.
While there is a possibility that no candidate is sufficiently strong across all criteria, I am optimistic that at least one modern PRNG will meet the quality, performance, and maintainability bar for a safe default upgrade.
If a default change is proposed, I will include:
- Side-by-side benchmark and quality evidence
- Compatibility impact notes for downstream users
- Clear versioning/migration documentation
- A conservative rollout plan discussed with mentors before adoption
Since migrating to a new default involves updating several existing and working packages, this work will be handled with utmost care ensuring proper testing so that no regression or bugs are introduced in the process.
Detailed Properties of Selected PRNGs
Below are the details for the 11 main goal PRNGs
1. PCG64
Permuted Congruential Generator, uses an LCG as the internal state but outputs a permuted/scrambled view of the state to improve quality.
The canonical 64-bit variant uses a 128-bit LCG transition along with the XSL-RR output permutation.
| State |
Output |
Period |
Features |
Tests |
| 128-bit |
64-bit |
2128 |
Jump-ahead Distance |
✔ BigCrush ✔ PractRand |
Adoption: Default in NumPy since 1.17 (2019).
✔ Very strong quality despite a simple underlying principle
✔ Easy stream separation via distinct increments and efficient jump operations
⚠️ Requires 128-bit arithmetic
2. Xoshiro256++
Xorshift-based generator using simple bitwise operations and output scrambling. The ++ output function provides decent bit mixing with fast performance.
| State |
Output |
Period |
Features |
Tests |
| 256-bit |
64-bit |
2256 - 1 |
Jump Long-jump |
✔ BigCrush ✔ PractRand |
Adoption: Default in Julia since 1.7 (2021).
✔ Excellent speed with simplicity due to minimal arithmetic operations
✔ Fixed jump-ahead and long-jump operations for parallel stream generation
⚠️ Low-order bits show statistical weakness but doesn't matter for 53-bit float generation
3. Philox4x32-10
Counter-based generator that repeatedly scrambles a counter using a key to produce random output blocks. Each unique counter/key pair generates a deterministic block independently, with no need to maintain a running state.
This variant uses 10 rounds of simple mixing operations on 4 32-bit words.
| State |
Output |
Period |
Features |
Tests |
| 128-bit counter + 64-bit key |
32-bit |
2128 |
Random-access |
✔ BigCrush ✔ PractRand |
Adoption: Default in TensorFlow and PyTorch (CUDA).
✔ Trivial stream partitioning via counter/key without jump operations
✔ Ideal for GPU and parallel batch generation with independent threads
⚠️ Heavier per-sample arithmetic than simple recurrence generators like PCG or Xoshiro
4. PCG32
32-bit PCG variant using a 64-bit LCG transition along with the XSH-RR output permutation.
| State |
Output |
Period |
Features |
Tests |
| 64-bit |
32-bit |
264 |
Jump-ahead Distance |
✔ BigCrush ✔ PractRand |
Adoption: Common in game engines, default in Godot.
✔ Strong statistical quality with very small state
⚠️ Requires 64-bit arithmetic
5. Xoshiro128**
32-bit xoshiro variant with ** output mixing.
| State |
Output |
Period |
Features |
Tests |
| 128-bit |
32-bit |
2128 - 1 |
Jump Long-jump |
✔ BigCrush ✔ PractRand |
Adoption: Widely recognized for strong statistical quality in 32-bit systems.
✔ Strongest statistical quality of 32-bit xoshiro variants
⚠️ Low-order bits weaker than high bits
6. Threefry4x32-20
Counter-based generator using Threefish-derived scrambling, stateless like Philox.
| State |
Output |
Period |
Features |
Tests |
| 128-bit counter + 128-bit key |
32-bit |
2128 |
Random-access |
✔ BigCrush ✔ PractRand |
Adoption: Random123 library and functional computation.
✔ Only add/xor/rotate operations; no multiplication required
✔ More CPU friendly than Philox
7. SFC32
Small Fast Chaotic generator with explicit counter term for ensuring minimum period.
| State |
Output |
Period |
Features |
Tests |
| 128-bit |
32-bit |
~2127 |
Chaotic |
✔ BigCrush ✔ PractRand |
Adoption: Popular in game dev and procedural generation.
✔ Excellent speed and compactness
⚠️ Period is seed-dependent, with a minimum of 232
8. MRG32k3a
3rd order Combined Multiple Recursive Generator by L'Ecuyer.
| State |
Output |
Period |
Features |
Tests |
| 192-bit |
32-bit |
~2191 |
Streams Substreams |
✔ BigCrush ✔ PractRand |
Adoption: Industry standard in high-stakes Monte Carlo simulations.
✔ Strong theoretical framework for independent streams
⚠️ Slower than modern counterparts with equivalent periods
9. Ranlux48
Luxury-level subtract-with-borrow generator utilizing chaotic dynamics theory.
| State |
Output |
Period |
Features |
Tests |
| 576-bit |
48-bit |
~2568 ~10171 |
Luxury levels |
✔ BigCrush ✔ PractRand |
Adoption: Used in CERN and high quality physics simulations.
✔ Gold standard of theoretical randomness
✔ Configurable quality via luxury levels
⚠️ Significantly slower than other generators due to luxury skipping
10. Xoshiro128++
32-bit xoshiro variant with ++ output mixing.
| State |
Output |
Period |
Features |
Tests |
| 128-bit |
32-bit |
2128 - 1 |
Jump Long-jump |
✔ BigCrush ✔ PractRand |
Adoption: Popular in embedded systems
✔ Very fast in tight loops
⚠️ Still inherits low-bit caveats of xoshiro family
11. JSF32
Jenkins Small Fast generator based on chaotic transitions.
| State |
Output |
Period |
Features |
Tests |
| 128-bit |
32-bit |
~2126 |
Chaotic |
✔ BigCrush ✔ PractRand |
Adoption: Used in lightweight RNG libraries and benchmark suites.
✔ Tiny implementation and strong speed profile
⚠️ Unpredictable period due to chaotic nature
Why this project?
Random number generation has always intrigued me, especially the idea that deterministic algorithms can produce seemingly random outputs feels like a paradox. This project offers a perfect opportunity to dive deep into the intricacies of PRNGs and explore how they are designed and optimized. The algorithmic challenges involved in implementing various PRNGs excite me, as they remind me of tackling problems in competitive programming where efficiency and precision are of utmost importance. I’m eager to contribute to this project and deepen my understanding of a critical area of computer science that has broad applications in fields like cryptography, simulations, and gaming.
Qualifications
As a competitive programmer, I have solid experience with algorithmic analysis, bit manipulation and modular arithmetic which are core concepts in PRNG algorithms and that makes this project a natural fit for me. Additionally, I’ve completed academic courses like Algorithms and Data Structures, Discrete Mathematics, Digital Logic Design, and Microprocessors, giving me a strong foundation in computational principles.
My familiarity with low-level performance concepts such as instruction pipelining, CPU cache behavior, and register pressure, as well as my long-standing interest in big-integer arithmetic, is perfectly suited to building efficient PRNG implementations in this project.
I’ve also demonstrated my familiarity with the stdlib codebase and PRNG internals by contributing two new PRNG implementations, which are awaiting approval and I’m currently studying research papers by various PRNG designers to understand the core ideas behind their algorithms.
Prior art
Source materials
Most of the PRNGs proposed in this project have accompanying papers which are listed below:
Others are described in blog posts and public sources:
Reference Implementations
Additional materials used for PRNG selection
Commitment
I plan to invest ~30 hr/week during the GSoC period for a total of 350 hours. My 3rd-year finals will be over by April and I'll be able to fully dedicate my time to this project as I have no other commitments during this period.
Schedule
Assuming a 12 week schedule, below is a draft timeline for realizing the project goals.
-
Community Bonding Period:
-
Week C1: Scoping and API alignment
- Discuss and exchange ideas with mentors to solidify the overall project plan and address any missing pieces of detail in my proposal
- This will involve new API designs, priority evaluation, possible challenges, and goal adjustments for the best outcome.
-
Week C2: Uint64/128 helpers and scaffolding setup
- Implement and test standalone
Uint64/128 arithmetic helper functions that can be included separately inside PRNG packages
- Explore existing scaffolding pipeline and start working on new scaffolding scripts
-
Week C3: Uint64/128 packages and old PR review
- Iterate over
Uint64/128 APIs and start implementing full fledged packages under number/uint64 and number/uint128
- Get existing PR for PCG32 over the finish line.
-
Week 1: 32-bit Xoshiro variants
- Implement Xoshiro128**
- Implement Xoshiro128++
- Parallel work on
Uint64/128
-
Week 2: 32-bit chaotic generators
- Implement SFC32
- Implement JSF32
- Parallel work on
Uint64/128
-
Week 3: 32-bit counter-based generators
- Implement Threefry
- Implement Philox
- Parallel work on
Uint64/128
-
Week 4: Buffer & 64-bit Xoshiro
- Address feedback from PR reviews and cover backlogs
- Implement Xoshiro256++
- Optionally implement SplitMix64
-
Week 5: 64-bit PCG & NumPy compatibility
- Implement PCG64
- Implement SeedSequence for NumPy-style seed expansion
- Integrate with PCG64 (either via options or new package)
- Test against NumPy
-
Week 6: Midterm & scaffolding preparation
- Address midterm evaluation
- Address feedback from PR reviews and cover backlogs
- Start work on adding structured metadata for scaffolding higher-level wrappers
-
Week 7: CMRG and metadata
- Implement MRG32k3a
- Parallel work on adding structured metadata
-
Week 8: Ranlux and metadata
- Implement Ranlux48
- Parallel work on adding structured metadata
-
Week 9: Wrappers and default scouting
- Generate
array and iter wrappers for all new PRNGs
- Benchmark and discuss new default candidate
-
Week 10: Wrappers and default migration
- Generate
stream and strided wrappers for all new PRNGs
- Start migrating existing packages to use the new default PRNG
-
Week 11: Buffer
- Address feedback from PR reviews and cover backlogs
- Finalize default migration
-
Week 12: Finishing
- Finish up any residual work
- Write project report and identify future works to be done
- Create issues for future reference if bugs and unresolved matters are found
-
Final Week: Submission
Related issues
Checklist
Full name
Abdul Kaium
University status
Yes
University name
Jahangirnagar University
University program
B.Sc. in Computer Science and Engineering
Expected graduation
2027
Short biography
I’m a 3rd-year (soon to be 4th-year) undergraduate in Computer Science & Engineering at Jahangirnagar University, Bangladesh. I primarily work with C/C++ and JavaScript/TypeScript, along with some experience in Python, Java, Rust, Bash, and Fortran. I enjoy writing efficient, performance-oriented code and have a strong interest in low-level optimization, numerical methods, and building systems from scratch. I also participated in competitive programming contests and have achieved 8th place in ICPC Dhaka Regional and also participated in ICPC Asia West Championship. My interests include high-performance computing, GPU computation, game development, and color science, along with building technically detailed frontend applications.
Timezone
Bangladesh Standard Time (UTC+06:00)
Contact details
email: abdulkaium1024@gmail.com, github: impawstarlight, linkedin: abdulkaium1024
Platform
Linux
Editor
VSCode, for its rich set of features, built-in Git integration, and extensive support for extensions.
Programming experience
I started programming in 8th grade (2017) out of curiosity, learning C, C++, and Java while solving math-focused problems from Project Euler, including large primes and factorials. As a challenge, I implemented my own arbitrary-precision integer routines in C for multiplication and factorial computation, albeit not very sophisticated but I tried my best.
In 2021, I picked up JavaScript and CSS and began building personal projects. Two of my favorite projects from this period are:
Up until then, I did not have access to a computer and worked entirely on a mobile device, which pushed me to develop a habit of writing efficient, performance-conscious code from scratch without relying on external libraries.
I began competitive programming in 2023 after enrolling in university and have since participated in 7 nation-wide contests, achieving rankings of 8th, 15th, 16th, and 23rd among others, competing against hundreds of participants. I also participated in the recent ICPC Asia West Championship, representing my university at a multi-national competition.
I also worked on a paid part-time project developing web-based math games for children, collaborating under supervision and gaining experience with real-world development practices and teamwork.
JavaScript experience
JavaScript is my go-to language for personal projects and the one I’m most comfortable with. I’ve worked extensively with vanilla JS, handling everything from DOM manipulation to complex algorithm implementation, and I also have practical experience with frontend and backend libraries.
The best part of JavaScript for me is its portability across different devices along with its ability to easily create GUI applications which made it accessible to me even without a computer.
On the downside, I find JavaScript's lack of static typing a bit limiting, and its lack of support for 64-bit integer arithmetic is a very awkward handicap.
Node.js experience
I’m familiar with Node.js, from frontend and backend development. I have experience with async/await, ESM and CJS modules, and building event-driven, real-time applications.
C/Fortran experience
C was my first programming language, and I’ve spent a significant amount of time with it, particularly for competitive programming. I’m very comfortable with its core concepts including pointers, dynamic memory management, and meta-programming.
As for Fortran, I started learning it last year while working on
stdliband am now familiar with its syntax and core concepts, though I’m not fully proficient yet.Interest in stdlib
stdlibstands out as a powerful JavaScript alternative to Python’s NumPy, offering efficient utilities for data manipulation, statistics, and mathematical computations. I’m fascinated by its motivation and architecture, particularly its modular design, which allows developers to import and use only the specific parts they need. I’m excited about contributing to a project with the potential to become the standard library for high-performance math in JavaScript.My favorite feature of
stdlibis its REPL environment which helped me a lot with debugging while working on my contributions tostdlibas it enables us to quickly runstdlibmodules from the command line. Another thing I particularly appreciate aboutstdlibis its large collection of assertion and utility functions that help keep the codebase clean, readable and meaningful.Version control
Yes
Contributions to stdlib
I have successfully contributed to
stdlibwith simple patches as well as complex features that are directly related to this project. In particular, I've implemented 2 new PRNG packages and a 64-bit unsigned integer constructor that are close to being merged.Merged PRs:
random/base/minstdstdlib#6498Open PRs:
random/base/xorshift32stdlib#6333random/base/pcg32stdlib#6551number/uint64/ctorstdlib#10908All PRs:
stdlib showcase
HackenneTwister19937
I created a small observable notebook to demonstrate how Mersenne Twister can be set up to produce arbitrary sequence of numbers (and make it sing!) as a fun demo. I utilized
stdlib's PRNG API to manually control the state of the MT19937.Goals
Abstract
Currently,
stdlib's PRNG collection is limited to only 3 underlying algorithms (minstd, minstd-shuffle, and mt19937), which restricts users' ability to choose appropriate algorithms for their specific use cases. Many modern scientific computing workflows, data science libraries, and numerical simulations depend on access to high-quality, widely-adopted PRNGs for reproducibility across ecosystems. As JavaScript gains adoption in numerical computing and data science, the lack of contemporary PRNG options creates a significant gap compared to NumPy, Julia, R, etc. Additionally, many users migrating workflows between languages require the same PRNG implementations to ensure reproducible results, which is currently difficult withstdlib's limited selection.To address these limitations, this project aims to implement at least 11 new PRNGs in both JavaScript and C within the
@stdlib/randomnamespace. This will includebaseimplementations and corresponding higher-level wrappers in thearray,iter,stream, andstridednamespaces.This work will directly improve cross-ecosystem reproducibility with major data science libraries by implementing many widespread and default PRNGs, helping users from different ecosystems find the PRNG they need for reproducible results in
stdlib.As a prerequisite of this project, basic support for 64-bit and 128-bit unsigned integers will be added to
stdlib, since many high-impact modern PRNGs require 64-bit and 128-bit arithmetic that is not natively available in JavaScript.Additionally, a key focus throughout the project will be on identifying the best overall PRNG among the newly implemented ones to potentially serve as the new default in
stdlib. However, this would be a breaking change for downstream libraries so it will be carefully weighed against its benefits and drawbacks.Selected PRNGs
The selection prioritizes generators with broad adoption across major data science ecosystems (NumPy, Julia, R, etc.), proven statistical quality, and suitability for specialized use cases (Monte Carlo simulations, machine learning, physics simulations). The generators span modern high-quality designs, parallel-friendly counter-based architectures, simulation-grade options with stream support, and historically significant legacy algorithms.
Some 64-bit PRNGs are selected as high-priority even though JavaScript lacks a standard way to expose 64-bit integer outputs. But they can still provide clear value by supporting high-quality 53-bit float generation for scientific workloads, bringing
stdlibclose to NumPy/Julia compatibility.For effective scoping, the list is organized into priority-based tiers, with the first 11 PRNGs as the project's core objectives. The remaining PRNGs are optional stretch goals to be pursued if time permits.
Tier 1: Modern Defaults (Highest Priority)
Tier 2: Modern 32-bit (High Priority)
Tier 3: Specialized Simulation (High Priority)
Tier 4: Additional Modern 32-bit (High/Normal Priority)
Tier 5: Additional Modern Defaults (Normal Priority)
Tier 6: Legacy (Normal/Low Priority)
Go to details
Intentionally Excluded PRNGs
Several widely discussed PRNGs were also considered but ultimately excluded due to the specified reasons:
Uint64/128 Requirements
Among the selected PRNGs, several require higher-precision integer arithmetic than JavaScript natively provides, including all Tier 1 generators. Specifically:
So it seems that implementing 64-bit and 128-bit integer arithmetic support must precede the implementation of these specific PRNGs. But doing so sequentially can potentially block and delay the Tier 1 PRNGs as implementing dedicated high-precision integer support requires thorough discussions about API design, use case patterns, and performance overhead. These are high-impact design decisions for
stdliband many future packages, so they must be given enough time and depth instead of being rushed.To prevent the dependency block and keep both workstreams progressing steadily, I will develop higher-precision integer support and PRNG implementations in parallel instead of strictly sequencing them. I'll start with 32-bit PRNGs to allow some grace period for
Uint64/128packages to be completed first.In case the
Uint64/128packages require significantly more time and effort that has the potential to delay the PRNG delivery timeline, I'll focus on only the necessary arithmetic packages or helpers instead of comprehensiveUint64/128support since PRNG implementations are more important milestones in this project. As a result, early PRNG versions may use local high-precision arithmetic helpers where needed, which will later be refactored to use the newly implementedUint64/128utilities once they are finalized.This is very much feasible as the core logic behind higher-precision arithmetic routines is not that complex and can be easily included inside specific PRNG packages. I have already implemented and used 64-bit unsigned addition and multiplication routines inside my PCG32 PR as a proof of concept so this will help accelerate subsequent work.
For implementation strategy, I am more inclined toward double-word emulation (quad-word for 128-bit) rather than BigInt. My independent experiments suggest BigInt is still significantly slower and its performance varies across runs and engines, while double-word emulation is faster and more consistent.
Seeding and Compatibility
stdlibPRNG APIs already support both single integer seeds and array seeds as seen in existing PRNG packages such asmt19937andminstd. So the required APIs for passing both kinds of seeds are already in place. The key task is matching ecosystem-specific seed processing for high-value compatibility targets.For example, the PCG64 variant is included in this project mainly because it has been NumPy's default PRNG since 2019. Including a NumPy-compatible PRNG in
stdlibwould be a major plus forstdlibadoption. But to achieve perfect reproducibility, we also need to implement NumPy'sSeedSequencelogic which is used for expanding a user-provided seed into arbitrary number of words. It is functionally similar to the SplitMix64 PRNG which is suggested for seeding Xoshiro PRNGs by original authors.Hence, to support NumPy compatibility for PCG64, I'll implement
SeedSequencelogic insidestdlib. I plan to do this by creating a separate package forSeedSequence, since it will also be useful for seeding other PRNGs. Furthermore, I will create two separate packages for PCG64 as below:pcg64: Using manual seeding.pcg64-npy: UsingSeedSequencefor reproducibility with NumPy.Similarly, the Xoshiro256++ variant was chosen because of its status as Julia's default PRNG since 2021. While Julia uses custom seeding logic, the official documentation explicitly states that reproducibility is not guaranteed between minor releases even with identical seeds, making ecosystem-compatible seeding infeasible. Therefore, I will not pursue Julia-specific reproducibility targeting. Instead, Xoshiro256++ will use the original authors' manual seeding approach, with optional SplitMix64 support for maximum flexibility. Xoshiro256++ remains high-priority because it is computationally lightweight for a high-quality 64-bit PRNG, requiring only 64-bit addition as its most complex operation, which is favorable for JS performance.
Other Xoshiro variants, such as Xoshiro256** in GFortran, Lua, and .NET, all use different seeding approaches. I will only implement the original manual seeding version in this project since there is very little gain from targeting these specific platforms.
The remaining PRNGs mostly follow one standard implementation but each one will still be evaluated on a case-by-case basis. Where divergent variants exist, the best course of action will be determined after discussing with mentors.
Jump-Ahead and Stream Support
Many of the selected PRNGs support jump-ahead, which advances the generator state by an arbitrary (or sometimes fixed) number of steps without iterating through each intermediate state. In practice, this can reduce skip cost from
O(n)toO(log n)and is important for deterministic parallel workloads, where each worker needs a reproducible, non-overlapping stream segment.While
stdlibdoes not yet expose a jump API in existing PRNG packages, this project provides a strong opportunity to add one. However, jump semantics vary across PRNG families, so designing a unified API involves challenges relating to API consistency. For example:The PCG family supports arbitrary jump lengths in both forward and backward directions with
O(log n)complexity, wherenis the jump distance. It uses binary exponentiation over affine transformations, which is functionally equivalent to general matrix exponentiation but optimized for an LCG's simple transition function.For the Xoshiro family, the original authors provide two fixed-size jump methods. A shorter jump advances the generator state by 2(n/2) steps, where
nis the number of state bits. A longer jump advances by 2(3n/4) steps. The implementation is mostly bitwise operations, so it is relatively straightforward even for 64-bit variants, and both methods have time complexity ofO(the number of state bits). Also there's a third party implementation that provides arbitrary jump feature which is linked in the original author's website.MRG32k3a also supports arbitrary jump in theory via matrix exponentiation, but in practice only two fixed-size jumps are commonly implemented: 276 and 2127 steps. This may require 64-bit integer arithmetic inside matrix multiplication because intermediate multiplications can exceed JavaScript's 53-bit integer precision.
Counter-based PRNGs such as Philox and Threefry provide effectively zero-cost arbitrary jump, because their state is fundamentally a counter. Time complexity is
O(1).For now, I will treat this section as an optional goal, with room for adjustments after further observation of the project's progress and pacing.
Higher-Level Wrappers
As discussed in structured package metadata,
stdlibalready has an established path for generating higher-level wrappers from base packages using scaffold metadata under the__stdlib__field inpackage.jsonand generation tooling under@stdlib/_tools/scaffold. I will extend this workflow for the PRNGs.Concretely, each base PRNG package will include scaffold metadata (alias, descriptions, parameter schema, example values, and benchmark random ranges), and wrapper-generation scripts will consume that metadata to produce
random/array,random/iter,random/stream, andrandom/stridedvariants with consistent README/docs/tests/benchmarks.To control timeline risk, I will start this work early (rather than after finishing all base PRNGs) and run a pilot with 1-2 PRNGs first. The pilot milestone will be a fully reproducible scaffold run that can generate and validate all four wrapper families from a single base metadata source. Once the pipeline is stable, adding new PRNG wrappers becomes mostly metadata-driven instead of hand-writing 40+ packages.
Initial setup will include template adaptation for random namespaces, metadata-schema alignment for PRNG-specific options, runner wiring, and regeneration-safe validation checks. I currently estimate this scaffolding setup phase at about 1-2 weeks, after which per-PRNG wrapper expansion should be significantly faster and lower risk.
Testing and Benchmarking
Evaluation workflow:
Correctness validation
For each PRNG, I will maintain deterministic test vectors from authoritative sources (reference implementations and/or ecosystem targets such as NumPy/Julia/R when applicable). Validation will be performed at multiple levels: raw integer output sequences, float output sequences, seeding behavior, and jump-ahead behavior (when supported). JS and C implementations will be cross-checked to ensure output parity.
Statistical quality
Before default-candidate evaluation, each implementation must pass baseline quality checks and reproduce known reference behavior. This stage is mainly to catch implementation defects (state transition bugs, seeding inconsistencies, output permutation errors) before performance conclusions are drawn.
Performance benchmarking
I will benchmark both throughput and setup overhead under realistic usage patterns:
Results will be summarized in a side-by-side comparison table for all primary candidates, including quality notes, reproducibility status, and performance across representative workloads. This report will serve as the basis for mentor discussion and default-candidate selection.
New Default and Migration
A critical objective is to identify the best-performing PRNG among those implemented to serve as the new default in
stdlib. While Mersenne Twister is widely adopted, it has significant limitations:The new default will be chosen to address these shortcomings by evaluating the following factors for each new PRNG:
After evaluating, I will shortlist the top candidate(s) and review trade-offs with mentors before proposing any default change.
While there is a possibility that no candidate is sufficiently strong across all criteria, I am optimistic that at least one modern PRNG will meet the quality, performance, and maintainability bar for a safe default upgrade.
If a default change is proposed, I will include:
Since migrating to a new default involves updating several existing and working packages, this work will be handled with utmost care ensuring proper testing so that no regression or bugs are introduced in the process.
Detailed Properties of Selected PRNGs
Below are the details for the 11 main goal PRNGs
1. PCG64
Permuted Congruential Generator, uses an LCG as the internal state but outputs a permuted/scrambled view of the state to improve quality.
The canonical 64-bit variant uses a 128-bit LCG transition along with the
XSL-RRoutput permutation.Distance
✔ PractRand
Adoption: Default in NumPy since 1.17 (2019).
⚠️ Requires 128-bit arithmetic
✔ Very strong quality despite a simple underlying principle
✔ Easy stream separation via distinct increments and efficient jump operations
2. Xoshiro256++
Xorshift-based generator using simple bitwise operations and output scrambling. The ++ output function provides decent bit mixing with fast performance.
Long-jump
✔ PractRand
Adoption: Default in Julia since 1.7 (2021).
⚠️ Low-order bits show statistical weakness but doesn't matter for 53-bit float generation
✔ Excellent speed with simplicity due to minimal arithmetic operations
✔ Fixed jump-ahead and long-jump operations for parallel stream generation
3. Philox4x32-10
Counter-based generator that repeatedly scrambles a counter using a key to produce random output blocks. Each unique counter/key pair generates a deterministic block independently, with no need to maintain a running state.
This variant uses 10 rounds of simple mixing operations on 4 32-bit words.
✔ PractRand
Adoption: Default in TensorFlow and PyTorch (CUDA).
⚠️ Heavier per-sample arithmetic than simple recurrence generators like PCG or Xoshiro
✔ Trivial stream partitioning via counter/key without jump operations
✔ Ideal for GPU and parallel batch generation with independent threads
4. PCG32
32-bit PCG variant using a 64-bit LCG transition along with the
XSH-RRoutput permutation.Distance
✔ PractRand
Adoption: Common in game engines, default in Godot.
⚠️ Requires 64-bit arithmetic
✔ Strong statistical quality with very small state
5. Xoshiro128**
32-bit xoshiro variant with ** output mixing.
Long-jump
✔ PractRand
Adoption: Widely recognized for strong statistical quality in 32-bit systems.
⚠️ Low-order bits weaker than high bits
✔ Strongest statistical quality of 32-bit xoshiro variants
6. Threefry4x32-20
Counter-based generator using Threefish-derived scrambling, stateless like Philox.
✔ PractRand
Adoption: Random123 library and functional computation.
✔ Only add/xor/rotate operations; no multiplication required
✔ More CPU friendly than Philox
7. SFC32
Small Fast Chaotic generator with explicit counter term for ensuring minimum period.
✔ PractRand
Adoption: Popular in game dev and procedural generation.
⚠️ Period is seed-dependent, with a minimum of 232
✔ Excellent speed and compactness
8. MRG32k3a
3rd order Combined Multiple Recursive Generator by L'Ecuyer.
Substreams
✔ PractRand
Adoption: Industry standard in high-stakes Monte Carlo simulations.
⚠️ Slower than modern counterparts with equivalent periods
✔ Strong theoretical framework for independent streams
9. Ranlux48
Luxury-level subtract-with-borrow generator utilizing chaotic dynamics theory.
~10171
✔ PractRand
Adoption: Used in CERN and high quality physics simulations.
⚠️ Significantly slower than other generators due to luxury skipping
✔ Gold standard of theoretical randomness
✔ Configurable quality via luxury levels
10. Xoshiro128++
32-bit xoshiro variant with ++ output mixing.
Long-jump
✔ PractRand
Adoption: Popular in embedded systems
⚠️ Still inherits low-bit caveats of xoshiro family
✔ Very fast in tight loops
11. JSF32
Jenkins Small Fast generator based on chaotic transitions.
✔ PractRand
Adoption: Used in lightweight RNG libraries and benchmark suites.
✔ Tiny implementation and strong speed profile
⚠️ Unpredictable period due to chaotic nature
Why this project?
Random number generation has always intrigued me, especially the idea that deterministic algorithms can produce seemingly random outputs feels like a paradox. This project offers a perfect opportunity to dive deep into the intricacies of PRNGs and explore how they are designed and optimized. The algorithmic challenges involved in implementing various PRNGs excite me, as they remind me of tackling problems in competitive programming where efficiency and precision are of utmost importance. I’m eager to contribute to this project and deepen my understanding of a critical area of computer science that has broad applications in fields like cryptography, simulations, and gaming.
Qualifications
As a competitive programmer, I have solid experience with algorithmic analysis, bit manipulation and modular arithmetic which are core concepts in PRNG algorithms and that makes this project a natural fit for me. Additionally, I’ve completed academic courses like Algorithms and Data Structures, Discrete Mathematics, Digital Logic Design, and Microprocessors, giving me a strong foundation in computational principles.
My familiarity with low-level performance concepts such as instruction pipelining, CPU cache behavior, and register pressure, as well as my long-standing interest in big-integer arithmetic, is perfectly suited to building efficient PRNG implementations in this project.
I’ve also demonstrated my familiarity with the stdlib codebase and PRNG internals by contributing two new PRNG implementations, which are awaiting approval and I’m currently studying research papers by various PRNG designers to understand the core ideas behind their algorithms.
Prior art
Source materials
Most of the PRNGs proposed in this project have accompanying papers which are listed below:
Others are described in blog posts and public sources:
Reference Implementations
PCG: Official C Implementation (GitHub)
Xoshiro: Author's C Implementations (xoshiro.di.unimi.it)
Philox and Threefry: Random123 Library (GitHub)
SFC: PractRand Source
JSF: Reference C Code by Bob Jenkins
SeedSequence: NumPy source
Additional materials used for PRNG selection
Commitment
I plan to invest ~30 hr/week during the GSoC period for a total of 350 hours. My 3rd-year finals will be over by April and I'll be able to fully dedicate my time to this project as I have no other commitments during this period.
Schedule
Assuming a 12 week schedule, below is a draft timeline for realizing the project goals.
Community Bonding Period:
Week C1: Scoping and API alignment
Week C2:
Uint64/128helpers and scaffolding setupUint64/128arithmetic helper functions that can be included separately inside PRNG packagesWeek C3:
Uint64/128packages and old PR reviewUint64/128APIs and start implementing full fledged packages undernumber/uint64andnumber/uint128Week 1: 32-bit Xoshiro variants
Uint64/128Week 2: 32-bit chaotic generators
Uint64/128Week 3: 32-bit counter-based generators
Uint64/128Week 4: Buffer & 64-bit Xoshiro
Week 5: 64-bit PCG & NumPy compatibility
Week 6: Midterm & scaffolding preparation
Week 7: CMRG and metadata
Week 8: Ranlux and metadata
Week 9: Wrappers and default scouting
arrayanditerwrappers for all new PRNGsWeek 10: Wrappers and default migration
streamandstridedwrappers for all new PRNGsWeek 11: Buffer
Week 12: Finishing
Final Week: Submission
Related issues
Checklist
[RFC]:and succinctly describes your proposal.