# Class: Statsample::TimeSeries::Pacf::Pacf

Inherits:
Object
• Object
show all
Defined in:
lib/statsample-timeseries/timeseries/pacf.rb

## Class Method Summary collapse

• Returns diagonal elements of matrices Will later abstract it to utilities.

• # Yule Walker Algorithm From the series, estimates AR(p)(autoregressive) parameter using Yule-Waler equation.

## Class Method Details

### .diag(mat) ⇒ Object

Returns diagonal elements of matrices Will later abstract it to utilities

 ``` 65 66 67``` ```# File 'lib/statsample-timeseries/timeseries/pacf.rb', line 65 def self.diag(mat) return mat.each_with_index(:diagonal).map { |x, r, c| x } end```

# Levinson-Durbin Algorithm

## Parameters

• series: timeseries, or a series of autocovariances

• nlags: integer(default: 10): largest lag to include in recursion or order of the AR process

• is_acovf: boolean(default: false): series is timeseries if it is false, else contains autocavariances

## Returns:

• sigma_v: estimate of the error variance

• arcoefs: AR coefficients

• pacf: pacf function

• sigma: some function

 ``` 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61``` ```# File 'lib/statsample-timeseries/timeseries/pacf.rb', line 28 def self.levinson_durbin(series, nlags = 10, is_acovf = false) if is_acovf series = series.map(&:to_f) else #nlags = order(k) of AR in this case series = series.acvf.map(&:to_f)[0..nlags] end #phi = Array.new((nlags+1), 0.0) { Array.new(nlags+1, 0.0) } order = nlags phi = Matrix.zero(nlags + 1) sig = Array.new(nlags+1) #setting initial point for recursion: phi[1,1] = series[1]/series[0] #phi[1][1] = series[1]/series[0] sig[1] = series[0] - phi[1, 1] * series[1] 2.upto(order).each do |k| phi[k, k] = (series[k] - (Statsample::Vector.new(phi[1...k, k-1]) * series[1...k].reverse.to_ts).sum) / sig[k-1] #some serious refinement needed in above for matrix manipulation. Will do today 1.upto(k-1).each do |j| phi[j, k] = phi[j, k-1] - phi[k, k] * phi[k-j, k-1] end sig[k] = sig[k-1] * (1-phi[k, k] ** 2) end sigma_v = sig[-1] arcoefs_delta = phi.column(phi.column_size - 1) arcoefs = arcoefs_delta[1..arcoefs_delta.size] pacf = diag(phi) pacf[0] = 1.0 return [sigma_v, arcoefs, pacf, sig, phi] end```

### .pacf_yw(timeseries, max_lags, method = 'yw') ⇒ Object

 ``` 6 7 8 9 10 11 12 13 14``` ```# File 'lib/statsample-timeseries/timeseries/pacf.rb', line 6 def self.pacf_yw(timeseries, max_lags, method = 'yw') #partial autocorrelation by yule walker equations. #Inspiration: StatsModels pacf = [1.0] (1..max_lags).map do |i| pacf << yule_walker(timeseries, i, method)[0][-1] end pacf end```

### Solves matrix equations

Solves for X in AX = B

 ``` 148 149 150 151 152 153 154 155 156 157 158 159``` ```# File 'lib/statsample-timeseries/timeseries/pacf.rb', line 148 def self.solve_matrix(matrix, out_vector) solution_vector = Array.new(out_vector.size, 0) matrix = matrix.to_a k = 0 matrix.each do |row| row.each_with_index do |element, i| solution_vector[k] += element * 1.0 * out_vector[i] end k += 1 end solution_vector end```

# ToEplitz

Generates teoeplitz matrix from an array en.wikipedia.org/wiki/Toeplitz_matrix Toeplitz matrix are equal when they are stored in row & column major

## Parameters

• arr: array of integers;

## Usage

``````arr = [0,1,2,3]
Pacf.toeplitz(arr)
``````

## Returns

[[0, 1, 2, 3],

``````[1, 0, 1, 2],
[2, 1, 0, 1],
[3, 2, 1, 0]]
``````
 ``` 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144``` ```# File 'lib/statsample-timeseries/timeseries/pacf.rb', line 126 def self.toeplitz(arr) eplitz_matrix = Array.new(arr.size) { Array.new(arr.size) } 0.upto(arr.size - 1) do |i| j = 0 index = i while i >= 0 do eplitz_matrix[index][j] = arr[i] j += 1 i -= 1 end i = index + 1; k = 1 while i < arr.size do eplitz_matrix[index][j] = arr[k] i += 1; j += 1; k += 1 end end eplitz_matrix end```

# Yule Walker Algorithm

From the series, estimates AR(p)(autoregressive) parameter using Yule-Waler equation. See - en.wikipedia.org/wiki/Autoregressive_moving_average_model

## Parameters

• ts: timeseries

• k: order, default = 1

• method: can be 'yw' or 'mle'. If 'yw' then it is unbiased, denominator is (n - k)

## Returns

• rho: autoregressive coefficients

• sigma: sigma parameter

 ``` 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110``` ```# File 'lib/statsample-timeseries/timeseries/pacf.rb', line 82 def self.yule_walker(ts, k = 1, method='yw') ts = ts - ts.mean n = ts.size if method.downcase.eql? 'yw' #unbiased => denominator = (n - k) denom =->(k) { n - k } else #mle #denominator => (n) denom =->(k) { n } end r = Array.new(k + 1) { 0.0 } r[0] = ts.map { |x| x**2 }.inject(:+).to_f / denom.call(0).to_f 1.upto(k) do |l| r[l] = (ts[0...-l].zip(ts[l...ts.size])).map do |x| x.inject(:*) end.inject(:+).to_f / denom.call(l).to_f end r_R = toeplitz(r[0...-1]) mat = Matrix.columns(r_R).inverse() phi = solve_matrix(mat, r[1..r.size]) phi_vector = Statsample::Vector.new(phi, :scale) r_vector = Statsample::Vector.new(r[1..r.size], :scale) sigma = r[0] - (r_vector * phi_vector).sum return [phi, sigma] end```