SVN r8748
This commit is contained in:
@@ -1,200 +0,0 @@
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Free software: Progressive edge-growth (PEG) algorithm */
|
||||
/* Created by Xiaoyu Hu */
|
||||
/* Evangelos Eletheriou */
|
||||
/* Dieter Arnold */
|
||||
/* IBM Research, Zurich Research Lab., Switzerland */
|
||||
/* */
|
||||
/* The C++ sources files have been compiled using xlC compiler */
|
||||
/* at IBM RS/6000 running AIX. For other compilers and platforms,*/
|
||||
/* minor changes might be needed. */
|
||||
/* */
|
||||
/* Bug reporting to: xhu@zurich.ibm.com */
|
||||
/**********************************************************************/
|
||||
|
||||
////
|
||||
// Modified by F. P. Beekhof; 2008 / 08 / 19
|
||||
////
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include "BigGirth.h"
|
||||
#include "Random.h"
|
||||
#include "CyclesOfGraph.h"
|
||||
|
||||
const double EPS = 1e-6;
|
||||
|
||||
using namespace std;
|
||||
|
||||
void usage()
|
||||
{
|
||||
cout<<"*******************************************************************************************"<<endl;
|
||||
cout<<" Usage Reminder: MainPEG -numM M -numN N -codeName CodeName -degFileName DegFileName " <<endl;
|
||||
cout<<" option: -sglConcent SglConcent " <<endl;
|
||||
cout<<" sglConcent==0 ----- strictly concentrated parity-check " <<endl;
|
||||
cout<<" degree distribution (including regular graphs)" <<endl;
|
||||
cout<<" sglConcent==1 ----- Best-effort concentrated (DEFAULT) " <<endl;
|
||||
cout<<" option: -tgtGirth TgtGirth " <<endl;
|
||||
cout<<" TgtGirth==4, 6 ...; if very large, then greedy PEG (DEFAULT) " <<endl;
|
||||
cout<<" IF sglConcent==0, TgtGirth is recommended to be set relatively small" <<endl;
|
||||
cout<<" option: -q " <<endl;
|
||||
cout<<" Quiet mode. Produces less output to the screen. " <<endl;
|
||||
cout<<" option: -outputMode <0,1,2> " <<endl;
|
||||
cout<<" Specifies output format. " <<endl;
|
||||
cout<<" '0': H in compressed format (default) " <<endl;
|
||||
cout<<" '1': H in un-compressed format " <<endl;
|
||||
cout<<" '2': G and H in compressed format " <<endl;
|
||||
cout<<" " <<endl;
|
||||
cout<<" Remarks: File CodeName stores the generated PEG Tanner graph. The first line contains"<<endl;
|
||||
cout<<" the block length, N. The second line defines the number of parity-checks, M."<<endl;
|
||||
cout<<" The third line defines the number of columns of the compressed parity-check "<<endl;
|
||||
cout<<" matrix. The following M lines are then the compressed parity-check matrix. "<<endl;
|
||||
cout<<" Each of the M rows contains the indices (1 ... N) of 1's in the compressed "<<endl;
|
||||
cout<<" row of parity-check matrix. If not all column entries are used, the column "<<endl;
|
||||
cout<<" is filled up with 0's. "<<endl;
|
||||
cout<<" "<<endl;
|
||||
cout<<" If both G and H are in the output, (outMode 2), the first line contains"<<endl;
|
||||
cout<<" N, the 2nd line K, the number of message bits, the 3rd line M, the 4th line"<<endl;
|
||||
cout<<" contains the number of rows of the compressed generator matrix; the 5th"<<endl;
|
||||
cout<<" defines the number of columns of the compressed parity-check matrix. The"<<endl;
|
||||
cout<<" format of G is almost like that of H, but vertical -- i.e. the padding"<<endl;
|
||||
cout<<" zeroes are on the bottom. "<<endl;
|
||||
|
||||
cout<<" "<<endl;
|
||||
cout<<" File DegFileName is the input file to specify the degree distribution (node "<<endl;
|
||||
cout<<" perspective). The first line contains the number of various degrees. The second"<<endl;
|
||||
cout<<" defines the row vector of degree sequence in the increasing order. The vector"<<endl;
|
||||
cout<<" of fractions of the corresponding degree is defined in the last line. "<<endl;
|
||||
cout<<" "<<endl;
|
||||
cout<<" A log file called 'leftHandGirth.dat' will also be generated and stored in the"<<endl;
|
||||
cout<<" current directory, which gives the girth of the left-hand subgraph of j, where"<<endl;
|
||||
cout<<" 1<=j<=N. The left-hand subgraph of j is defined as all the edges emanating from"<<endl;
|
||||
cout<<" bit nodes {1 ... j} and their associated nodes. "<<endl;
|
||||
cout<<" "<<endl;
|
||||
cout<<" The last point is, when strictly concentrated parity-check degree distribution"<<endl;
|
||||
cout<<" is invoked, i.e. sglConcent==0, the girth might be weaken to some extent as "<<endl;
|
||||
cout<<" compared to the generic PEG algorithm. "<<endl;
|
||||
cout<<"**********************************************************************************************"<<endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]){
|
||||
int sglConcent=1; // default to non-strictly concentrated parity-check distribution
|
||||
int targetGirth=100000; // default to greedy PEG version
|
||||
std::string codeName, degFileName;
|
||||
int M = -1, N = -1;
|
||||
bool verbose = true;
|
||||
|
||||
const int OUTPUT_MODE_H_COMPRESSED = 0;
|
||||
const int OUTPUT_MODE_H = 1;
|
||||
const int OUTPUT_MODE_G_H_COMPRESSED = 2;
|
||||
int output_mode = OUTPUT_MODE_H_COMPRESSED; // default
|
||||
|
||||
if (argc<9) {
|
||||
usage();
|
||||
}else {
|
||||
for(int i=1;i<argc;++i){
|
||||
if (strcmp(argv[i], "-numM")==0) {
|
||||
if (++i >= argc) usage();
|
||||
M=atoi(argv[i]);
|
||||
} else if(strcmp(argv[i], "-numN")==0) {
|
||||
if (++i >= argc) usage();
|
||||
N=atoi(argv[i]);
|
||||
} else if(strcmp(argv[i], "-codeName")==0) {
|
||||
if (++i >= argc) usage();
|
||||
codeName = argv[i];
|
||||
} else if(strcmp(argv[i], "-degFileName")==0) {
|
||||
if (++i >= argc) usage();
|
||||
degFileName = argv[i];
|
||||
} else if(strcmp(argv[i], "-sglConcent")==0) {
|
||||
if (++i >= argc) usage();
|
||||
sglConcent=atoi(argv[i]);
|
||||
} else if(strcmp(argv[i], "-tgtGirth")==0) {
|
||||
if (++i >= argc) usage();
|
||||
targetGirth=atoi(argv[i]);
|
||||
} else if(strcmp(argv[i], "-outputMode")==0) {
|
||||
if (++i >= argc) usage();
|
||||
output_mode=atoi(argv[i]);
|
||||
} else if(strcmp(argv[i], "-q")==0) {
|
||||
verbose=false;
|
||||
} else{
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if (M == -1 || N == -1) {
|
||||
cout<<"Error: M or N not specified!"<<endl;
|
||||
exit(-1);
|
||||
}
|
||||
if (M>N) {
|
||||
cout<<"Error: M must be smaller than N!"<<endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> degSeq(N);
|
||||
|
||||
ifstream infn(degFileName.c_str());
|
||||
if (!infn) {cout << "\nCannot open file " << degFileName << endl; exit(-1); }
|
||||
int m;
|
||||
infn >>m;
|
||||
std::vector<int> deg(m);
|
||||
std::vector<double> degFrac(m);
|
||||
for(int i=0;i<m;i++) infn>>deg[i];
|
||||
for(int i=0;i<m;i++) infn>>degFrac[i];
|
||||
infn.close();
|
||||
double dtmp=0.0;
|
||||
for(int i=0;i<m;i++) dtmp+=degFrac[i];
|
||||
cout.setf(ios::fixed, ios::floatfield);
|
||||
if(abs(dtmp-1.0)>EPS) {
|
||||
cout.setf(ios::fixed, ios::floatfield);
|
||||
cout <<"\n Invalid degree distribution (node perspective): sum != 1.0 but "<<setprecision(10)<<dtmp<<endl; exit(-1);
|
||||
}
|
||||
for(int i=1;i<m;++i) degFrac[i]+=degFrac[i-1];
|
||||
for(int i=0;i<N;++i) {
|
||||
dtmp=double(i)/double(N);
|
||||
int j;
|
||||
for(j=m-1;j>=0;--j) {
|
||||
if(dtmp>degFrac[j]) break;
|
||||
}
|
||||
if(dtmp<degFrac[0]) degSeq[i]=deg[0];
|
||||
else degSeq[i]=deg[j+1];
|
||||
}
|
||||
|
||||
BigGirth bigGirth(M, N, °Seq[0], codeName.c_str(),
|
||||
sglConcent, targetGirth, verbose);
|
||||
|
||||
switch(output_mode)
|
||||
{
|
||||
case OUTPUT_MODE_H_COMPRESSED: bigGirth.writeToFile_Hcompressed(); break;
|
||||
case OUTPUT_MODE_H: // different output format
|
||||
bigGirth.writeToFile_Hmatrix(); break;
|
||||
case OUTPUT_MODE_G_H_COMPRESSED:
|
||||
// different output format: including generator matrix (compressed)
|
||||
bigGirth.writeToFile(); break;
|
||||
default:
|
||||
cout << "Error: invalid output mode specified." << endl << endl;
|
||||
usage();
|
||||
}
|
||||
|
||||
//computing local girth distribution
|
||||
|
||||
if (verbose && N<10000) {
|
||||
cout<<" Now computing the local girth on the global Tanner graph setting. "<<endl;
|
||||
cout<<" might take a bit long time. Please wait ... "<<endl;
|
||||
bigGirth.loadH();
|
||||
CyclesOfGraph cog(M, N, bigGirth.H);
|
||||
cog.getCyclesTable();
|
||||
cog.printCyclesTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
!subroutine symspec65(dd,npts,ss,nqsym,savg)
|
||||
subroutine symspec65(dd,npts,nqsym,savg)
|
||||
|
||||
! Compute JT65 symbol spectra at quarter-symbol steps
|
||||
|
||||
parameter (NFFT=8192)
|
||||
parameter (NSZ=3413) !NFFT*5000/12000
|
||||
parameter (MAXHSYM=322)
|
||||
parameter (MAXQSYM=552)
|
||||
real*8 hstep
|
||||
real*4 dd(npts)
|
||||
! real*4 ss(MAXHSYM,NSZ)
|
||||
real*4 ss(MAXQSYM,NSZ)
|
||||
real*4 savg(NSZ)
|
||||
real*4 x(NFFT)
|
||||
real*4 w(NFFT)
|
||||
complex c(0:NFFT/2)
|
||||
logical first
|
||||
common/refspec/dfref,ref(NSZ)
|
||||
equivalence (x,c)
|
||||
data first/.true./
|
||||
save /refspec/,first,w
|
||||
common/sync/ss
|
||||
|
||||
hstep=2048.d0*12000.d0/11025.d0 !half-symbol = 2229.116 samples
|
||||
qstep=hstep/2.0 !quarter-symbol = 1114.558 samples
|
||||
nsps=nint(2*hstep)
|
||||
df=12000.0/NFFT
|
||||
nhsym=(npts-NFFT)/hstep
|
||||
nqsym=(npts-NFFT)/qstep
|
||||
savg=0.
|
||||
fac1=1.e-3
|
||||
|
||||
if(first) then
|
||||
! Compute the FFT window
|
||||
! width=0.25*nsps
|
||||
do i=1,NFFT
|
||||
! z=(i-NFFT/2)/width
|
||||
w(i)=1
|
||||
if(i.gt.4458) w(i)=0
|
||||
! w(i)=exp(-z*z)
|
||||
enddo
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
do j=1,nqsym
|
||||
i0=(j-1)*qstep
|
||||
x=fac1*w*dd(i0+1:i0+NFFT)
|
||||
call four2a(c,NFFT,1,-1,0) !r2c forward FFT
|
||||
do i=1,NSZ
|
||||
s=real(c(i))**2 + aimag(c(i))**2
|
||||
ss(j,i)=s
|
||||
savg(i)=savg(i)+s
|
||||
enddo
|
||||
enddo
|
||||
savg=savg/nhsym
|
||||
|
||||
! call flat65(ss,nhsym,MAXQSYM,NSZ,ref) !Flatten the 2d spectrum, saving
|
||||
call flat65(ss,nqsym,MAXQSYM,NSZ,ref) !Flatten the 2d spectrum, saving
|
||||
dfref=df ! the reference spectrum ref()
|
||||
savg=savg/ref
|
||||
! do j=1,nhsym
|
||||
do j=1,nqsym
|
||||
ss(j,1:NSZ)=ss(j,1:NSZ)/ref
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine symspec65
|
||||
Reference in New Issue
Block a user