@@ -87,6 +87,54 @@ impl SamplingExt<f64> for AGARCH<f64> {
8787 x
8888 }
8989
90+ fn sample_simd ( & self ) -> Array1 < f64 > {
91+ use crate :: stats:: distr:: normal:: SimdNormal ;
92+
93+ let p = self . alpha . len ( ) ;
94+ let q = self . beta . len ( ) ;
95+
96+ // Generate white noise
97+ let z = Array1 :: random ( self . n , SimdNormal :: new ( 0.0 , 1.0 ) ) ;
98+
99+ // Arrays for X_t and sigma_t^2
100+ let mut x = Array1 :: < f64 > :: zeros ( self . n ) ;
101+ let mut sigma2 = Array1 :: < f64 > :: zeros ( self . n ) ;
102+
103+ // Summation for unconditional variance init
104+ let sum_alpha: f64 = self . alpha . iter ( ) . sum ( ) ;
105+ let sum_delta_half: f64 = self . delta . iter ( ) . sum :: < f64 > ( ) * 0.5 ;
106+ let sum_beta: f64 = self . beta . iter ( ) . sum ( ) ;
107+ let denom = ( 1.0 - sum_alpha - sum_delta_half - sum_beta) . max ( 1e-8 ) ;
108+
109+ for t in 0 ..self . n {
110+ if t == 0 {
111+ sigma2[ t] = self . omega / denom;
112+ } else {
113+ let mut var_t = self . omega ;
114+ // p-lag terms
115+ for i in 1 ..=p {
116+ if t >= i {
117+ let x_lag = x[ t - i] ;
118+ let indicator = if x_lag < 0.0 { 1.0 } else { 0.0 } ;
119+
120+ var_t +=
121+ self . alpha [ i - 1 ] * x_lag. powi ( 2 ) + self . delta [ i - 1 ] * x_lag. powi ( 2 ) * indicator;
122+ }
123+ }
124+ // q-lag terms
125+ for j in 1 ..=q {
126+ if t >= j {
127+ var_t += self . beta [ j - 1 ] * sigma2[ t - j] ;
128+ }
129+ }
130+ sigma2[ t] = var_t;
131+ }
132+ x[ t] = sigma2[ t] . sqrt ( ) * z[ t] as f64 ;
133+ }
134+
135+ x
136+ }
137+
90138 fn n ( & self ) -> usize {
91139 self . n
92140 }
@@ -144,6 +192,55 @@ impl SamplingExt<f32> for AGARCH<f32> {
144192 x
145193 }
146194
195+ #[ cfg( feature = "simd" ) ]
196+ fn sample_simd ( & self ) -> Array1 < f32 > {
197+ use crate :: stats:: distr:: normal:: SimdNormal ;
198+
199+ let p = self . alpha . len ( ) ;
200+ let q = self . beta . len ( ) ;
201+
202+ // Generate white noise
203+ let z = Array1 :: random ( self . n , SimdNormal :: new ( 0.0 , 1.0 ) ) ;
204+
205+ // Arrays for X_t and sigma_t^2
206+ let mut x = Array1 :: < f32 > :: zeros ( self . n ) ;
207+ let mut sigma2 = Array1 :: < f32 > :: zeros ( self . n ) ;
208+
209+ // Summation for unconditional variance init
210+ let sum_alpha: f32 = self . alpha . iter ( ) . sum ( ) ;
211+ let sum_delta_half: f32 = self . delta . iter ( ) . sum :: < f32 > ( ) * 0.5 ;
212+ let sum_beta: f32 = self . beta . iter ( ) . sum ( ) ;
213+ let denom = ( 1.0 - sum_alpha - sum_delta_half - sum_beta) . max ( 1e-8 ) ;
214+
215+ for t in 0 ..self . n {
216+ if t == 0 {
217+ sigma2[ t] = self . omega / denom;
218+ } else {
219+ let mut var_t = self . omega ;
220+ // p-lag terms
221+ for i in 1 ..=p {
222+ if t >= i {
223+ let x_lag = x[ t - i] ;
224+ let indicator = if x_lag < 0.0 { 1.0 } else { 0.0 } ;
225+
226+ var_t +=
227+ self . alpha [ i - 1 ] * x_lag. powi ( 2 ) + self . delta [ i - 1 ] * x_lag. powi ( 2 ) * indicator;
228+ }
229+ }
230+ // q-lag terms
231+ for j in 1 ..=q {
232+ if t >= j {
233+ var_t += self . beta [ j - 1 ] * sigma2[ t - j] ;
234+ }
235+ }
236+ sigma2[ t] = var_t;
237+ }
238+ x[ t] = sigma2[ t] . sqrt ( ) * z[ t] ;
239+ }
240+
241+ x
242+ }
243+
147244 fn n ( & self ) -> usize {
148245 self . n
149246 }
0 commit comments