| 152 | void StateCanonical::connect_mlnorm ( const mlnorm<fsqmat> &ml ) { |
| 153 | //get ids of yrv |
| 154 | const RV &yrv = ml._rv(); |
| 155 | //need to determine u_t - it is all in _rvc that is not in ml._rv() |
| 156 | RV rgr0 = ml._rvc().remove_time(); |
| 157 | RV urv = rgr0.subt ( yrv ); |
| 158 | |
| 159 | //We can do only 1d now... :( |
| 160 | bdm_assert ( yrv._dsize() == 1, "Only for SISO so far..." ); |
| 161 | |
| 162 | // create names for |
| 163 | RV xrv; //empty |
| 164 | RV Crv; //empty |
| 165 | int td = ml._rvc().mint(); |
| 166 | // assuming strictly proper function!!! |
| 167 | for ( int t = -1; t >= td; t-- ) { |
| 168 | xrv.add ( yrv.copy_t ( t ) ); |
| 169 | Crv.add ( urv.copy_t ( t ) ); |
| 170 | } |
| 171 | |
| 172 | // get mapp |
| 173 | th2A.set_connection ( xrv, ml._rvc() ); |
| 174 | th2C.set_connection ( Crv, ml._rvc() ); |
| 175 | th2D.set_connection ( urv, ml._rvc() ); |
| 176 | |
| 177 | //set matrix sizes |
| 178 | this->A = zeros ( xrv._dsize(), xrv._dsize() ); |
| 179 | for ( int j = 1; j < xrv._dsize(); j++ ) { |
| 180 | A ( j, j - 1 ) = 1.0; // off diagonal |
| 181 | } |
| 182 | this->B = zeros ( xrv._dsize(), 1 ); |
| 183 | this->B ( 0 ) = 1.0; |
| 184 | this->C = zeros ( 1, xrv._dsize() ); |
| 185 | this->D = zeros ( 1, urv._dsize() ); |
| 186 | this->Q = zeros ( xrv._dsize(), xrv._dsize() ); |
| 187 | // R is set by update |
| 188 | |
| 189 | //set cache |
| 190 | this->A1row = zeros ( xrv._dsize() ); |
| 191 | this->C1row = zeros ( xrv._dsize() ); |
| 192 | this->D1row = zeros ( urv._dsize() ); |
| 193 | |
| 194 | update_from ( ml ); |
| 195 | validate(); |
| 196 | }; |
| 197 | |
| 198 | void StateCanonical::update_from ( const mlnorm<fsqmat> &ml ) { |
| 199 | |
| 200 | vec theta = ml._A().get_row ( 0 ); // this |
| 201 | |
| 202 | th2A.filldown ( theta, A1row ); |
| 203 | th2C.filldown ( theta, C1row ); |
| 204 | th2D.filldown ( theta, D1row ); |
| 205 | |
| 206 | R = ml._R(); |
| 207 | |
| 208 | A.set_row ( 0, A1row ); |
| 209 | C.set_row ( 0, C1row + D1row ( 0 ) *A1row ); |
| 210 | D.set_row ( 0, D1row ); |
| 211 | } |
| 212 | |
| 213 | void StateFromARX::connect_mlnorm ( const mlnorm<chmat> &ml, RV &xrv, RV &urv ) { |
| 214 | //get ids of yrv |
| 215 | const RV &yrv = ml._rv(); |
| 216 | //need to determine u_t - it is all in _rvc that is not in ml._rv() |
| 217 | const RV &rgr = ml._rvc(); |
| 218 | RV rgr0 = rgr.remove_time(); |
| 219 | urv = rgr0.subt ( yrv ); |
| 220 | |
| 221 | // create names for state variables |
| 222 | xrv = yrv; |
| 223 | |
| 224 | int y_multiplicity = -rgr.mint ( yrv ); |
| 225 | int y_block_size = yrv.length() * ( y_multiplicity ); // current yt + all delayed yts |
| 226 | for ( int m = 0; m < y_multiplicity - 1; m++ ) { // ========= -1 is important see arx2statespace_notes |
| 227 | xrv.add ( yrv.copy_t ( -m - 1 ) ); //add delayed yt |
| 228 | } |
| 229 | //! temporary RV for connection to ml.rvc, since notation of xrv and ml.rvc does not match |
| 230 | RV xrv_ml = xrv.copy_t ( -1 ); |
| 231 | |
| 232 | // add regressors |
| 233 | ivec u_block_sizes ( urv.length() ); // no_blocks = yt + unique rgr |
| 234 | for ( int r = 0; r < urv.length(); r++ ) { |
| 235 | RV R = urv.subselect ( vec_1 ( r ) ); //non-delayed element of rgr |
| 236 | int r_size = urv.size ( r ); |
| 237 | int r_multiplicity = -rgr.mint ( R ); |
| 238 | u_block_sizes ( r ) = r_size * r_multiplicity ; |
| 239 | for ( int m = 0; m < r_multiplicity; m++ ) { |
| 240 | xrv.add ( R.copy_t ( -m - 1 ) ); //add delayed yt |
| 241 | xrv_ml.add ( R.copy_t ( -m - 1 ) ); //add delayed yt |
| 242 | } |
| 243 | } |
| 244 | // add constant |
| 245 | if ( any ( ml._mu_const() != 0.0 ) ) { |
| 246 | have_constant = true; |
| 247 | xrv.add ( RV ( "bdm_reserved_constant_one", 1 ) ); |
| 248 | } else { |
| 249 | have_constant = false; |
| 250 | } |
| 251 | |
| 252 | |
| 253 | // get mapp |
| 254 | th2A.set_connection ( xrv_ml, ml._rvc() ); |
| 255 | th2B.set_connection ( urv, ml._rvc() ); |
| 256 | |
| 257 | //set matrix sizes |
| 258 | this->A = zeros ( xrv._dsize(), xrv._dsize() ); |
| 259 | //create y block |
| 260 | diagonal_part ( this->A, yrv._dsize(), 0, y_block_size - yrv._dsize() ); |
| 261 | |
| 262 | this->B = zeros ( xrv._dsize(), urv._dsize() ); |
| 263 | //add diagonals for rgr |
| 264 | int active_x = y_block_size; |
| 265 | for ( int r = 0; r < urv.length(); r++ ) { |
| 266 | diagonal_part ( this->A, active_x + urv.size ( r ), active_x, u_block_sizes ( r ) - urv.size ( r ) ); |
| 267 | this->B.set_submatrix ( active_x, 0, eye ( urv.size ( r ) ) ); |
| 268 | active_x += u_block_sizes ( r ); |
| 269 | } |
| 270 | this->C = zeros ( yrv._dsize(), xrv._dsize() ); |
| 271 | this->C.set_submatrix ( 0, 0, eye ( yrv._dsize() ) ); |
| 272 | this->D = zeros ( yrv._dsize(), urv._dsize() ); |
| 273 | this->R.setCh ( zeros ( yrv._dsize(), yrv._dsize() ) ); |
| 274 | this->Q.setCh ( zeros ( xrv._dsize(), xrv._dsize() ) ); |
| 275 | // Q is set by update |
| 276 | |
| 277 | update_from ( ml ); |
| 278 | validate(); |
| 279 | } |
| 280 | |
| 281 | void StateFromARX::update_from ( const mlnorm<chmat> &ml ) { |
| 282 | vec Arow = zeros ( A.cols() ); |
| 283 | vec Brow = zeros ( B.cols() ); |
| 284 | // ROW- WISE EVALUATION ===== |
| 285 | for ( int i = 0; i < ml._rv()._dsize(); i++ ) { |
| 286 | |
| 287 | vec theta = ml._A().get_row ( i ); |
| 288 | |
| 289 | th2A.filldown ( theta, Arow ); |
| 290 | if ( have_constant ) { |
| 291 | // constant is always at the end no need for datalink |
| 292 | Arow ( A.cols() - 1 ) = ml._mu_const() ( i ); |
| 293 | } |
| 294 | this->A.set_row ( i, Arow ); |
| 295 | |
| 296 | th2B.filldown ( theta, Brow ); |
| 297 | this->B.set_row ( i, Brow ); |
| 298 | } |
| 299 | this->Q._Ch().set_submatrix ( 0, 0, ml.__R()._Ch() ); |
| 300 | |
| 301 | } |