Advertisement
iainism

CAPL RLS implementation

May 5th, 2012
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.44 KB | None | 0 0
  1. /* CAPL implementation of RLS algorithm */
  2.  
  3. /*
  4.     CAPL Types (for reference, with C99 equivalents)
  5.     char = uint8_t  int  = int16_t   long  = int32_t   float  = IEEE 32-bit
  6.     byte = uint8_t  word = uint16_t  dword = uint32_t  double = IEEE 64-bit
  7. */
  8.  
  9. /********************* Variables required */
  10.     const byte SET_ON = 1;
  11.     const byte SET_OFF = 0;
  12.  
  13.     // Vectors, matrices and values for RLS algorithm
  14.     const byte n_theta = 2;     // Assume linear relationship, y = a*x +b;
  15.     const byte n_cov = 4;       // P \in Real^(n_theta*n_theta) [NB: byte type limits n_cov to 0xFF elements]
  16.  
  17.     double theta_s[n_theta];    // Short-term predictions
  18.     double cov_s[n_cov];        // Short-term covariance matrix
  19.     const double lambda_s = 0.98;   // Forgetting factor for short-term prediction
  20. /* Ljung (1999) says that memory of estimator is approximately M samples
  21. *     Where, M = 1 / (1 - lambda)   (lambda = 0.98 --> M = 50 samples)
  22. *     Therefore, lambda = (M - 1) / M
  23. *     lambda MUST be in interval (0, 1], typically is in [0.95, 0.995]
  24. */
  25.  
  26.     double theta_l[n_theta];    // Long-term predictions
  27.     double cov_l[n_cov];        // Long-term covariance matrix
  28.     const double lambda_l = 1.0;    // Forgetting factor for long-term prediction (no forgetting)
  29.  
  30.     // Indices for covariance matrices
  31.     const byte p11 = 0; const byte p12 = 1; const byte p21 = 2; const byte p22 = 3;
  32.  
  33.     // Indices for parameter vectors
  34.     const byte th1 = 0;     const byte th2 = 1;
  35.  
  36.     const double COV_INIT = 1e5;    // Initialisation value for estimator covariances
  37.     int thetaNotInit;       // Tracks if theta has been fully initialased
  38.  
  39. /********************* Set-up */
  40.     // Initialise covariance matrices to I*1e5:
  41.     cov_s[p11] = COV_INIT;
  42.     cov_s[p22] = COV_INIT;
  43.     cov_l[p11] = COV_INIT;
  44.     cov_l[p22] = COV_INIT;
  45.  
  46.     // Initialise theta - assume gradient = -1 initially (adjust as required)
  47.     theta_s[th1] = theta_l[th1]= -1.0;
  48.  
  49.     // Initialise theta - assume offset = 32 initially (adjust as required)
  50.     theta_s[th2] = theta_l[th2]= 32.0;
  51.  
  52. /********************* RLS functions */
  53. doRLS(double lambda, double theta[], double cov[], double x, double y)
  54. {
  55. /* Perform RLS estimation (with specified forgetting factor), system input is `x', observation is `y'
  56. *      Assumes system being parameterised is y = th1*x+th2
  57. */
  58.  
  59.     double cov_next[n_cov];     // Temporary covariance matrix
  60.     double LDivisor, L1, L2, OSAPE; // L1, L2 are gain vector elements, OSAPE is `1-step ahead prediction error'
  61.  
  62.     LDivisor = 1 + x * (x * cov[p11] + cov[p12] + cov[p21]) + cov[p22];
  63.  
  64.     L1 = (x * cov[p11] + cov[p12]) / LDivisor;
  65.     L2 = (x * cov[p21] + cov[p22]) / LDivisor;
  66.  
  67.     OSAPE = y - (x * theta[th1] + theta[th2]);
  68.  
  69.     theta[th1] = theta[th1] + L1 * OSAPE;
  70.     theta[th2] = theta[th2] + L2 * OSAPE;
  71.  
  72.     cov_next[p11] = cov[p11] - L1 * (x * cov[p11] + cov[p21]) / lambda;
  73.     cov_next[p12] = cov[p12] - L1 * (x * cov[p12] + cov[p22]) / lambda;
  74.     cov_next[p21] = cov[p21] - L2 * (x * cov[p11] + cov[p21]) / lambda;
  75.     cov_next[p22] = cov[p22] - L2 * (x * cov[p12] + cov[p22]) / lambda;
  76.  
  77.     _memcpy(cov, cov_next);
  78. }
  79.  
  80.  
  81. byte _memcpy (double dest[], double source[])
  82. {
  83. /* Copy one array of doubles to another.
  84. *     Mimics C memcpy() function.
  85.  
  86.     byte destLen, sourceLen, iter;
  87.  
  88.     destLen = elcount(dest);
  89.     sourceLen = elcount(source);
  90.  
  91.     if (destLen != sourceLen) {
  92.         runError(1001,1);   // Can't copy if not equal lengths - throw a runtime error
  93.         return SET_OFF;
  94.     } else {
  95.         for (iter = 0; iter < sourceLen; ++iter){
  96.             dest[iter] = source[iter];
  97.         }
  98.         return SET_ON;
  99.     }
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement