cmMath.h/c : Added cmLFSR() and cmGenGoldCode().
This commit is contained in:
parent
c262a44e72
commit
032d359a90
131
cmMath.c
131
cmMath.c
@ -1,5 +1,10 @@
|
||||
#include "cmPrefix.h"
|
||||
#include "cmGlobal.h"
|
||||
#include "cmRpt.h"
|
||||
#include "cmErr.h"
|
||||
#include "cmCtx.h"
|
||||
#include "cmMem.h"
|
||||
#include "cmMallocDebug.h"
|
||||
#include "cmFloatTypes.h"
|
||||
#include "cmMath.h"
|
||||
#include <sys/types.h> // u_char
|
||||
@ -464,6 +469,128 @@ bool cmIsCloseU( unsigned x0, unsigned x1, double eps )
|
||||
{
|
||||
if( x0 == x1 )
|
||||
return true;
|
||||
|
||||
return abs(x0-x1)/(x0+x1) < eps;
|
||||
if( x0 > x1 )
|
||||
return (x0-x1)/(x0+x1) < eps;
|
||||
else
|
||||
return (x1-x0)/(x0+x1) < eps;
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
||||
// cmLFSR() implementation based on note at bottom of:
|
||||
// http://www.ece.cmu.edu/~koopman/lfsr/index.html
|
||||
void cmLFSR( unsigned lfsrN, unsigned tapMask, unsigned seed, unsigned* yV, unsigned yN )
|
||||
{
|
||||
assert( 0 < lfsrN && lfsrN < 32 );
|
||||
|
||||
unsigned i;
|
||||
for(i=0; i<yN; ++i)
|
||||
{
|
||||
if( (yV[i] = seed & 1)==1 )
|
||||
seed = (seed >> 1) ^ tapMask;
|
||||
else
|
||||
seed = (seed >> 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool cmMLS_IsBalanced( const unsigned* xV, int xN)
|
||||
{
|
||||
int a = 0;
|
||||
unsigned i;
|
||||
|
||||
for(i=0; i<xN; ++i)
|
||||
if( xV[i] == 1 )
|
||||
++a;
|
||||
|
||||
return abs(a - (xN-a)) == 1;
|
||||
}
|
||||
|
||||
unsigned _cmGenGoldCopy( int* y, unsigned yi, unsigned yN, unsigned* x, unsigned xN)
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0; i<xN; ++i,++yi)
|
||||
y[yi] = x[i]==1 ? -1 : 1;
|
||||
|
||||
assert(yi <= yN);
|
||||
return yi;
|
||||
}
|
||||
|
||||
bool cmGenGoldCodes( unsigned lfsrN, unsigned poly_coeff0, unsigned poly_coeff1, unsigned goldN, int* yM, unsigned mlsN )
|
||||
{
|
||||
bool retFl = true;
|
||||
unsigned yi = 0;
|
||||
unsigned yN = goldN * mlsN;
|
||||
unsigned* mls0V = cmMemAllocZ(unsigned,mlsN);
|
||||
unsigned* mls1V = cmMemAllocZ(unsigned,mlsN);
|
||||
unsigned* xorV = cmMemAllocZ(unsigned,mlsN);
|
||||
|
||||
unsigned i,j;
|
||||
|
||||
cmLFSR(lfsrN, poly_coeff0, 1 << (lfsrN-1), mls0V, mlsN);
|
||||
|
||||
cmLFSR(lfsrN, poly_coeff1, 1 << (lfsrN-1), mls1V, mlsN);
|
||||
|
||||
if( cmMLS_IsBalanced(mls0V,mlsN) )
|
||||
yi = _cmGenGoldCopy(yM, yi, yN, mls0V, mlsN);
|
||||
|
||||
if( yi<yN && cmMLS_IsBalanced(mls1V,mlsN) )
|
||||
yi = _cmGenGoldCopy(yM, yi, yN, mls1V, mlsN);
|
||||
|
||||
|
||||
for(i=0; yi < yN && i<mlsN-1; ++i )
|
||||
{
|
||||
for(j=0; j<mlsN; ++j)
|
||||
xorV[j] = (mls0V[j] + mls1V[ (i+j) % mlsN ]) % 2;
|
||||
|
||||
if( cmMLS_IsBalanced(xorV,mlsN) )
|
||||
yi = _cmGenGoldCopy(yM,yi,yN,xorV,mlsN);
|
||||
}
|
||||
|
||||
if(yi < yN )
|
||||
{
|
||||
//rc = cmErrMsg(err,kOpFailAtRC,"Gold code generation failed. Insuffient balanced pairs.");
|
||||
retFl = false;
|
||||
}
|
||||
|
||||
cmMemFree(mls0V);
|
||||
cmMemFree(mls1V);
|
||||
cmMemFree(xorV);
|
||||
|
||||
return retFl;
|
||||
|
||||
}
|
||||
|
||||
bool cmLFSR_Test()
|
||||
{
|
||||
// lfsrN = 5; % 5 6 7;
|
||||
// poly_coeff0 = 0x12; % 0x12 0x21 0x41;
|
||||
// poly_coeff1 = 0x1e; % 0x1e 0x36 0x72;
|
||||
|
||||
unsigned lfsrN = 7;
|
||||
unsigned pc0 = 0x41;
|
||||
unsigned pc1 = 0x72;
|
||||
unsigned mlsN = (1 << lfsrN)-1;
|
||||
|
||||
unsigned yN = mlsN*2;
|
||||
unsigned yV[ yN ];
|
||||
unsigned i;
|
||||
|
||||
cmLFSR( lfsrN, pc0, 1 << (lfsrN-1), yV, yN );
|
||||
|
||||
for(i=0; i<mlsN; ++i)
|
||||
if( yV[i] != yV[i+mlsN] )
|
||||
return false;
|
||||
|
||||
//atVOU_PrintL(NULL,"0x12",yV,mlsN,2);
|
||||
|
||||
cmLFSR( lfsrN, pc1, 1 << (lfsrN-1), yV, yN );
|
||||
|
||||
//atVOU_PrintL(NULL,"0x17",yV,mlsN,2);
|
||||
|
||||
for(i=0; i<mlsN; ++i)
|
||||
if( yV[i] != yV[i+mlsN] )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
37
cmMath.h
37
cmMath.h
@ -74,4 +74,41 @@ bool cmIsCloseF( float x0, float x1, double eps );
|
||||
bool cmIsCloseI( int x0, int x1, double eps );
|
||||
bool cmIsCloseU( unsigned x0, unsigned x1, double eps );
|
||||
|
||||
//=================================================================
|
||||
// Run a length 'lfsrN' linear feedback shift register (LFSR) for 'yN' iterations to
|
||||
// produce a length 'yN' bit string in yV[yN].
|
||||
// 'lfsrN' count of bits in the shift register range: 2<= lfsrN <= 32.
|
||||
// 'tapMask' is a bit mask which gives the tap indexes positions for the LFSR.
|
||||
// The least significant bit corresponds to the maximum delay tap position.
|
||||
// The min tap position is therefore denoted by the tap mask bit location 1 << (lfsrN-1).
|
||||
// A minimum of two taps must exist.
|
||||
// 'seed' sets the initial delay state.
|
||||
// 'yV[yN]' is the the output vector
|
||||
// 'yN' is count of elements in yV.
|
||||
// The function resturn kOkAtRC on success or kInvalidArgsRCRC if any arguments are invalid.
|
||||
// /sa cmLFSR_Test.
|
||||
void cmLFSR( unsigned lfsrN, unsigned tapMask, unsigned seed, unsigned* yV, unsigned yN );
|
||||
|
||||
// Example and test code for cmLFSR()
|
||||
bool cmLFSR_Test();
|
||||
|
||||
|
||||
// Generate a set of 'goldN' Gold codes using the Maximum Length Sequences (MLS) generated
|
||||
// by a length 'lfsrN' linear feedback shift register.
|
||||
// 'err' is an error object to be set if the the function fails.
|
||||
// 'lfsrN' is the length of the Linear Feedback Shift Registers (LFSR) used to generate the MLS.
|
||||
// 'poly_coeff0' tap mask for the first LFSR.
|
||||
// 'coeff1' tap mask the the second LFSR.
|
||||
// 'goldN' is the count of Gold codes to generate.
|
||||
// 'yM[mlsN', goldN] is a column major output matrix where each column contains a Gold code.
|
||||
// 'mlsN' is the length of the maximum length sequence for each Gold code which can be
|
||||
// calculated as mlsN = (1 << a->lfsrN) - 1.
|
||||
// Note that values of 'lfsrN' and the 'poly_coeffx' must be carefully selected such that
|
||||
// they will produce a MLS. For example to generate a MLS with length 31 set 'lfsrN' to 5 and
|
||||
// then select poly_coeff from two different elements of the set {0x12 0x14 0x17 0x1B 0x1D 0x1E}.
|
||||
// See http://www.ece.cmu.edu/~koopman/lfsr/index.html for a complete set of MSL polynomial
|
||||
// coefficients for given LFSR lengths.
|
||||
// Returns false if insufficient balanced pairs exist.
|
||||
bool cmGenGoldCodes( unsigned lfsrN, unsigned poly_coeff0, unsigned poly_coeff1, unsigned goldN, int* yM, unsigned mlsN );
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user