Advertisement
Guest User

Signals lab 2

a guest
Oct 23rd, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.91 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "log"
  6.     "math"
  7.     "math/cmplx"
  8.     "math/rand"
  9.     "strconv"
  10.     "strings"
  11.     "time"
  12. )
  13.  
  14. const (
  15.     // N is the size of sequence.
  16.     N = 11
  17.     // LIMIT is the maximum value of sequence element.
  18.     LIMIT = 100
  19. )
  20.  
  21. type sequence []int64
  22. type complexSequence []complex128
  23.  
  24. func main() {
  25.     // Generate the sequences.
  26.     x1 := make(sequence, N)
  27.     x2 := make(sequence, N)
  28.  
  29.     rand.Seed(time.Now().UTC().UnixNano())
  30.  
  31.     for i := 0; i < N; i++ {
  32.         x1[i] = rand.Int63n(LIMIT)
  33.         x2[i] = rand.Int63n(LIMIT)
  34.     }
  35.  
  36.     fmt.Println("x1(n):", getSequenceStr(x1))
  37.     fmt.Println("x2(n):", getSequenceStr(x2))
  38.  
  39.     // Compute the circular convolution of the 2 sequences.
  40.     convolution, err := sequencesConvolution(x1, x2)
  41.     handleError("Couldn't compute the convolution of the 2 sequnces", err)
  42.  
  43.     fmt.Println("x(n):", getSequenceStr(convolution))
  44.  
  45.     // Compute DTF of each sequence.
  46.     X1 := discreteFourierTransform(x1)
  47.     X2 := discreteFourierTransform(x2)
  48.  
  49.     fmt.Println("X1(n):", getComplexSequenceStr(X1))
  50.     fmt.Println("X2(n):", getComplexSequenceStr(X2))
  51.  
  52.     X, err := multiplyDTFs(X1, X2)
  53.     handleError("Couldn't multiply the DTF sequences", err)
  54.     xReverseDTF := reverseDiscreteFourierTransform(X)
  55.  
  56.     fmt.Println("X(n):", getComplexSequenceStr(X))
  57.     fmt.Println("x(n):", getSequenceStr(xReverseDTF))
  58. }
  59.  
  60. func getSequenceStr(seq sequence) string {
  61.     values := make([]string, len(seq))
  62.  
  63.     for i := range seq {
  64.         values[i] = strconv.FormatInt(seq[i], 10)
  65.     }
  66.  
  67.     return strings.Join(values, ", ")
  68. }
  69.  
  70. func getComplexSequenceStr(seq complexSequence) string {
  71.     values := make([]string, len(seq))
  72.  
  73.     for i := range seq {
  74.         values[i] = fmt.Sprintf("%v", seq[i])
  75.     }
  76.  
  77.     return strings.Join(values, ", ")
  78. }
  79.  
  80. // getSequnceElement handles negative index for sequence.
  81. func getSequnceElement(seq sequence, i int) int64 {
  82.     if i < 0 {
  83.         n := len(seq)
  84.         return seq[n+i]
  85.     }
  86.  
  87.     return seq[i]
  88. }
  89.  
  90. // sequencesConvolution computes the convolution of the 2 sequences.
  91. func sequencesConvolution(x1 sequence, x2 sequence) (sequence, error) {
  92.     if len(x1) != len(x2) {
  93.         return nil, fmt.Errorf("The sequences should be of the same length")
  94.     }
  95.  
  96.     length := len(x2)
  97.     result := make(sequence, length)
  98.  
  99.     for n := 0; n < length; n++ {
  100.         for i := 0; i < length; i++ {
  101.             result[n] += x1[i] * getSequnceElement(x2, n-i)
  102.         }
  103.     }
  104.  
  105.     return result, nil
  106. }
  107.  
  108. func turnFactor(k int, n int, N int) complex128 {
  109.     return cmplx.Pow(complex128(math.E), complex(0.0, -(2.0*math.Pi*float64(k)*float64(n))/float64(N)))
  110. }
  111.  
  112. // discreteFourierTransform computes the DTF sequence by the given sequence.
  113. func discreteFourierTransform(x sequence) complexSequence {
  114.     length := len(x)
  115.     result := make(complexSequence, length)
  116.  
  117.     for k := 0; k < length; k++ {
  118.         for n := 0; n < length; n++ {
  119.             result[k] += complex(float64(x[n]), 0) * turnFactor(k, n, length)
  120.         }
  121.     }
  122.  
  123.     return result
  124. }
  125.  
  126. // reverseDiscreteFourierTransform computes the RDTF sequence by the given DTF sequence.
  127. func reverseDiscreteFourierTransform(x complexSequence) sequence {
  128.     length := len(x)
  129.     result := make(complexSequence, length)
  130.  
  131.     for k := 0; k < length; k++ {
  132.         for n := 0; n < length; n++ {
  133.             result[k] += x[n] * turnFactor(-k, n, length)
  134.         }
  135.  
  136.         result[k] *= complex(1.0/float64(length), 0)
  137.     }
  138.  
  139.     return complexSeqToSeq(result)
  140. }
  141.  
  142. func multiplyDTFs(x1 complexSequence, x2 complexSequence) (complexSequence, error) {
  143.     if len(x1) != len(x2) {
  144.         return nil, fmt.Errorf("The sequences should be of the same length")
  145.     }
  146.  
  147.     length := len(x2)
  148.     result := make(complexSequence, length)
  149.  
  150.     for i := 0; i < length; i++ {
  151.         result[i] = x1[i] * x2[i]
  152.     }
  153.  
  154.     return result, nil
  155. }
  156.  
  157. func complexSeqToSeq(complexSeq complexSequence) sequence {
  158.     seq := make(sequence, len(complexSeq))
  159.  
  160.     for i := range complexSeq {
  161.         seq[i] = int64(math.Round(real(complexSeq[i])))
  162.     }
  163.  
  164.     return seq
  165. }
  166.  
  167. func handleError(message string, err error) {
  168.     if err != nil {
  169.         log.Fatalf("%s: %s", message, err)
  170.     }
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement