mirror of
https://github.com/gonum/gonum.git
synced 2025-09-27 03:26:04 +08:00

Changes made in dsp/fourier/internal/fftpack break the formatting used there, so these are reverted. There will be complaints in CI. [git-generate] gofmt -w . go generate gonum.org/v1/gonum/blas go generate gonum.org/v1/gonum/blas/gonum go generate gonum.org/v1/gonum/unit go generate gonum.org/v1/gonum/unit/constant go generate gonum.org/v1/gonum/graph/formats/dot go generate gonum.org/v1/gonum/graph/formats/rdf go generate gonum.org/v1/gonum/stat/card git checkout -- dsp/fourier/internal/fftpack
167 lines
3.5 KiB
Go
167 lines
3.5 KiB
Go
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Copyright ©2015 The Gonum Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package math32
|
|
|
|
import (
|
|
"math"
|
|
)
|
|
|
|
const (
|
|
unan = 0x7fc00000
|
|
uinf = 0x7f800000
|
|
uneginf = 0xff800000
|
|
mask = 0x7f8 >> 3
|
|
shift = 32 - 8 - 1
|
|
bias = 127
|
|
)
|
|
|
|
// Abs returns the absolute value of x.
|
|
//
|
|
// Special cases are:
|
|
//
|
|
// Abs(±Inf) = +Inf
|
|
// Abs(NaN) = NaN
|
|
func Abs(x float32) float32 {
|
|
switch {
|
|
case x < 0:
|
|
return -x
|
|
case x == 0:
|
|
return 0 // return correctly abs(-0)
|
|
}
|
|
return x
|
|
}
|
|
|
|
// Copysign returns a value with the magnitude
|
|
// of x and the sign of y.
|
|
func Copysign(x, y float32) float32 {
|
|
const sign = 1 << 31
|
|
return math.Float32frombits(math.Float32bits(x)&^sign | math.Float32bits(y)&sign)
|
|
}
|
|
|
|
// Hypot returns Sqrt(p*p + q*q), taking care to avoid
|
|
// unnecessary overflow and underflow.
|
|
//
|
|
// Special cases are:
|
|
//
|
|
// Hypot(±Inf, q) = +Inf
|
|
// Hypot(p, ±Inf) = +Inf
|
|
// Hypot(NaN, q) = NaN
|
|
// Hypot(p, NaN) = NaN
|
|
func Hypot(p, q float32) float32 {
|
|
// special cases
|
|
switch {
|
|
case IsInf(p, 0) || IsInf(q, 0):
|
|
return Inf(1)
|
|
case IsNaN(p) || IsNaN(q):
|
|
return NaN()
|
|
}
|
|
if p < 0 {
|
|
p = -p
|
|
}
|
|
if q < 0 {
|
|
q = -q
|
|
}
|
|
if p < q {
|
|
p, q = q, p
|
|
}
|
|
if p == 0 {
|
|
return 0
|
|
}
|
|
q = q / p
|
|
return p * Sqrt(1+q*q)
|
|
}
|
|
|
|
// Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
|
|
func Inf(sign int) float32 {
|
|
var v uint32
|
|
if sign >= 0 {
|
|
v = uinf
|
|
} else {
|
|
v = uneginf
|
|
}
|
|
return math.Float32frombits(v)
|
|
}
|
|
|
|
// IsInf reports whether f is an infinity, according to sign.
|
|
// If sign > 0, IsInf reports whether f is positive infinity.
|
|
// If sign < 0, IsInf reports whether f is negative infinity.
|
|
// If sign == 0, IsInf reports whether f is either infinity.
|
|
func IsInf(f float32, sign int) bool {
|
|
// Test for infinity by comparing against maximum float.
|
|
// To avoid the floating-point hardware, could use:
|
|
// x := math.Float32bits(f);
|
|
// return sign >= 0 && x == uinf || sign <= 0 && x == uneginf;
|
|
return sign >= 0 && f > math.MaxFloat32 || sign <= 0 && f < -math.MaxFloat32
|
|
}
|
|
|
|
// IsNaN reports whether f is an IEEE 754 “not-a-number” value.
|
|
func IsNaN(f float32) (is bool) {
|
|
// IEEE 754 says that only NaNs satisfy f != f.
|
|
// To avoid the floating-point hardware, could use:
|
|
// x := math.Float32bits(f);
|
|
// return uint32(x>>shift)&mask == mask && x != uinf && x != uneginf
|
|
return f != f
|
|
}
|
|
|
|
// Max returns the larger of x or y.
|
|
//
|
|
// Special cases are:
|
|
//
|
|
// Max(x, +Inf) = Max(+Inf, x) = +Inf
|
|
// Max(x, NaN) = Max(NaN, x) = NaN
|
|
// Max(+0, ±0) = Max(±0, +0) = +0
|
|
// Max(-0, -0) = -0
|
|
func Max(x, y float32) float32 {
|
|
// special cases
|
|
switch {
|
|
case IsInf(x, 1) || IsInf(y, 1):
|
|
return Inf(1)
|
|
case IsNaN(x) || IsNaN(y):
|
|
return NaN()
|
|
case x == 0 && x == y:
|
|
if Signbit(x) {
|
|
return y
|
|
}
|
|
return x
|
|
}
|
|
if x > y {
|
|
return x
|
|
}
|
|
return y
|
|
}
|
|
|
|
// Min returns the smaller of x or y.
|
|
//
|
|
// Special cases are:
|
|
//
|
|
// Min(x, -Inf) = Min(-Inf, x) = -Inf
|
|
// Min(x, NaN) = Min(NaN, x) = NaN
|
|
// Min(-0, ±0) = Min(±0, -0) = -0
|
|
func Min(x, y float32) float32 {
|
|
// special cases
|
|
switch {
|
|
case IsInf(x, -1) || IsInf(y, -1):
|
|
return Inf(-1)
|
|
case IsNaN(x) || IsNaN(y):
|
|
return NaN()
|
|
case x == 0 && x == y:
|
|
if Signbit(x) {
|
|
return x
|
|
}
|
|
return y
|
|
}
|
|
if x < y {
|
|
return x
|
|
}
|
|
return y
|
|
}
|
|
|
|
// NaN returns an IEEE 754 “not-a-number” value.
|
|
func NaN() float32 { return math.Float32frombits(unan) }
|