Browse Source

cmMath.h/c : Added cmLFSR() and cmGenGoldCode().

master
kevin 9 years ago
parent
commit
032d359a90
2 changed files with 165 additions and 1 deletions
  1. 128
    1
      cmMath.c
  2. 37
    0
      cmMath.h

+ 128
- 1
cmMath.c View File

@@ -1,5 +1,10 @@
1 1
 #include "cmPrefix.h"
2 2
 #include "cmGlobal.h"
3
+#include "cmRpt.h"
4
+#include "cmErr.h"
5
+#include "cmCtx.h"
6
+#include "cmMem.h"
7
+#include "cmMallocDebug.h"
3 8
 #include "cmFloatTypes.h"
4 9
 #include "cmMath.h"
5 10
 #include <sys/types.h> // u_char
@@ -464,6 +469,128 @@ bool cmIsCloseU( unsigned x0, unsigned x1, double eps )
464 469
 {
465 470
   if( x0 == x1 )
466 471
     return true;
472
+  if( x0 > x1 )
473
+    return (x0-x1)/(x0+x1) < eps;
474
+  else
475
+    return (x1-x0)/(x0+x1) < eps;
476
+}
477
+
478
+//=================================================================
479
+
480
+// cmLFSR() implementation based on note at bottom of:
481
+// http://www.ece.cmu.edu/~koopman/lfsr/index.html
482
+void cmLFSR( unsigned lfsrN, unsigned tapMask, unsigned seed, unsigned* yV, unsigned yN )
483
+{
484
+  assert( 0 < lfsrN && lfsrN < 32 );
485
+  
486
+  unsigned i;
487
+  for(i=0; i<yN; ++i)
488
+  {
489
+    if( (yV[i] = seed & 1)==1 )
490
+      seed = (seed >> 1) ^ tapMask;
491
+    else
492
+      seed = (seed >> 1);
493
+
494
+  }
495
+}
496
+
497
+bool cmMLS_IsBalanced( const unsigned* xV, int xN)
498
+{
499
+  int      a = 0;
500
+  unsigned i;
501
+
502
+  for(i=0; i<xN; ++i)
503
+    if( xV[i] == 1 )
504
+      ++a;
505
+
506
+  return abs(a - (xN-a)) == 1;
507
+}
508
+
509
+unsigned _cmGenGoldCopy( int* y, unsigned yi, unsigned yN, unsigned* x, unsigned xN)
510
+{
511
+  unsigned i;
512
+  for(i=0; i<xN; ++i,++yi)
513
+    y[yi] = x[i]==1 ? -1 : 1;
514
+
515
+  assert(yi <= yN);
516
+  return yi;
517
+}
518
+
519
+bool cmGenGoldCodes( unsigned lfsrN, unsigned poly_coeff0, unsigned poly_coeff1, unsigned goldN, int* yM, unsigned mlsN  )
520
+{
521
+  bool      retFl = true;
522
+  unsigned  yi    = 0;
523
+  unsigned  yN    = goldN * mlsN;
524
+  unsigned* mls0V = cmMemAllocZ(unsigned,mlsN);
525
+  unsigned* mls1V = cmMemAllocZ(unsigned,mlsN);
526
+  unsigned* xorV  = cmMemAllocZ(unsigned,mlsN);
527
+  
528
+  unsigned  i,j;
467 529
   
468
-  return abs(x0-x1)/(x0+x1) < eps;
530
+  cmLFSR(lfsrN, poly_coeff0, 1 << (lfsrN-1), mls0V, mlsN);
531
+
532
+  cmLFSR(lfsrN, poly_coeff1, 1 << (lfsrN-1), mls1V, mlsN);
533
+
534
+  if( cmMLS_IsBalanced(mls0V,mlsN) )
535
+    yi = _cmGenGoldCopy(yM, yi, yN, mls0V, mlsN);
536
+
537
+  if( yi<yN && cmMLS_IsBalanced(mls1V,mlsN) )
538
+    yi = _cmGenGoldCopy(yM, yi, yN, mls1V, mlsN);
539
+
540
+  
541
+  for(i=0;  yi < yN && i<mlsN-1; ++i )
542
+  {
543
+    for(j=0; j<mlsN; ++j)
544
+      xorV[j] = (mls0V[j] + mls1V[ (i+j) % mlsN ]) % 2;
545
+    
546
+    if( cmMLS_IsBalanced(xorV,mlsN) )
547
+      yi = _cmGenGoldCopy(yM,yi,yN,xorV,mlsN);
548
+  }
549
+
550
+  if(yi < yN )
551
+  {    
552
+    //rc = cmErrMsg(err,kOpFailAtRC,"Gold code generation failed.  Insuffient balanced pairs.");
553
+    retFl = false;
554
+  }
555
+  
556
+  cmMemFree(mls0V);
557
+  cmMemFree(mls1V);
558
+  cmMemFree(xorV);
559
+
560
+  return retFl;
561
+
562
+}
563
+
564
+bool  cmLFSR_Test()
565
+{
566
+  // lfsrN          = 5;   % 5    6    7;
567
+  // poly_coeff0    = 0x12;  % 0x12 0x21 0x41;
568
+  // poly_coeff1    = 0x1e;  % 0x1e 0x36 0x72;
569
+
570
+  unsigned lfsrN = 7;
571
+  unsigned pc0   = 0x41;
572
+  unsigned pc1   = 0x72;
573
+  unsigned mlsN    = (1 << lfsrN)-1;
574
+
575
+  unsigned yN = mlsN*2;
576
+  unsigned yV[ yN ];
577
+  unsigned i;
578
+
579
+  cmLFSR( lfsrN, pc0, 1 << (lfsrN-1), yV, yN );
580
+
581
+  for(i=0; i<mlsN; ++i)
582
+    if( yV[i] != yV[i+mlsN] )
583
+      return false;
584
+
585
+  //atVOU_PrintL(NULL,"0x12",yV,mlsN,2);
586
+
587
+  cmLFSR( lfsrN, pc1, 1 << (lfsrN-1), yV, yN );
588
+
589
+  //atVOU_PrintL(NULL,"0x17",yV,mlsN,2);
590
+
591
+  for(i=0; i<mlsN; ++i)
592
+    if( yV[i] != yV[i+mlsN] )
593
+      return false;
594
+
595
+  return true;
469 596
 }

