github.com/gopherd/gonum@v0.0.4/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  	"github.com/gopherd/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  //  abs(a-b) <= tol * max(abs(a), abs(b)).
    27  func EqualWithinRel(a, b complex128, tol float64) bool {
    28  	if a == b {
    29  		return true
    30  	}
    31  
    32  	delta := cmplx.Abs(a - b)
    33  	if delta <= minNormalFloat64 {
    34  		return delta <= tol*minNormalFloat64
    35  	}
    36  	// We depend on the division in this relationship to identify
    37  	// infinities.
    38  	return delta/math.Max(cmplx.Abs(a), cmplx.Abs(b)) <= tol
    39  }
    40  
    41  // EqualWithinAbsOrRel returns true when a and b are equal to within
    42  // the absolute or relative tolerances. See EqualWithinAbs and
    43  // EqualWithinRel for details.
    44  func EqualWithinAbsOrRel(a, b complex128, absTol, relTol float64) bool {
    45  	return EqualWithinAbs(a, b, absTol) || EqualWithinRel(a, b, relTol)
    46  }
    47  
    48  // ParseWithNA converts the string s to a complex128 in value.
    49  // If s equals missing, weight is returned as 0, otherwise 1.
    50  func ParseWithNA(s, missing string) (value complex128, weight float64, err error) {
    51  	if s == missing {
    52  		return 0, 0, nil
    53  	}
    54  	value, err = parse(s)
    55  	if err == nil {
    56  		weight = 1
    57  	}
    58  	return value, weight, err
    59  }
    60  
    61  // Round returns the half away from zero rounded value of x with prec precision.
    62  //
    63  // Special cases are:
    64  // 	Round(±0) = +0
    65  // 	Round(±Inf) = ±Inf
    66  // 	Round(NaN) = NaN
    67  func Round(x complex128, prec int) complex128 {
    68  	if x == 0 {
    69  		// Make sure zero is returned
    70  		// without the negative bit set.
    71  		return 0
    72  	}
    73  	return complex(scalar.Round(real(x), prec), scalar.Round(imag(x), prec))
    74  }
    75  
    76  // RoundEven returns the half even rounded value of x with prec precision.
    77  //
    78  // Special cases are:
    79  // 	RoundEven(±0) = +0
    80  // 	RoundEven(±Inf) = ±Inf
    81  // 	RoundEven(NaN) = NaN
    82  func RoundEven(x complex128, prec int) complex128 {
    83  	if x == 0 {
    84  		// Make sure zero is returned
    85  		// without the negative bit set.
    86  		return 0
    87  	}
    88  	return complex(scalar.RoundEven(real(x), prec), scalar.RoundEven(imag(x), prec))
    89  }
    90  
    91  // Same returns true when the inputs have the same value, allowing NaN equality.
    92  func Same(a, b complex128) bool {
    93  	return a == b || (cmplx.IsNaN(a) && cmplx.IsNaN(b))
    94  }