gonum.org/v1/gonum@v0.14.0/cmplxs/cscalar/cscalar.go (about)

     1  // Copyright ©2013 The Gonum Authors. All rights reserved.
     2  // Use of this code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package cscalar
     6  
     7  import (
     8  	"math"
     9  	"math/cmplx"
    10  
    11  	"gonum.org/v1/gonum/floats/scalar"
    12  )
    13  
    14  // EqualWithinAbs returns true when a and b have an absolute difference
    15  // not greater than tol.
    16  func EqualWithinAbs(a, b complex128, tol float64) bool {
    17  	return a == b || cmplx.Abs(a-b) <= tol
    18  }
    19  
    20  // minNormalFloat64 is the smallest normal number. For 64 bit IEEE-754
    21  // floats this is 2^{-1022}.
    22  const minNormalFloat64 = 0x1p-1022
    23  
    24  // EqualWithinRel returns true when the difference between a and b
    25  // is not greater than tol times the greater absolute value of a and b,
    26  //
    27  //	abs(a-b) <= tol * max(abs(a), abs(b)).
    28  func EqualWithinRel(a, b complex128, tol float64) bool {
    29  	if a == b {
    30  		return true
    31  	}
    32  
    33  	delta := cmplx.Abs(a - b)
    34  	if delta <= minNormalFloat64 {
    35  		return delta <= tol*minNormalFloat64
    36  	}
    37  	// We depend on the division in this relationship to identify
    38  	// infinities.
    39  	return delta/math.Max(cmplx.Abs(a), cmplx.Abs(b)) <= tol
    40  }
    41  
    42  // EqualWithinAbsOrRel returns true when a and b are equal to within
    43  // the absolute or relative tolerances. See EqualWithinAbs and
    44  // EqualWithinRel for details.
    45  func EqualWithinAbsOrRel(a, b complex128, absTol, relTol float64) bool {
    46  	return EqualWithinAbs(a, b, absTol) || EqualWithinRel(a, b, relTol)
    47  }
    48  
    49  // ParseWithNA converts the string s to a complex128 in value.
    50  // If s equals missing, weight is returned as 0, otherwise 1.
    51  func ParseWithNA(s, missing string) (value complex128, weight float64, err error) {
    52  	if s == missing {
    53  		return 0, 0, nil
    54  	}
    55  	value, err = parse(s)
    56  	if err == nil {
    57  		weight = 1
    58  	}
    59  	return value, weight, err
    60  }
    61  
    62  // Round returns the half away from zero rounded value of x with prec precision.
    63  //
    64  // Special cases are:
    65  //
    66  //	Round(±0) = +0
    67  //	Round(±Inf) = ±Inf
    68  //	Round(NaN) = NaN
    69  func Round(x complex128, prec int) complex128 {
    70  	if x == 0 {
    71  		// Make sure zero is returned
    72  		// without the negative bit set.
    73  		return 0
    74  	}
    75  	return complex(scalar.Round(real(x), prec), scalar.Round(imag(x), prec))
    76  }
    77  
    78  // RoundEven returns the half even rounded value of x with prec precision.
    79  //
    80  // Special cases are:
    81  //
    82  //	RoundEven(±0) = +0
    83  //	RoundEven(±Inf) = ±Inf
    84  //	RoundEven(NaN) = NaN
    85  func RoundEven(x complex128, prec int) complex128 {
    86  	if x == 0 {
    87  		// Make sure zero is returned
    88  		// without the negative bit set.
    89  		return 0
    90  	}
    91  	return complex(scalar.RoundEven(real(x), prec), scalar.RoundEven(imag(x), prec))
    92  }
    93  
    94  // Same returns true when the inputs have the same value, allowing NaN equality.
    95  func Same(a, b complex128) bool {
    96  	return a == b || (cmplx.IsNaN(a) && cmplx.IsNaN(b))
    97  }