github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/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/jingcheng-WU/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 }