Skip to content

Instantly share code, notes, and snippets.

@wiless
Created November 26, 2014 16:56
Show Gist options
  • Save wiless/38f203e710e5bc50dbeb to your computer and use it in GitHub Desktop.
Save wiless/38f203e710e5bc50dbeb to your computer and use it in GitHub Desktop.
QPSK BER simulation in Golang
package main
import (
"fmt"
"math/rand"
"math"
"io/ioutil"
"time"
"flag"
"runtime"
)
var concflag *bool = flag.Bool("conc", true, "#Enables Concurrent Goroutines Default [true]")
var randomize *bool = flag.Bool("randomize", false, "#Randomize Seed ")
func main(){
flag.Parse()
flag.PrintDefaults()
if *randomize{
rand.Seed(time.Now().UnixNano())
}
concurrent:=*concflag
fmt.Printf("\nMax Available CPUS %v",runtime.NumCPU())
fmt.Printf("\nCurrent SET CPUS %v",runtime.GOMAXPROCS(-1))
t:=time.Now()
fmt.Printf("\nTime Now : %v",t)
snr,ber:=simulate(20,concurrent)
fmt.Printf("\nElapsed : %v",time.Since(t))
fmt.Printf("\n With Concurrent : %v",concurrent)
fmt.Printf("\n SNR = %v",snr)
fmt.Printf("\n BER = %v",ber)
towrite:=false
if(towrite){
var txttowrite =fmt.Sprintf("snr =%v\n",snr)+fmt.Sprintf("ber =%v\n",ber)
ioutil.WriteFile("results.m",[]byte(txttowrite),0600)
}
fmt.Printf("\n Done..\n")
}
func simulate(n int,runtype bool) (snrdB []float64,ber []float64) {
var f=make([]float64, n)
var snr=make([]float64, n)
var initSNR float64
initSNR= 0
if runtype{
ch := make(chan float64,20)
for k := 0; k < n; k++ {
var currentSNR=initSNR+float64(k)
snr[k]=currentSNR
go link(ch, float64(currentSNR))
}
for k := 0; k < n; k++ {
f[k] = <-ch
}
} else {
for k := 0; k < n; k++ {
var currentSNR=initSNR+float64(k)
snr[k]=currentSNR
f[k]=seqlink(currentSNR)
}
}
return snr,f
}
func link(ch chan float64, k float64) {
Nbits:=1024*100 //*(50-int(k))
var symbols=[]complex128{0.7+0.7i,+0.7-0.7i,-0.7+0.7i,-0.7-0.7i}
var txbits=make([]int,Nbits)
for i:=0;i<len(txbits);i++{
txbits[i]=rand.Intn(4)
}
var txsymbols=make([]complex128,Nbits)
var noise=make([]complex128,Nbits)
var rxnoise=make([]complex128,Nbits)
var noisevar float64
lsnr:=float64(math.Pow(10,(k/10)))
Es:=float64(1)
noisevar=Es/lsnr
errorbits:=int(0)
for i,indx :=range txbits{
txsymbols[i]=symbols[indx]
noise[i]=complex(rand.NormFloat64()*math.Sqrt(noisevar*0.5),rand.NormFloat64()*math.Sqrt(noisevar*0.5))
tmp:=txsymbols[i]+noise[i]
switch
{
case real(tmp)>0 && imag(tmp)>0:rxnoise[i]=symbols[0]
case real(tmp)>0 && imag(tmp)<0:rxnoise[i]=symbols[1]
case real(tmp)<0 && imag(tmp)>0:rxnoise[i]=symbols[2]
case real(tmp)<0 && imag(tmp)<0:rxnoise[i]=symbols[3]
}
if (rxnoise[i]!=txsymbols[i]){
errorbits++
}
}
var ber =float64(errorbits)/float64(Nbits)
ch <- ber
}
func seqlink(k float64) float64 {
Nbits:=1024*100 //*(50-int(k))
var symbols=[]complex128{0.7+0.7i,+0.7-0.7i,-0.7+0.7i,-0.7-0.7i}
var txbits=make([]int,Nbits)
for i:=0;i<len(txbits);i++{
txbits[i]=rand.Intn(4)
}
var txsymbols=make([]complex128,Nbits)
var noise=make([]complex128,Nbits)
var rxnoise=make([]complex128,Nbits)
var noisevar float64
lsnr:=float64(math.Pow(10,(k/10)))
Es:=float64(1)
noisevar=Es/lsnr
errorbits:=int(0)
for i,indx :=range txbits{
txsymbols[i]=symbols[indx]
noise[i]=complex(rand.NormFloat64()*math.Sqrt(noisevar*0.5),rand.NormFloat64()*math.Sqrt(noisevar*0.5))
tmp:=txsymbols[i]+noise[i]
switch
{
case real(tmp)>0 && imag(tmp)>0:rxnoise[i]=symbols[0]
case real(tmp)>0 && imag(tmp)<0:rxnoise[i]=symbols[1]
case real(tmp)<0 && imag(tmp)>0:rxnoise[i]=symbols[2]
case real(tmp)<0 && imag(tmp)<0:rxnoise[i]=symbols[3]
}
if (rxnoise[i]!=txsymbols[i]){
errorbits++
}
}
var ber =float64(errorbits)/float64(Nbits)
return ber
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment