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 }