+ 37
- 0
cmMath.h View File

@@ -74,4 +74,41 @@ bool cmIsCloseF( float    x0, float    x1, double eps );
74 74
 bool cmIsCloseI( int      x0, int      x1, double eps );
75 75
 bool cmIsCloseU( unsigned x0, unsigned x1, double eps );
76 76
 
77
+//=================================================================
78
+// Run a length 'lfsrN' linear feedback shift register (LFSR) for 'yN' iterations to
79
+// produce a length 'yN' bit string in yV[yN].
80
+// 'lfsrN' count of bits in the shift register range: 2<= lfsrN <= 32.
81
+// 'tapMask' is a bit mask which gives the tap indexes positions for the LFSR. 
82
+// The least significant bit corresponds to the maximum delay tap position.  
83
+// The min tap position is therefore denoted by the tap mask bit location 1 << (lfsrN-1).
84
+// A minimum of two taps must exist.
85
+// 'seed' sets the initial delay state.
86
+// 'yV[yN]' is the the output vector
87
+// 'yN' is count of elements in yV.
88
+// The function resturn kOkAtRC on success or kInvalidArgsRCRC if any arguments are invalid.
89
+// /sa cmLFSR_Test.
90
+void   cmLFSR( unsigned lfsrN, unsigned tapMask, unsigned seed, unsigned* yV, unsigned yN );
91
+
92
+// Example and test code for cmLFSR() 
93
+bool cmLFSR_Test();
94
+
95
+
96
+// Generate a set of 'goldN' Gold codes using the Maximum Length Sequences (MLS) generated
97
+// by a length 'lfsrN' linear feedback shift register.
98
+// 'err' is an error object to be set if the the function fails.
99
+// 'lfsrN' is the length of the Linear Feedback Shift Registers (LFSR) used to generate the MLS.
100
+// 'poly_coeff0' tap mask for the first LFSR.
101
+// 'coeff1' tap mask the the second LFSR.
102
+// 'goldN' is the count of Gold codes to generate. 
103
+// 'yM[mlsN', goldN] is a column major output matrix where each column contains a Gold code.
104
+// 'mlsN' is the length of the maximum length sequence for each Gold code which can be
105
+// calculated as mlsN = (1 << a->lfsrN) - 1.
106
+// Note that values of 'lfsrN' and the 'poly_coeffx' must be carefully selected such that
107
+// they will produce a MLS.  For example to generate a MLS with length 31 set 'lfsrN' to 5 and
108
+// then select poly_coeff from two different elements of the set {0x12 0x14 0x17 0x1B 0x1D 0x1E}.
109
+// See http://www.ece.cmu.edu/~koopman/lfsr/index.html for a complete set of MSL polynomial
110
+// coefficients for given LFSR lengths.
111
+// Returns false if insufficient balanced pairs exist.
112
+bool   cmGenGoldCodes( unsigned lfsrN, unsigned poly_coeff0, unsigned poly_coeff1, unsigned goldN, int* yM, unsigned mlsN  );
113
+
77 114
 #endif

Loading…
Cancel
Save