fixed dependencies
This commit is contained in:
96
vendor/github.com/mjibson/go-dsp/dsputils/compare.go
generated
vendored
Normal file
96
vendor/github.com/mjibson/go-dsp/dsputils/compare.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Matt Jibson <matt.jibson@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package dsputils
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
const (
|
||||
closeFactor = 1e-8
|
||||
)
|
||||
|
||||
// PrettyClose returns true if the slices a and b are very close, else false.
|
||||
func PrettyClose(a, b []float64) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, c := range a {
|
||||
if !Float64Equal(c, b[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// PrettyCloseC returns true if the slices a and b are very close, else false.
|
||||
func PrettyCloseC(a, b []complex128) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, c := range a {
|
||||
if !ComplexEqual(c, b[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// PrettyClose2 returns true if the matrixes a and b are very close, else false.
|
||||
func PrettyClose2(a, b [][]complex128) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, c := range a {
|
||||
if !PrettyCloseC(c, b[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// PrettyClose2F returns true if the matrixes a and b are very close, else false.
|
||||
func PrettyClose2F(a, b [][]float64) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, c := range a {
|
||||
if !PrettyClose(c, b[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ComplexEqual returns true if a and b are very close, else false.
|
||||
func ComplexEqual(a, b complex128) bool {
|
||||
r_a := real(a)
|
||||
r_b := real(b)
|
||||
i_a := imag(a)
|
||||
i_b := imag(b)
|
||||
|
||||
return Float64Equal(r_a, r_b) && Float64Equal(i_a, i_b)
|
||||
}
|
||||
|
||||
// Float64Equal returns true if a and b are very close, else false.
|
||||
func Float64Equal(a, b float64) bool {
|
||||
return math.Abs(a-b) <= closeFactor || math.Abs(1-a/b) <= closeFactor
|
||||
}
|
||||
115
vendor/github.com/mjibson/go-dsp/dsputils/dsputils.go
generated
vendored
Normal file
115
vendor/github.com/mjibson/go-dsp/dsputils/dsputils.go
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Matt Jibson <matt.jibson@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
// Package dsputils provides functions useful in digital signal processing.
|
||||
package dsputils
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
// ToComplex returns the complex equivalent of the real-valued slice.
|
||||
func ToComplex(x []float64) []complex128 {
|
||||
y := make([]complex128, len(x))
|
||||
for n, v := range x {
|
||||
y[n] = complex(v, 0)
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
// IsPowerOf2 returns true if x is a power of 2, else false.
|
||||
func IsPowerOf2(x int) bool {
|
||||
return x&(x-1) == 0
|
||||
}
|
||||
|
||||
// NextPowerOf2 returns the next power of 2 >= x.
|
||||
func NextPowerOf2(x int) int {
|
||||
if IsPowerOf2(x) {
|
||||
return x
|
||||
}
|
||||
|
||||
return int(math.Pow(2, math.Ceil(math.Log2(float64(x)))))
|
||||
}
|
||||
|
||||
// ZeroPad returns x with zeros appended to the end to the specified length.
|
||||
// If len(x) >= length, x is returned, otherwise a new array is returned.
|
||||
func ZeroPad(x []complex128, length int) []complex128 {
|
||||
if len(x) >= length {
|
||||
return x
|
||||
}
|
||||
|
||||
r := make([]complex128, length)
|
||||
copy(r, x)
|
||||
return r
|
||||
}
|
||||
|
||||
// ZeroPadF returns x with zeros appended to the end to the specified length.
|
||||
// If len(x) >= length, x is returned, otherwise a new array is returned.
|
||||
func ZeroPadF(x []float64, length int) []float64 {
|
||||
if len(x) >= length {
|
||||
return x
|
||||
}
|
||||
|
||||
r := make([]float64, length)
|
||||
copy(r, x)
|
||||
return r
|
||||
}
|
||||
|
||||
// ZeroPad2 returns ZeroPad of x, with the length as the next power of 2 >= len(x).
|
||||
func ZeroPad2(x []complex128) []complex128 {
|
||||
return ZeroPad(x, NextPowerOf2(len(x)))
|
||||
}
|
||||
|
||||
// ToComplex2 returns the complex equivalent of the real-valued matrix.
|
||||
func ToComplex2(x [][]float64) [][]complex128 {
|
||||
y := make([][]complex128, len(x))
|
||||
for n, v := range x {
|
||||
y[n] = ToComplex(v)
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
// Segment returns segs equal-length slices that are segments of x with noverlap% of overlap.
|
||||
// The returned slices are not copies of x, but slices into it.
|
||||
// Trailing entries in x that connot be included in the equal-length segments are discarded.
|
||||
// noverlap is a percentage, thus 0 <= noverlap <= 1, and noverlap = 0.5 is 50% overlap.
|
||||
func Segment(x []complex128, segs int, noverlap float64) [][]complex128 {
|
||||
lx := len(x)
|
||||
|
||||
// determine step, length, and overlap
|
||||
var overlap, length, step, tot int
|
||||
for length = lx; length > 0; length-- {
|
||||
overlap = int(float64(length) * noverlap)
|
||||
tot = segs*(length-overlap) + overlap
|
||||
if tot <= lx {
|
||||
step = length - overlap
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if length == 0 {
|
||||
panic("too many segments")
|
||||
}
|
||||
|
||||
r := make([][]complex128, segs)
|
||||
s := 0
|
||||
for n := range r {
|
||||
r[n] = x[s : s+length]
|
||||
s += step
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
216
vendor/github.com/mjibson/go-dsp/dsputils/matrix.go
generated
vendored
Normal file
216
vendor/github.com/mjibson/go-dsp/dsputils/matrix.go
generated
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Matt Jibson <matt.jibson@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package dsputils
|
||||
|
||||
// Matrix is a multidimensional matrix of arbitrary size and dimension.
|
||||
// It cannot be resized after creation. Arrays in any axis can be set or fetched.
|
||||
type Matrix struct {
|
||||
list []complex128
|
||||
dims, offsets []int
|
||||
}
|
||||
|
||||
// MakeMatrix returns a new Matrix populated with x having dimensions dims.
|
||||
// For example, to create a 3-dimensional Matrix with 2 components, 3 rows, and 4 columns:
|
||||
// MakeMatrix([]complex128 {
|
||||
// 1, 2, 3, 4,
|
||||
// 5, 6, 7, 8,
|
||||
// 9, 0, 1, 2,
|
||||
//
|
||||
// 3, 4, 5, 6,
|
||||
// 7, 8, 9, 0,
|
||||
// 4, 3, 2, 1},
|
||||
// []int {2, 3, 4})
|
||||
func MakeMatrix(x []complex128, dims []int) *Matrix {
|
||||
length := 1
|
||||
offsets := make([]int, len(dims))
|
||||
|
||||
for i := len(dims) - 1; i >= 0; i-- {
|
||||
if dims[i] < 1 {
|
||||
panic("invalid dimensions")
|
||||
}
|
||||
|
||||
offsets[i] = length
|
||||
length *= dims[i]
|
||||
}
|
||||
|
||||
if len(x) != length {
|
||||
panic("incorrect dimensions")
|
||||
}
|
||||
|
||||
dc := make([]int, len(dims))
|
||||
copy(dc, dims)
|
||||
return &Matrix{x, dc, offsets}
|
||||
}
|
||||
|
||||
// MakeMatrix2 is a helper function to convert a 2-d array to a matrix.
|
||||
func MakeMatrix2(x [][]complex128) *Matrix {
|
||||
dims := []int{len(x), len(x[0])}
|
||||
r := make([]complex128, dims[0]*dims[1])
|
||||
for n, v := range x {
|
||||
if len(v) != dims[1] {
|
||||
panic("ragged array")
|
||||
}
|
||||
|
||||
copy(r[n*dims[1]:(n+1)*dims[1]], v)
|
||||
}
|
||||
|
||||
return MakeMatrix(r, dims)
|
||||
}
|
||||
|
||||
// Copy returns a new copy of m.
|
||||
func (m *Matrix) Copy() *Matrix {
|
||||
r := &Matrix{m.list, m.dims, m.offsets}
|
||||
r.list = make([]complex128, len(m.list))
|
||||
copy(r.list, m.list)
|
||||
return r
|
||||
}
|
||||
|
||||
// MakeEmptyMatrix creates an empty Matrix with given dimensions.
|
||||
func MakeEmptyMatrix(dims []int) *Matrix {
|
||||
x := 1
|
||||
for _, v := range dims {
|
||||
x *= v
|
||||
}
|
||||
|
||||
return MakeMatrix(make([]complex128, x), dims)
|
||||
}
|
||||
|
||||
// offset returns the index in the one-dimensional array
|
||||
func (s *Matrix) offset(dims []int) int {
|
||||
if len(dims) != len(s.dims) {
|
||||
panic("incorrect dimensions")
|
||||
}
|
||||
|
||||
i := 0
|
||||
for n, v := range dims {
|
||||
if v > s.dims[n] {
|
||||
panic("incorrect dimensions")
|
||||
}
|
||||
|
||||
i += v * s.offsets[n]
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
func (m *Matrix) indexes(dims []int) []int {
|
||||
i := -1
|
||||
for n, v := range dims {
|
||||
if v == -1 {
|
||||
if i >= 0 {
|
||||
panic("only one dimension index allowed")
|
||||
}
|
||||
|
||||
i = n
|
||||
} else if v >= m.dims[n] {
|
||||
panic("dimension out of bounds")
|
||||
}
|
||||
}
|
||||
|
||||
if i == -1 {
|
||||
panic("must specify one dimension index")
|
||||
}
|
||||
|
||||
x := 0
|
||||
for n, v := range dims {
|
||||
if v >= 0 {
|
||||
x += m.offsets[n] * v
|
||||
}
|
||||
}
|
||||
|
||||
r := make([]int, m.dims[i])
|
||||
for j := range r {
|
||||
r[j] = x + m.offsets[i]*j
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// Dimensions returns the dimension array of the Matrix.
|
||||
func (m *Matrix) Dimensions() []int {
|
||||
r := make([]int, len(m.dims))
|
||||
copy(r, m.dims)
|
||||
return r
|
||||
}
|
||||
|
||||
// Dim returns the array of any given index of the Matrix.
|
||||
// Exactly one value in dims must be -1. This is the array dimension returned.
|
||||
// For example, using the Matrix documented in MakeMatrix:
|
||||
// m.Dim([]int {1, 0, -1}) = []complex128 {3, 4, 5, 6}
|
||||
// m.Dim([]int {0, -1, 2}) = []complex128 {3, 7, 1}
|
||||
// m.Dim([]int {-1, 1, 3}) = []complex128 {8, 0}
|
||||
func (s *Matrix) Dim(dims []int) []complex128 {
|
||||
inds := s.indexes(dims)
|
||||
r := make([]complex128, len(inds))
|
||||
for n, v := range inds {
|
||||
r[n] = s.list[v]
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func (m *Matrix) SetDim(x []complex128, dims []int) {
|
||||
inds := m.indexes(dims)
|
||||
if len(x) != len(inds) {
|
||||
panic("incorrect array length")
|
||||
}
|
||||
|
||||
for n, v := range inds {
|
||||
m.list[v] = x[n]
|
||||
}
|
||||
}
|
||||
|
||||
// Value returns the value at the given index.
|
||||
// m.Value([]int {1, 2, 3, 4}) is equivalent to m[1][2][3][4].
|
||||
func (s *Matrix) Value(dims []int) complex128 {
|
||||
return s.list[s.offset(dims)]
|
||||
}
|
||||
|
||||
// SetValue sets the value at the given index.
|
||||
// m.SetValue(10, []int {1, 2, 3, 4}) is equivalent to m[1][2][3][4] = 10.
|
||||
func (s *Matrix) SetValue(x complex128, dims []int) {
|
||||
s.list[s.offset(dims)] = x
|
||||
}
|
||||
|
||||
// To2D returns the 2-D array equivalent of the Matrix.
|
||||
// Only works on Matrixes of 2 dimensions.
|
||||
func (m *Matrix) To2D() [][]complex128 {
|
||||
if len(m.dims) != 2 {
|
||||
panic("can only convert 2-D Matrixes")
|
||||
}
|
||||
|
||||
r := make([][]complex128, m.dims[0])
|
||||
for i := 0; i < m.dims[0]; i++ {
|
||||
r[i] = make([]complex128, m.dims[1])
|
||||
copy(r[i], m.list[i*m.dims[1]:(i+1)*m.dims[1]])
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// PrettyClose returns true if the Matrixes are very close, else false.
|
||||
// Comparison done using dsputils.PrettyCloseC().
|
||||
func (m *Matrix) PrettyClose(n *Matrix) bool {
|
||||
// todo: use new slice equality comparison
|
||||
for i, v := range m.dims {
|
||||
if v != n.dims[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return PrettyCloseC(m.list, n.list)
|
||||
}
|
||||
Reference in New Issue
Block a user