correlation.frink

View or download correlation.frink in plain text format


/** This library calculates the correlation between items in lists. */



/** This calculates the autocorrelation of a single numeric list, that is, it
    identifies the periods at which sequences appear to repeat.  The result
    is a sorted list containing pairs of [offset, correlation] with the terms
    of strongest correlation being first in the list.

    If you just want a single most likely autcorrelation period, it is found at
       result@0@0

    see correlationTest.frink for an example of using it.
*/

autocorrelation[list] :=
{
   results = new array
   size = length[list]
   average = sum[list] / size

   // Scale the list around its average
   normalizedList = new array[size+1]
   denom = 0
   for i = 1 to size
   {
      term = list@(i-1) - average
      normalizedList@i = term
      denom = denom + term^2
   }

   for offset=1 to size
   {
      sum = 0
      for i = 1 to size-offset
         sum = sum + normalizedList@i * normalizedList@(i+offset)

      results.push[[offset, sum/denom]]
   }

   return sort[results, {|a,b| b@1 <=> a@1 }]
}


/** This is the partial autocorrelation of a series.  The partial
    autocorrelation is useful because it eliminates the effects of smaller
    offsets.  For example, the partial autocorrelation at offset k is the
    autocorrelation not accounted for by offsets 1 through k-1.  That means
    that, for example, if a sequence has a perfect autocorrelation with a
    offset of 5, this will *not* display any partial autocorrelation at
    10, 15, etc.

    For equation:
    https://support.minitab.com/en-us/minitab/18/help-and-how-to/modeling-statistics/time-series/how-to/autocorrelation/methods-and-formulas/methods-and-formulas/
*/

partialAutocorrelation[list] :=
{
   results = new array
   size = length[list]
   average = sum[list] / size

   // Scale the list around its average
   normalizedList = new array[size+1]
   denom = 0
   for i = 1 to size
   {
      term = list@(i-1) - average
      normalizedList@i = term
      denom = denom + term^2
   }

   for offset=1 to size
   {
      sum = 0
      for t = offset+1 to size-offset
         sum = sum + normalizedList@(t-offset) * normalizedList@(t)

      results.push[[offset, sum/denom]]
   }

   return sort[results, {|a,b| b@1 <=> a@1 }]
}


View or download correlation.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 19030 days, 12 hours, 18 minutes ago.