Source code for sluyspy.numerics

# -*- coding: utf-8 -*-
# SPDX-License-Identifier: EUPL-1.2
#  
#  Copyright (c) 2022-2024  Marc van der Sluys - Nikhef/Utrecht University - marc.vandersluys.nl
#  
#  This file is part of the sluyspy Python package:
#  Marc van der Sluys' personal Python modules.
#  See: https://github.com/MarcvdSluys/sluyspy
#  
#  This is free software: you can redistribute it and/or modify it under the terms of the European Union
#  Public Licence 1.2 (EUPL 1.2).  This software is distributed in the hope that it will be useful, but
#  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
#  PURPOSE.  See the EU Public Licence for more details.  You should have received a copy of the European
#  Union Public Licence along with this code.  If not, see <https://www.eupl.eu/1.2/en/>.


"""Numerics stuff for the sluyspy package"""


import numpy as _np
import astroconst as _ac


eps  = _np.finfo(_np.float64).eps;  """Smallest value for which 1+eps != 1:  2.2204460492503131e-16"""
eps1 = 1 + eps;                     """Smallest value larger than 1:  1 + 2.2204460492503131e-16"""
tiny = _np.nextafter(0, 1);         """Smallest value larger than 0: 4.9406564584124654e-324"""


[docs] def sigdig(num, dig=14): """Return a string with a given number using (at most) the specified number of significant digits. Parameters: num (float): Number to print. dig (int): Number of significant digits to use (optional; defaults to 14 to avoid machine rounding). Returns: (struct): Struct containing command-line arguments. Note: - Trailing zeros are NOT printed - hence, this function does not EXACTLY print the desired number of significant digits; - 0.075 with a single digit is printed as 0.07, hence multiply with eps1! See: E.g. the discussions here: https://stackoverflow.com/q/3410976/1386750 """ if num is None: sigdig = 'None' else: fmt = '%%0.%ig' % (dig) sigdig = fmt % (num * eps1) # w/o snum.eps1, (0.075,1) will be written as 0.07! return sigdig
[docs] def map_pi_pi(ang): """Map an (array of) angle(s) to lie between -PI and +PI. Parameters: ang (float): (Array of) angle(s). Returns: (float): (Array) of angles between -PI and +PI. """ return _np.mod(ang+_ac.pi, _ac.pi2)-_ac.pi
[docs] def nint(val): """Convert a float to the nearest integer with proper rounding. Parameters: val (float): Value to convert. Returns: (int): Nearest integer (or float('nan')). """ if _np.isnan(val): nint = float('nan') else: nint = int(_np.round(val,0)) return nint