github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/dsp/fourier/quarter.go (about)

     1  // Copyright ©2018 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package fourier
     6  
     7  import "github.com/jingcheng-WU/gonum/dsp/fourier/internal/fftpack"
     8  
     9  // QuarterWaveFFT implements Fast Fourier Transform for quarter wave data.
    10  type QuarterWaveFFT struct {
    11  	work []float64
    12  	ifac [15]int
    13  }
    14  
    15  // NewQuarterWaveFFT returns a QuarterWaveFFT initialized for work on sequences of length n.
    16  func NewQuarterWaveFFT(n int) *QuarterWaveFFT {
    17  	var t QuarterWaveFFT
    18  	t.Reset(n)
    19  	return &t
    20  }
    21  
    22  // Len returns the length of the acceptable input.
    23  func (t *QuarterWaveFFT) Len() int { return len(t.work) / 3 }
    24  
    25  // Reset reinitializes the QuarterWaveFFT for work on sequences of length n.
    26  func (t *QuarterWaveFFT) Reset(n int) {
    27  	if 3*n <= cap(t.work) {
    28  		t.work = t.work[:3*n]
    29  	} else {
    30  		t.work = make([]float64, 3*n)
    31  	}
    32  	fftpack.Cosqi(n, t.work, t.ifac[:])
    33  }
    34  
    35  // CosCoefficients computes the Fast Fourier Transform of quarter wave data for
    36  // the input sequence, seq, placing the cosine series coefficients in dst and
    37  // returning it.
    38  // This transform is unnormalized; a call to CosCoefficients followed by a call
    39  // to CosSequence will multiply the input sequence by 4*n, where n is the length
    40  // of the sequence.
    41  //
    42  // If the length of seq is not t.Len(), CosCoefficients will panic.
    43  // If dst is nil, a new slice is allocated and returned. If dst is not nil and
    44  // the length of dst does not equal t.Len(), CosCoefficients will panic.
    45  // It is safe to use the same slice for dst and seq.
    46  func (t *QuarterWaveFFT) CosCoefficients(dst, seq []float64) []float64 {
    47  	if len(seq) != t.Len() {
    48  		panic("fourier: sequence length mismatch")
    49  	}
    50  	if dst == nil {
    51  		dst = make([]float64, t.Len())
    52  	} else if len(dst) != t.Len() {
    53  		panic("fourier: destination length mismatch")
    54  	}
    55  	copy(dst, seq)
    56  	fftpack.Cosqf(len(dst), dst, t.work, t.ifac[:])
    57  	return dst
    58  }
    59  
    60  // CosSequence computes the Inverse Fast Fourier Transform of quarter wave data for
    61  // the input cosine series coefficients, coeff, placing the sequence data in dst
    62  // and returning it.
    63  // This transform is unnormalized; a call to CosSequence followed by a call
    64  // to CosCoefficients will multiply the input sequence by 4*n, where n is the length
    65  // of the sequence.
    66  //
    67  // If the length of seq is not t.Len(), CosSequence will panic.
    68  // If dst is nil, a new slice is allocated and returned. If dst is not nil and
    69  // the length of dst does not equal t.Len(), CosSequence will panic.
    70  // It is safe to use the same slice for dst and seq.
    71  func (t *QuarterWaveFFT) CosSequence(dst, coeff []float64) []float64 {
    72  	if len(coeff) != t.Len() {
    73  		panic("fourier: coefficients length mismatch")
    74  	}
    75  	if dst == nil {
    76  		dst = make([]float64, t.Len())
    77  	} else if len(dst) != t.Len() {
    78  		panic("fourier: destination length mismatch")
    79  	}
    80  	copy(dst, coeff)
    81  	fftpack.Cosqb(len(dst), dst, t.work, t.ifac[:])
    82  	return dst
    83  }
    84  
    85  // SinCoefficients computes the Fast Fourier Transform of quarter wave data for
    86  // the input sequence, seq, placing the sine series coefficients in dst and
    87  // returning it.
    88  // This transform is unnormalized; a call to SinCoefficients followed by a call
    89  // to SinSequence will multiply the input sequence by 4*n, where n is the length
    90  // of the sequence.
    91  //
    92  // If the length of seq is not t.Len(), SinCoefficients will panic.
    93  // If dst is nil, a new slice is allocated and returned. If dst is not nil and
    94  // the length of dst does not equal t.Len(), SinCoefficients will panic.
    95  // It is safe to use the same slice for dst and seq.
    96  func (t *QuarterWaveFFT) SinCoefficients(dst, seq []float64) []float64 {
    97  	if len(seq) != t.Len() {
    98  		panic("fourier: sequence length mismatch")
    99  	}
   100  	if dst == nil {
   101  		dst = make([]float64, t.Len())
   102  	} else if len(dst) != t.Len() {
   103  		panic("fourier: destination length mismatch")
   104  	}
   105  	copy(dst, seq)
   106  	fftpack.Sinqf(len(dst), dst, t.work, t.ifac[:])
   107  	return dst
   108  }
   109  
   110  // SinSequence computes the Inverse Fast Fourier Transform of quarter wave data for
   111  // the input sine series coefficients, coeff, placing the sequence data in dst
   112  // and returning it.
   113  // This transform is unnormalized; a call to SinSequence followed by a call
   114  // to SinCoefficients will multiply the input sequence by 4*n, where n is the length
   115  // of the sequence.
   116  //
   117  // If the length of seq is not t.Len(), SinSequence will panic.
   118  // If dst is nil, a new slice is allocated and returned. If dst is not nil and
   119  // the length of dst does not equal t.Len(), SinSequence will panic.
   120  // It is safe to use the same slice for dst and seq.
   121  func (t *QuarterWaveFFT) SinSequence(dst, coeff []float64) []float64 {
   122  	if len(coeff) != t.Len() {
   123  		panic("fourier: coefficients length mismatch")
   124  	}
   125  	if dst == nil {
   126  		dst = make([]float64, t.Len())
   127  	} else if len(dst) != t.Len() {
   128  		panic("fourier: destination length mismatch")
   129  	}
   130  	copy(dst, coeff)
   131  	fftpack.Sinqb(len(dst), dst, t.work, t.ifac[:])
   132  	return dst
   133  }