| | 93 | //! access debug function |
| | 94 | mat getL(){ return L; } |
| | 95 | |
| | 96 | private: |
| | 97 | RV trs_crv; |
| | 98 | |
| | 99 | //! compute complete RV from all of RVs used in Losses array |
| | 100 | /*RV getCompleteRV() { |
| | 101 | RV cRv; //complete RV |
| | 102 | |
| | 103 | //cRv has form [rv, "other", 1] |
| | 104 | cRv = rv; //add rv |
| | 105 | |
| | 106 | //add "other" |
| | 107 | for(int i = 0; i < Losses.size(); i++) |
| | 108 | cRv.add(Losses(i).rv); |
| | 109 | |
| | 110 | cRv.add(rvOne); //add 1 |
| | 111 | |
| | 112 | return cRv; |
| | 113 | }*/ |
| | 114 | |
| | 115 | mat getMatRow (quadraticfn sourceQfn){ //returns row of matrixes crated from quadratic function |
| | 116 | |
| | 117 | mat tmpMatRow; //tmp variable for row of matrixes to be returned |
| | 118 | tmpMatRow.set_size(sourceQfn.Q.rows(), trs_crv.countsize()); //(rows, cols) |
| | 119 | tmpMatRow.zeros(); |
| | 120 | |
| | 121 | //set data in tmpMatRow - other times then current replace using model |
| | 122 | RV tmpQrv = sourceQfn.rv; |
| | 123 | for(int j = 0; j < tmpQrv.length(); j++){ |
| | 124 | ivec j_vec(1); |
| | 125 | j_vec(0) = j; |
| | 126 | if( (tmpQrv.time(j) == 0) && (sum(tmpQrv(j_vec).findself(trs_crv)) > (-1)) ) {//sum is only formal, summed vector is in fact scalar |
| | 127 | //jth element of tmpQrv is also element of trs_crv with a proper time |
| | 128 | ivec copytarget = (tmpQrv(j_vec)).dataind(trs_crv); //get target column position in tmpMatRow |
| | 129 | ivec copysource = (tmpQrv(j_vec)).dataind(tmpQrv); //get source column position in Losses(i).Q |
| | 130 | if(copytarget.size() != copysource.size()) {return mat(0); /*error*/} |
| | 131 | vec copycol; |
| | 132 | for(int k = 0; k < copysource.size(); k++){ |
| | 133 | copycol = sourceQfn.Q._Ch().get_col(copysource(k)); |
| | 134 | tmpMatRow.set_col(copytarget(k), copycol); |
| | 135 | } |
| | 136 | } |
| | 137 | else { |
| | 138 | //cout << "USING MODEL" << endl; |
| | 139 | //jth tmpQrv element is not in trs_crv -> using Model to teplace it |
| | 140 | ivec copysource;// = (tmpQrv(j_vec)).findself(tmpQrv); //get source column position in Losses(i).Q |
| | 141 | |
| | 142 | //int selectedModel = -1; |
| | 143 | |
| | 144 | //int k; |
| | 145 | ////find first usable replacement in Model |
| | 146 | //for(k = 0; k < Models.size(); k++){ |
| | 147 | // if( sum((tmpQrv(j_vec)).findself(Models(k).rv_ret)) > (-1) ){ |
| | 148 | // //TODO is tmpQrv(j) in kth Models RV |
| | 149 | // //if( (Models(k)).rv_ret.findself_ids(trs_crv) ){//??????????????????? |
| | 150 | // // is kth Models rv_ret subset of trs_crv |
| | 151 | |
| | 152 | // selectedModel = k; |
| | 153 | // break; |
| | 154 | |
| | 155 | // //} |
| | 156 | // } |
| | 157 | //} |
| | 158 | |
| | 159 | //!model is model_rv_ret = sum(Array<linfn>) = sum( A1*rv + B1 + ... + An*rv + Bn) |
| | 160 | |
| | 161 | //if(selectedModel == -1) {cout << "NO MODEL" << endl;return mat("0");}//ERROR - inconsistent model data; |
| | 162 | //!!TODO!!if(NOT((tmpQrv(j_vec)).findself(model_rv_ret))) {cout << "NO MODEL" << endl;return mat("0");}//ERROR - inconsistent model data; |
| | 163 | //use kth Model to convert tmpQrv memeber to trs_crv memeber |
| | 164 | |
| | 165 | //get submatrix from Q which represents jth tmpQrv data |
| | 166 | copysource = (tmpQrv(j_vec)).dataind(tmpQrv); //get source column position in Losses(i).Q |
| | 167 | mat copysubmat; |
| | 168 | copysubmat.set_size(sourceQfn.Q.rows(), copysource.size()); //(rows, cols) |
| | 169 | copysubmat.zeros(); |
| | 170 | vec copycol; |
| | 171 | int k; |
| | 172 | for(k = 0; k < copysource.size(); k++){ |
| | 173 | copycol = sourceQfn.Q._Ch().get_col(copysource(k)); |
| | 174 | copysubmat.set_col(k, copycol); |
| | 175 | } |
| | 176 | |
| | 177 | //check every Models element if it is a proper substitution: tmpQrv(j_vec) memeber of rv_ret |
| | 178 | for(k = 0; k < Models.size(); k++){ |
| | 179 | if( sum((tmpQrv(j_vec)).findself(Models(k).rv_ret)) > (-1) ){ //formal sum, find usable model |
| | 180 | //check if model is correct |
| | 181 | ivec check = (Models(k).rv).findself(trs_crv); |
| | 182 | if(sum(check) <= -check.size()){ |
| | 183 | bdm_assert (false , "Incorrect Model: Unusable Models element!" ); |
| | 184 | continue; |
| | 185 | } |
| | 186 | |
| | 187 | //create transformed submatrix |
| | 188 | mat transsubmat = copysubmat * ((Models(k)).A); |
| | 189 | |
| | 190 | //put them on a right place in tmpQrv |
| | 191 | ivec copytarget = (Models(k)).rv.dataind(trs_crv); //get target column position in tmpMatRow |
| | 192 | |
| | 193 | //copy transsubmat into tmpMatRow with adding to current one |
| | 194 | // tmpMatRow(new) = tmpMatRow(old) + transsubmat /all in proper indices |
| | 195 | int l; |
| | 196 | for(l = 0; l < copysource.size(); l++){ |
| | 197 | copycol = tmpMatRow.get_col(copytarget(l)); |
| | 198 | copycol += transsubmat.get_col(l); |
| | 199 | tmpMatRow.set_col(copytarget(l), copycol); |
| | 200 | } |
| | 201 | |
| | 202 | //if linear fnc constant element vec B is nonzero |
| | 203 | vec constElB = (Models(k)).B; |
| | 204 | if(prod(constElB) != 0){ |
| | 205 | //copy transformed constant vec into last (1's) col in tmpMatRow |
| | 206 | int lastcol = tmpMatRow.cols() - 1; |
| | 207 | copycol = tmpMatRow.get_col(lastcol); |
| | 208 | copycol += (copysubmat * ((Models(k)).B)); |
| | 209 | tmpMatRow.set_col(lastcol, copycol); |
| | 210 | } |
| | 211 | } |
| | 212 | |
| | 213 | } |
| | 214 | |
| | 215 | |
| | 216 | } |
| | 217 | } |
| | 218 | |
| | 219 | return tmpMatRow; |
| | 220 | } |
| | 221 | |
| | 222 | //! create first(0) or other (1) pre_qr matrix |
| | 223 | void build_pre_qr(bool next) { |
| | 224 | int i; |
| | 225 | //used fake quadratic function from tolC matrix |
| | 226 | quadraticfn fakeQfn; |
| | 227 | |
| | 228 | //RV pretrs_crv = getCompleteRV(); // crv before transformation based on Losses array |
| | 229 | |
| | 230 | //set proper size of pre_qr matrix |
| | 231 | int rows = 0; |
| | 232 | for(i = 0; i < Losses.size(); i++) |
| | 233 | rows += Losses(i).Q.rows(); |
| | 234 | if(!next) rows += finalLoss.Q.rows(); |
| | 235 | else{ |
| | 236 | //used fake quadratic function from tolC matrix |
| | 237 | //setup fakeQfn |
| | 238 | fakeQfn.Q.setCh(tolC); |
| | 239 | RV fakeM1; |
| | 240 | fakeM1 = rvc; |
| | 241 | fakeM1.add(RV("1", 1, 0)); |
| | 242 | fakeM1.t_plus(1); //RV in time t+1 => necessary use of Model to get RV in time t |
| | 243 | fakeQfn.rv = fakeM1; |
| | 244 | |
| | 245 | rows += fakeQfn.Q.rows(); |
| | 246 | } |
| | 247 | //cout << "buildpreqr trscrv: " << trs_crv << " of size " << trs_crv.countsize() << endl; |
| | 248 | pre_qr.set_size(rows, trs_crv.countsize()); //(rows, cols) |
| | 249 | pre_qr.zeros(); |
| | 250 | |
| | 251 | //fill pre_qr matrix for each Losses quadraticfn |
| | 252 | int rowIndex = 0; |
| | 253 | mat tmpMatRow; |
| | 254 | for(i = 0; i < Losses.size(); i++) { |
| | 255 | rows = Losses(i).Q.rows(); |
| | 256 | |
| | 257 | //compute row matrix and insert it on proper place in pre_qr |
| | 258 | tmpMatRow = getMatRow(Losses(i)); |
| | 259 | //cout << "tmpMatRow no " << i << endl << tmpMatRow << endl; |
| | 260 | //copy tmpMatRow in pre_qr |
| | 261 | |
| | 262 | /*cout << "submatrix ( " << rowIndex << ", " << |
| | 263 | (rowIndex + rows - 1) << ", 0, " << (trs_crv.countsize() - 1) << ")" << endl; |
| | 264 | cout << "seting with submatrix of rows " << tmpMatRow.rows() << " and cols " << tmpMatRow.cols() << |
| | 265 | "and data " << endl << tmpMatRow << endl;*/ |
| | 266 | |
| | 267 | pre_qr.set_submatrix(rowIndex, (rowIndex + rows - 1), 0, (trs_crv.countsize() - 1), tmpMatRow); //(int r1, int r2, int c1, int c2, const Mat< Num_T > &m) |
| | 268 | rowIndex += rows; |
| | 269 | } |
| | 270 | |
| | 271 | if(!next) { |
| | 272 | tmpMatRow = getMatRow(finalLoss); |
| | 273 | pre_qr.set_submatrix(rowIndex, (rowIndex + finalLoss.Q.rows() - 1), 0, (trs_crv.countsize() - 1), tmpMatRow); //(int r1, int r2, int c1, int c2, const Mat< Num_T > &m) |
| | 274 | } |
| | 275 | else { //next |
| | 276 | //based on tolC but time must be shifted by one - all implemented in getMatRow method |
| | 277 | |
| | 278 | //get matrix row via getMatRow method |
| | 279 | tmpMatRow = getMatRow(fakeQfn); |
| | 280 | /*cout << "submatrix ( " << rowIndex << ", " << |
| | 281 | (rowIndex + fakeQfn.Q.rows() - 1) << ", 0, " << (trs_crv.countsize() - 1) << ")" << endl; |
| | 282 | cout << "seting with submatrix of rows " << tmpMatRow.rows() << " and cols " << tmpMatRow.cols() << |
| | 283 | "and data " << endl << tmpMatRow << endl;*/ |
| | 284 | pre_qr.set_submatrix(rowIndex, (rowIndex + fakeQfn.Q.rows() - 1), 0, (trs_crv.countsize() - 1), tmpMatRow); //(int r1, int r2, int c1, int c2, const Mat< Num_T > &m) |
| | 285 | //cout << "NEXT 3" << endl; |
| | 286 | } |
| | 287 | //cout << "last tmpMatRow " << endl << tmpMatRow << endl; |
| | 288 | } |
| | 289 | |
| | 290 | mat get_qr_submatrix(int submatidx) { |
| | 291 | /* |
| | 292 | |rv||rvc||1| |
| | 293 | |
| | 294 | AAAABBBBBBBB |
| | 295 | AAABBBBBBBB |
| | 296 | AABBBBBBBB |
| | 297 | ABBBBBBBB |
| | 298 | CCCCCCCC |
| | 299 | CCCCCCC |
| | 300 | CCCCCC |
| | 301 | CCCCC |
| | 302 | CCCC |
| | 303 | CCC |
| | 304 | CC |
| | 305 | C |
| | 306 | */ |
| | 307 | /*! |
| | 308 | submatidx | get_submatrix |
| | 309 | ----------|-------------- |
| | 310 | 0 | A |
| | 311 | 1 | B |
| | 312 | 2+ | C |
| | 313 | */ |
| | 314 | int sizeA = rv.countsize(); |
| | 315 | int colsB = post_qr.cols() - sizeA; |
| | 316 | // rowsB = sizeA; |
| | 317 | // colsC = colsB; |
| | 318 | //not required whole C - it is triangular |
| | 319 | //=> NOT int rowsC = post_qr.rows() - sizeA; |
| | 320 | //=> int sizeC = colsB; |
| | 321 | |
| | 322 | mat qr_submat; |
| | 323 | |
| | 324 | if(submatidx == 0) qr_submat = post_qr.get(0, (sizeA - 1), 0, (sizeA - 1)); //(int r1, int r2, int c1, int c2) |
| | 325 | else if(submatidx == 1) qr_submat = post_qr.get(0, (sizeA - 1), sizeA, (post_qr.cols() - 1)); |
| | 326 | else qr_submat = post_qr.get(sizeA, (sizeA + colsB - 1), sizeA, (post_qr.cols() - 1)); |
| | 327 | |
| | 328 | return qr_submat; |
| | 329 | } |
| | 330 | |
| | 331 | void generateLmat(int timestep){ |
| | 332 | //! control strategy matrix L is based on loss in time: |
| | 333 | //! time = horizon loss = finalLoss |
| | 334 | //! time = horizon - 1 loss = sum(Losses)(time) + finalLoss |
| | 335 | //! time = horizon - k > 1 loss = sum(Losses)(time) + tolC time+1 loss |
| | 336 | |
| | 337 | trs_crv = rv; //transformed crv only in proper times, form [rv, rvc, 1] |
| | 338 | trs_crv.add(rvc); |
| | 339 | trs_crv.add(RV("1", 1, 0)); |
| | 340 | |
| | 341 | //!first time, time = horizon - 1 |
| | 342 | if(timestep == (horizon-1)) |
| | 343 | build_pre_qr(0); |
| | 344 | |
| | 345 | //!other times |
| | 346 | else |
| | 347 | build_pre_qr(1); |
| | 348 | |
| | 349 | mat tmpQ; |
| | 350 | qr(pre_qr, tmpQ, post_qr); |
| | 351 | //cout << "preQR " << pre_qr << endl << "postQR" << post_qr << endl; |
| | 352 | mat qrA = get_qr_submatrix(0); |
| | 353 | mat qrB = get_qr_submatrix(1); |
| | 354 | mat qrC = get_qr_submatrix(2); |
| | 355 | //cout << "A " << qrA << "\n B " << qrB << "\n C " << qrC << endl; |
| | 356 | |
| | 357 | L = - inv(qrA)*qrB; ///////// INVERSE OF TRIANGLE MATRIX! better? |
| | 358 | tolC = qrC; |
| | 359 | } |
| | 360 | |