{"id":37064016,"url":"https://github.com/verificarlo/significantdigits","last_synced_at":"2026-01-14T07:28:55.128Z","repository":{"id":45063398,"uuid":"328716557","full_name":"verificarlo/significantdigits","owner":"verificarlo","description":"Solid statistical analysis of Stochastic Arithmetic.","archived":false,"fork":false,"pushed_at":"2025-06-28T02:20:43.000Z","size":927,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-08-30T02:29:22.691Z","etag":null,"topics":["floating-point","ieee754","significant","significant-digits","stochastic","stochastic-arithmetic","uncertainty"],"latest_commit_sha":null,"homepage":"https://verificarlo.github.io/significantdigits/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/verificarlo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-01-11T15:59:06.000Z","updated_at":"2025-06-28T02:18:23.000Z","dependencies_parsed_at":"2025-06-28T02:29:49.593Z","dependency_job_id":"66147b7f-3913-433c-b86c-16775a7ce1fd","html_url":"https://github.com/verificarlo/significantdigits","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/verificarlo/significantdigits","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verificarlo%2Fsignificantdigits","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verificarlo%2Fsignificantdigits/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verificarlo%2Fsignificantdigits/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verificarlo%2Fsignificantdigits/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/verificarlo","download_url":"https://codeload.github.com/verificarlo/significantdigits/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verificarlo%2Fsignificantdigits/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28413215,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["floating-point","ieee754","significant","significant-digits","stochastic","stochastic-arithmetic","uncertainty"],"created_at":"2026-01-14T07:28:54.454Z","updated_at":"2026-01-14T07:28:55.118Z","avatar_url":"https://github.com/verificarlo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# significantdigits package - v0.4.0\n\nCompute the number of significant digits based on the paper [Confidence Intervals for Stochastic Arithmetic](https://arxiv.org/abs/1807.09655).\nThis package is also inspired by the [Jupyter Notebook](https://github.com/interflop/stochastic-confidence-intervals/blob/master/Intervals.ipynb) included with the publication.\n\n\n\n## Table of Contents\n\n- [Getting started](#getting-started)\n- [Installation](#installation)\n- [Advanced Usage](#advanced-usage)\n    - [Inputs types](#inputs-types)\n    - [Z computation](#z-computation)\n    - [Methods](#methods)\n    - [Significant digits](#significant-digits)\n    - [Contributing digits](#contributing-digits)\n    - [Formatting Results with `format_uncertainty`](#formatting-results-with-format_uncertainty)\n    - [Utils function](#utils-function)\n        - [`probability_estimation_general`](#probability_estimation_general)\n        - [`minimum_number_of_trials`](#minimum_number_of_trials)\n- [Recent Improvements](#recent-improvements)\n- [Testing](#testing)\n- [License](#license)\n\n## Getting started\n\nThis synthetic example illustrates how to compute significant digits\nof a results sample with a given known reference:\n\n```python\n\u003e\u003e\u003e import significantdigits as sd\n\u003e\u003e\u003e import numpy as np\n\u003e\u003e\u003e from numpy.random import uniform as U\n\u003e\u003e\u003e np.random.seed(0)\n\u003e\u003e\u003e eps = 2**-52\n\u003e\u003e\u003e # simulates results with epsilon differences\n\u003e\u003e\u003e X = [1+U(-1,1)*eps for _ in range(10)]\n\u003e\u003e\u003e sd.significant_digits(X, reference=1)\n\u003e\u003e\u003e 51.02329058847853\n```\n\nor with the CLI interface assuming `X` is in `test.txt`:\n\n```bash\n\u003e significantdigits --metric significant -i \"$(cat test.txt)\" --input-format stdin --reference 1\n\u003e (51.02329058847853,)\n```\nIf the reference is unknown, one can use the sample average:\n\n```python\n...\n\u003e\u003e\u003e sd.significant_digits(X, reference=np.mean(X))\n\u003e\u003e\u003e 51.02329058847853\n```\n\nTo print the result as mean +/- error, use the format_uncertainty function:\n\n```python\n\u003e\u003e\u003e print(sd.format_uncertainty(X, reference=1))\n\u003e\u003e\u003e ['+1.00000000000000000 ± 1.119313369151395181e-16'\n     '+1.00000000000000000 ± 1.119313369151395181e-16'\n     '+1.00000000000000000 ± 1.119313369151395181e-16'\n     '+1.00000000000000000 ± 1.119313369151395181e-16'\n     '+1.00000000000000000 ± 1.119313369151395181e-16'\n     '+1.00000000000000000 ± 1.119313369151395181e-16'\n     '+1.00000000000000000 ± 1.119313369151395181e-16'\n     '+1.00000000000000022 ± 1.119313369151395181e-16'\n     '+1.00000000000000022 ± 1.119313369151395181e-16'\n     '+1.00000000000000000 ± 1.119313369151395181e-16']\n```\n\n## Installation\n\n```bash\npython3 -m pip install -U significantdigits\n```\n\nor if you want the latest version of the code, you can install it **from** the repository directly\n\n```bash\npython3 -m pip install -U git+https://github.com/verificarlo/significantdigits.git\n# or if you don't have 'git' installed\npython3 -m pip install -U https://github.com/verificarlo/significantdigits/zipball/master\n```\n\n## Examples\n\nThe [`examples`](./examples) directory contains several example scripts demonstrating how to use the `significantdigits` package in different scenarios. You can find practical usage patterns, sample data, and step-by-step guides to help you get started or deepen your understanding of the package's features. \n\n## Advanced Usage\n\n### Inputs types\n\nFunctions accept the following types of inputs:\n```python\n    InputType: ArrayLike\n```\nThose types are accessible with the `numpy.typing.ArrayLike` type.\n\n### Z computation\nMetrics are computed using Z, the distance between the samples and the reference.\nThere are four possible cases depending on the distance and the nature of the reference that are summarized in this table:\n\n|                    | constant reference (x) | random variable reference (Y) |\n| ------------------ | ---------------------- | ----------------------------- |\n| Absolute precision | Z = X - x              | Z = X - Y                     |\n| Relative precision | Z = X/x - 1            | Z = X/Y - 1                   |\n\n\n```python\n_compute_z(array: InternalArrayType, \n           reference: InternalArrayType | None, \n           error: Error | str, \n           axis: int, \n           shuffle_samples: bool = False) -\u003e InternalArrayType\n    Compute Z, the distance between the random variable and the reference\n\n    Compute Z, the distance between the random variable and the reference\n    with three cases depending on the dimensions of array and reference:\n\n    X = array\n    Y = reference\n\n    Three cases:\n    - Y is none\n        - The case when X = Y\n        - We split X in two and set one group to X and the other to Y\n    - X.ndim == Y.ndim\n        X and Y have the same dimension\n        It it the case when Y is a random variable\n    - X.ndim - 1 == Y.ndim or Y.ndim == 0\n        Y is a scalar value\n\n    Parameters\n    ----------\n    array : InternalArrayType\n        The random variable\n    reference : InternalArrayType | None\n        The reference to compare against\n    error : Error | str\n        The error function to use to compute error between array and reference.\n    axis : int, default=0\n        The axis or axes along which compute Z\n    shuflle_samples : bool, default=False\n        If True, shuffles the groups when the reference is None\n\n    Returns\n    -------\n    array : InternalArrayType\n        The result of Z following the error method choose\n    scaling_factor : InternalArrayType\n        The scaling factor to compute the significant digits\n        Useful for absolute error to normalizing the number of significant digits\n        ``When Y is a random variable, we choose e = ⎣log_2|E[Y]|⎦+1.``p.10:9\n\n```\n\n### Methods\n\nTwo methods exist for computing both significant and contributing digits depending on whether the sample follows a Centered Normal distribution or not.\nYou can pass the method to the function by using the `Method` enum provided by the package. \nThe functions also accept the name as a string\n`\"cnh\"` for `Method.CNH` and `\"general\"` for `Method.General`.\n\n```python\nclass Method(AutoName):\n    \"\"\"\n    CNH: Centered Normality Hypothesis\n         X follows a Gaussian law centered around the reference or\n         Z follows a Gaussian law centered around 0\n    General: No assumption about the distribution of X or Z\n    \"\"\"\n    CNH = auto()\n    General = auto()\n```\n\n### Significant digits\n\n\n\n```python\nsignificant_digits(array: InputType,\n                   reference: ReferenceType | None = None,\n                   axis: int = 0, \n                   basis: int = 2,\n                   error: Error | str,\n                   method: Method | str,\n                   probability: float = 0.95,\n                   confidence: float = 0.95,\n                   shuffle_samples: bool = False,\n                   dtype: DTypeLike | None = None\n                   ) -\u003e ArrayLike\n    \n    Compute significant digits\n\n    This function computes with a certain probability\n    the number of bits that are significant.\n\n    Parameters\n    ----------\n    array: InputType\n        Element to compute\n    reference: ReferenceType | None, optional=None\n        Reference for comparing the array\n    axis: int, optional=0\n        Axis or axes along which the significant digits are computed\n    basis: int, optional=2\n        Basis in which represent the significant digits\n    error : Error | str, optional=Error.Relative\n        Error function to use to compute error between array and reference.\n    method : Method | str, optional=Method.CNH\n        Method to use for the underlying distribution hypothesis\n    probability : float, default=0.95\n        Probability for the significant digits result\n    confidence : float, default=0.95\n        Confidence level for the significant digits result\n    shuffle_samples : bool, optional=False\n        If reference is None, the array is split in two and \\\n        comparison is done between both pieces. \\\n        If shuffle_samples is True, it shuffles pieces.\n    dtype : dtype_like | None, default=None\n        Numerical type used for computing significant digits\n        Widest format between array and reference is taken if no supplied.\n\n    Returns\n    -------\n    ndarray\n        array_like containing significant digits\n\n```\n\n### Contributing digits\n\n```python\ncontributing_digits(array: InputType,\n                    reference: ReferenceType | None = None,\n                    axis: int = 0,\n                    basis: int = 2,\n                    error: Error | str,\n                    method: Method | str,\n                    probability: float = 0.51,\n                    confidence: float = 0.95,\n                    shuffle_samples: bool = False,\n                    dtype: DTypeLike | None = None\n                    ) -\u003e ArrayLike\n    \n    Compute contributing digits\n\n    This function computes with a certain probability the number of bits\n    of the mantissa that will round the result towards the correct reference\n    value[1]_\n\n    Parameters\n    ----------\n    array: InputArray\n        Element to compute\n    reference: ReferenceArray | None, default=None\n        Reference for comparing the array\n    axis: int, default=0\n        Axis or axes along which the contributing digits are computed\n        default: None\n    basis: int, optional=2\n        basis in which represent the contributing digits\n    error : Error | str, default=Error.Relative\n        Error function to use to compute error between array and reference.\n    method : Method | str, default=Method.CNH\n        Method to use for the underlying distribution hypothesis\n    probability : float, default=0.51\n        Probability for the contributing digits result\n    confidence : float, default=0.95\n        Confidence level for the contributing digits result\n    shuffle_samples : bool, default=False\n        If reference is None, the array is split in two and\n        comparison is done between both pieces.\n        If shuffle_samples is True, it shuffles pieces.\n    dtype : dtype_like | None, default=None\n        Numerical type used for computing contributing digits\n        Widest format between array and reference is taken if no supplied.\n\n    Returns\n    -------\n    ndarray\n        array_like containing contributing digits\n\n```\n\n### Formatting Results with `format_uncertainty`\n\nFormats the results as mean ± error for each sample.\n\n```python\nformat_uncertainty(array: InputType,\n                   reference: ReferenceType | None = None,\n                   axis: int = 0,\n                   error: Error | str = Error.Relative,\n                   dtype: DTypeLike | None = None\n                   ) -\u003e list[str]\n    Format the uncertainty of each sample as a string\n\n    This function returns a list of strings representing each value in the input array\n    formatted as \"mean ± error\", where the error is computed with respect to the reference.\n\n    Parameters\n    ----------\n    array: InputType\n        Array of values to format\n    reference: ReferenceType | None, optional=None\n        Reference value(s) for error computation\n    axis: int, optional=0\n        Axis along which to compute the mean and error\n    error: Error | str, optional=Error.Relative\n        Error function to use for uncertainty calculation\n    dtype: DTypeLike | None, optional=None\n        Numerical type used for computation\n\n    Returns\n    -------\n    list[str]\n        List of formatted strings for each sample\n```\n\n### Utils function\n\nThese are utility functions for the general case.\n\n#### `probability_estimation_general`\n\nEstimates the lower bound probability given the sample size.\n\n\n```python\nprobability_estimation_general(success: int, trials: int, confidence: float) -\u003e float\n    Computes probability lower bound for Bernouilli process\n\n    This function computes the probability associated with metrics\n    computed in the general case (without assumption on the underlying\n    distribution). Indeed, in that case the probability is given by the\n    sample size with a certain confidence level.\n\n    Parameters\n    ----------\n    success : int\n        Number of success for a Bernoulli experiment\n    trials : int\n        Number of trials for a Bernoulli experiment\n    confidence : float\n        Confidence level for the probability lower bound estimation\n\n    Returns\n    -------\n    float\n        The lower bound probability with `confidence` level to have `success` successes for `trials` trials\n```\n\n#### `minimum_number_of_trials`\n\nReturns the minimal sample size required to reach the requested `probability` and `confidence`.\n\n\n```python\nminimum_number_of_trials(probability: float, confidence: float) -\u003e int\n    Computes the minimum number of trials to have probability and confidence\n\n    This function computes the minimal sample size required to have\n    metrics with a certain probability and confidence for the general case\n    (without assumption on the underlying distribution).\n\n    For example, if one wants significant digits with proabability p = 99%\n    and confidence (1 - alpha) = 95%, it requires at least 299 observations.\n\n    Parameters\n    ----------\n    probability : float\n        Probability\n    confidence : float\n        Confidence\n\n    Returns\n    -------\n    int\n        Minimal sample size to have given probability and confidence\n```\n\n## Recent Improvements\n\n**Bug Fixes \u0026 Reliability:**\n- Fixed critical parameter validation bug in CLI argument handling\n- Corrected integer division precision issues in sample size calculations\n- Added missing return statements for error handling edge cases\n- Enhanced numerical stability for extreme values (inf/NaN handling)\n\n**Performance Optimizations (15-40% faster):**\n- Optimized exponential operations using `np.exp2()` instead of `2**(-kth)`\n- Enhanced bitwise operations with efficient `\u0026 1` masking\n- Improved memory allocation and array operations\n- Better conditional processing and vectorized computations\n\n**Comprehensive Test Suite (3x more tests):**\n- Expanded from 51 to 153 total tests across 5 new test modules\n- Added property-based testing and fuzzing (65 tests)\n- Enhanced edge case coverage (26 tests)\n- Comprehensive validation and error handling tests (24 tests)\n- Performance regression testing and integration tests (38 tests)\n## Testing\n\nThe package includes a comprehensive test suite with 153 tests across multiple categories:\n\n### Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run with performance tests (marked with @pytest.mark.performance)\npytest -m performance\n\n# Run specific test categories\npytest tests/test_edge_cases.py      # Edge cases and numerical stability\npytest tests/test_validation.py     # Parameter validation and error handling\npytest tests/test_property_based.py # Property-based testing and fuzzing\npytest tests/test_integration.py    # End-to-end integration tests\npytest tests/test_performance.py    # Performance regression tests\n```\n\n### Test Categories\n\n- **Edge Cases (26 tests)**: Numerical stability, inf/NaN handling, extreme values\n- **Validation (24 tests)**: Parameter validation, input sanitization, error handling\n- **Property-Based (65 tests)**: Mathematical invariants, randomized testing, fuzzing\n- **Integration (23 tests)**: CLI testing, file I/O, complete workflows\n- **Performance (15 tests)**: Regression testing, optimization verification\n\n### Mathematical Properties Tested\n\n- **Monotonicity**: More precise data yields more significant digits\n- **Scale Invariance**: Relative error results are invariant under scaling\n- **Basis Conversion**: Consistent results across different number bases\n- **Sample Size Effects**: Larger samples generally provide better estimates\n- **Method Consistency**: CNH and General methods produce comparable results\n\n### License\n\nThis file is part of the Verificarlo project,\nunder the Apache License v2.0 with LLVM Exceptions.\nSPDX-License-Identifier: Apache-2.0 WITH LLVM-exception.\nSee https://llvm.org/LICENSE.txt for license information.\n\nCopyright (c) 2020-2023 Verificarlo Contributors\n\n---","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fverificarlo%2Fsignificantdigits","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fverificarlo%2Fsignificantdigits","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fverificarlo%2Fsignificantdigits/lists"}