Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "log"
- "math"
- "math/cmplx"
- "math/rand"
- "strconv"
- "strings"
- "time"
- )
- const (
- // N is the size of sequence.
- N = 11
- // LIMIT is the maximum value of sequence element.
- LIMIT = 100
- )
- type sequence []int64
- type complexSequence []complex128
- func main() {
- // Generate the sequences.
- x1 := make(sequence, N)
- x2 := make(sequence, N)
- rand.Seed(time.Now().UTC().UnixNano())
- for i := 0; i < N; i++ {
- x1[i] = rand.Int63n(LIMIT)
- x2[i] = rand.Int63n(LIMIT)
- }
- fmt.Println("x1(n):", getSequenceStr(x1))
- fmt.Println("x2(n):", getSequenceStr(x2))
- // Compute the circular convolution of the 2 sequences.
- convolution, err := sequencesConvolution(x1, x2)
- handleError("Couldn't compute the convolution of the 2 sequnces", err)
- fmt.Println("x(n):", getSequenceStr(convolution))
- // Compute DTF of each sequence.
- X1 := discreteFourierTransform(x1)
- X2 := discreteFourierTransform(x2)
- fmt.Println("X1(n):", getComplexSequenceStr(X1))
- fmt.Println("X2(n):", getComplexSequenceStr(X2))
- X, err := multiplyDTFs(X1, X2)
- handleError("Couldn't multiply the DTF sequences", err)
- xReverseDTF := reverseDiscreteFourierTransform(X)
- fmt.Println("X(n):", getComplexSequenceStr(X))
- fmt.Println("x(n):", getSequenceStr(xReverseDTF))
- }
- func getSequenceStr(seq sequence) string {
- values := make([]string, len(seq))
- for i := range seq {
- values[i] = strconv.FormatInt(seq[i], 10)
- }
- return strings.Join(values, ", ")
- }
- func getComplexSequenceStr(seq complexSequence) string {
- values := make([]string, len(seq))
- for i := range seq {
- values[i] = fmt.Sprintf("%v", seq[i])
- }
- return strings.Join(values, ", ")
- }
- // getSequnceElement handles negative index for sequence.
- func getSequnceElement(seq sequence, i int) int64 {
- if i < 0 {
- n := len(seq)
- return seq[n+i]
- }
- return seq[i]
- }
- // sequencesConvolution computes the convolution of the 2 sequences.
- func sequencesConvolution(x1 sequence, x2 sequence) (sequence, error) {
- if len(x1) != len(x2) {
- return nil, fmt.Errorf("The sequences should be of the same length")
- }
- length := len(x2)
- result := make(sequence, length)
- for n := 0; n < length; n++ {
- for i := 0; i < length; i++ {
- result[n] += x1[i] * getSequnceElement(x2, n-i)
- }
- }
- return result, nil
- }
- func turnFactor(k int, n int, N int) complex128 {
- return cmplx.Pow(complex128(math.E), complex(0.0, -(2.0*math.Pi*float64(k)*float64(n))/float64(N)))
- }
- // discreteFourierTransform computes the DTF sequence by the given sequence.
- func discreteFourierTransform(x sequence) complexSequence {
- length := len(x)
- result := make(complexSequence, length)
- for k := 0; k < length; k++ {
- for n := 0; n < length; n++ {
- result[k] += complex(float64(x[n]), 0) * turnFactor(k, n, length)
- }
- }
- return result
- }
- // reverseDiscreteFourierTransform computes the RDTF sequence by the given DTF sequence.
- func reverseDiscreteFourierTransform(x complexSequence) sequence {
- length := len(x)
- result := make(complexSequence, length)
- for k := 0; k < length; k++ {
- for n := 0; n < length; n++ {
- result[k] += x[n] * turnFactor(-k, n, length)
- }
- result[k] *= complex(1.0/float64(length), 0)
- }
- return complexSeqToSeq(result)
- }
- func multiplyDTFs(x1 complexSequence, x2 complexSequence) (complexSequence, error) {
- if len(x1) != len(x2) {
- return nil, fmt.Errorf("The sequences should be of the same length")
- }
- length := len(x2)
- result := make(complexSequence, length)
- for i := 0; i < length; i++ {
- result[i] = x1[i] * x2[i]
- }
- return result, nil
- }
- func complexSeqToSeq(complexSeq complexSequence) sequence {
- seq := make(sequence, len(complexSeq))
- for i := range complexSeq {
- seq[i] = int64(math.Round(real(complexSeq[i])))
- }
- return seq
- }
- func handleError(message string, err error) {
- if err != nil {
- log.Fatalf("%s: %s", message, err)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement