Changeset 3 for include/fflas-ffpack/ffpack_frobenius.inl
- Timestamp:
- 03/11/07 15:11:02 (2 years ago)
- Files:
-
- 1 modified
-
include/fflas-ffpack/ffpack_frobenius.inl (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
include/fflas-ffpack/ffpack_frobenius.inl
r1 r3 14 14 15 15 //--------------------------------------------------------------------- 16 // Frobenius: Las Vegas algorithm to compute the Frobeniusnormal form over a large field16 // CharpolyArithProg: Las Vegas algorithm to compute the Charpoly normal form over a large field 17 17 //--------------------------------------------------------------------- 18 18 … … 146 146 template <class Field, class Polynomial> 147 147 std::list<Polynomial>& 148 FFPACK:: Frobenius(const Field& F, std::list<Polynomial>& frobeniusForm,149 const size_t N, typename Field::Element * A, const size_t lda, const size_t c){148 FFPACK::CharpolyArithProg (const Field& F, std::list<Polynomial>& frobeniusForm, 149 const size_t N, typename Field::Element * A, const size_t lda, const size_t c){ 150 150 151 151 static typename Field::Element one, zero, mone; … … 156 156 size_t * rp = new size_t[2*N]; 157 157 158 size_t noc = static_cast<size_t>(ceil( N/double(c)));159 160 // Building the workplace matrix Aw158 size_t noc = static_cast<size_t>(ceil(double(N)/double(c))); 159 160 // Building the workplace matrix 161 161 typename Field::Element *K = new typename Field::Element[N*(noc*c)]; 162 162 typename Field::Element *K2 = new typename Field::Element[N*(noc*c)]; … … 170 170 171 171 size_t *dA = new size_t[N]; //PA 172 size_t *dK = new size_t[N];172 // size_t *dK = new size_t[N]; 173 173 174 174 … … 185 185 // K+(c-2)*noc*ldk, ldk, A, lda, zero, K+(c-1)*noc*ldk, ldk); 186 186 187 //write_field(F,cerr<<"K = "<<endl,K, c*noc,N,ldk);188 //write_field(F,cerr<<"A = "<<endl,A, N,N,ldk);187 //write_field(F,cerr<<"K = "<<endl,K, c*noc,N,ldk); 188 //write_field(F,cerr<<"A = "<<endl,A, N,N,ldk); 189 189 size_t * Pk = new size_t[N]; 190 190 size_t * Qk = new size_t[c*noc]; … … 193 193 size_t w_idx = 0; 194 194 for (size_t i=0; i<noc; ++i) 195 for (size_t j=0; j<c; ++j )196 fcopy(F, N, (K2+(w_idx ++)*ldk), 1, (K+(i+j*noc)*ldk), 1);195 for (size_t j=0; j<c; ++j, w_idx++) 196 fcopy(F, N, (K2+(w_idx)*ldk), 1, (K+(i+j*noc)*ldk), 1); 197 197 198 198 for (size_t i=0; i<noc*c; ++i) … … 200 200 201 201 size_t R = LUdivine(F, FflasNonUnit, noc*c, N, K, ldk, Pk, Qk, FfpackLQUP); 202 if (R<N){ 203 std::cerr<<"Preconditionning failed; not yet implemented"<<std::endl; 204 exit(-1); 205 } 206 202 203 //write_field(F,cerr<<"Apres LUDivine K = "<<endl,K, c*noc,N,ldk); 204 // cerr<<"Q = "; 205 // for (size_t i=0; i<noc*c; ++i) 206 // cerr<<Qk[i]<<" "; 207 // cerr<<endl; 207 208 size_t row_idx = 0; 208 size_t * d egini= new size_t[noc];209 size_t * dK = new size_t[noc]; 209 210 for (size_t i=0; i<noc; ++i) 210 degini[i]=0; 211 // size_t * degK = new size_t[c]; 212 // for (size_t i=0; i<c; ++i) 213 // degK[i]=0; 211 dK[i]=0; 214 212 215 213 size_t i=0; 216 214 row_idx=0; 215 size_t dold = c; 216 size_t nb_full_blocks = 0; 217 size_t Mk = 0; 217 218 for (size_t k = 0; k<noc; ++k){ 218 219 size_t d = 0; 219 220 while ( (d<c) && (row_idx<R) && (Qk[row_idx] == i)) {i++; row_idx++; d++;} 220 degini[k] = d; 221 if (d > dold){ 222 std::cerr << "FAIL in preconditionning phase:" 223 << " degree sequence is not monotonically not increasing" 224 << std::endl; 225 //exit (-1); 226 throw CharpolyFailed(); 227 } 228 229 dK[k] = dold = d; 230 Mk++; 231 if (d == c) 232 nb_full_blocks++; 221 233 i = Qk[row_idx]; 222 234 } 223 224 // for (size_t i = 0; i<N; ++i) 225 // if (Qk[row_idx] == i){ 226 // degini[i % noc] ++; 227 // // degK[i/noc] ++; 228 // row_idx ++; 235 //cerr<<"Mk = "<<Mk<<endl; 236 // Selection of the last iterate of each block 237 size_t bk_idx = 0; 238 //write_field (F,cerr<<"Avant fgemm K2 = "<<endl, K2, noc*c, N, ldk); 239 240 for (size_t i = 0; i < Mk; ++i){ 241 #if DEBUG 242 std::cerr<<"dK ["<<i<<"] = "<<dK[i]<<std::endl; 243 #endif 244 fcopy (F, N, (K2+i*ldk), 1, (K2 + (bk_idx + dK[i]-1)*ldk), 1); 245 //cerr<<"(bk_idx+dK[i]-1) = "<<(bk_idx+dK[i]-1)<<endl; 246 bk_idx+= c; 247 } 248 249 typename Field::Element* K2b = K2+Mk*ldk; 250 // K <- K A^T 251 252 //write_field (F,cerr<<"Avant fgemm K2 = "<<endl, K2, noc*c, N, ldk); 253 fgemm( F, FflasNoTrans, FflasTrans, Mk, N, N, one, K2, ldk, A, lda, zero, K2b, ldk); 254 255 //write_field (F,cerr<<"Apres fgemm K2b = "<<endl, K2b, Mk, N, ldk); 256 257 // K <- K P^T 258 applyP (F, FflasRight, FflasTrans, Mk, 0, R, K2b, ldk, Pk); 259 260 //write_field (F,cerr<<"Apres applyP K2b = "<<endl, K2b, Mk, N, ldk); 261 // K <- K U^-1 262 ftrsm (F, FflasRight, FflasUpper, FflasNoTrans, FflasNonUnit, Mk, R, one, K, ldk, K2b, ldk); 263 264 //write_field (F,cerr<<"Apres ftrsm K2b = "<<endl, K2b, Mk, N, ldk); 265 // K <- K Q^T 266 //applyP (F, FflasRight, FflasNoTrans, Mk, 0, R, K2b, ldk, Qk); 267 268 269 // row_idx = 0; 270 // for (size_t i=0; i<R; ++i){ 271 // for (size_t k=row_idx; k<Qk[i]; ++k) // iterate on the linearly dependent rows 272 // for (size_t j=0; j<i; ++j) 273 // F.assign( *(K+j+k*ldk),zero); 274 // row_idx = Qk[i]+1; 275 // } 276 //cerr<<"c, noc, row_idx, N = "<<c<<" "<<noc<<" "<<row_idx<<" "<<N<<endl; 277 //row_idx = noc*c -1; 278 // while (row_idx < noc*c){ 279 // for (size_t j=0; j<MIN(row_idx,N); ++j) 280 // F.assign( *(K + j + (row_idx)*ldk),zero); 281 // row_idx++; 282 // } 283 //write_field (F,cerr<<"Avant solvelb K2b = "<<endl, K2b, Mk, N, ldk); 284 // K <- K L^-1 285 //compressing L 286 // write_field (F,cerr<<"Avant compression L = "<<endl, K, noc*c, N, ldk); 287 applyP(F, FflasLeft, FflasNoTrans, N, 0, R, K, ldk, Qk); 288 //write_field (F,cerr<<"Apres compression L = "<<endl, K, noc*c, N, ldk); 289 290 ftrsm (F, FflasRight, FflasLower, FflasNoTrans, FflasUnit, Mk, R, one, K, ldk, K2b, ldk); 291 //undoing permutation on K 292 applyP(F, FflasLeft, FflasTrans, N, 0, R, K, ldk, Qk); 293 // solveLB2 (F, FflasRight, Mk, noc*c, R, K, ldk, Qk, K2b, ldk); 294 //§!!!!! 295 //applyP (F, FflasRight, FflasTrans, Mk, 0, R, K2b, ldk, Qk); 296 //write_field (F,cerr<<"Apres solvelb K2b = "<<endl, K2b, Mk, N, ldk); 297 298 // Recovery of the completed invariant factors 299 //cerr<<"// Recovery of the completed invariant factors"<<endl; 300 size_t Ma = Mk; 301 size_t Ncurr = R; 302 size_t offset = Ncurr-1; 303 size_t oldNcurr = Ncurr; 304 Polynomial *P; 305 //write_field (F,cerr<<"Recovery of the completed blocks"<<endl, K2b, Mk, N, ldk); 306 for (size_t i=Mk-1; i>=nb_full_blocks+1; --i) 307 if (dK[i] >= 1){ 308 Polynomial P (dK [i]); 309 for (size_t j=0; j < dK [i]; ++j){ 310 F.neg (P [dK [i]-j-1], *(K2b + i*ldk + (offset-j))); 311 //cerr<<" "<<(*(K2b + i*ldk + (offset-j))); 312 } 313 //cerr<<endl; 314 // for (size_t j=0; j<dK[i]; ++j) 315 // cerr<<" "<<(P)[j]; 316 frobeniusForm.push_front(P); 317 //cerr<<"Storing polynomial "<<i<<endl; 318 offset -= dK [i]; 319 Ncurr -= dK [i]; 320 //block_idx--; 321 Ma--; 322 } 323 Mk = Ma; 324 //cerr<<"taille frob = "<<frobeniusForm.size()<<endl; 325 //write_field(F,cerr,K,oldNcurr, Mk, ldk); 326 // cerr<<"nb_full_blocks, Mk, Ncurr, oldNcurr, offset = " 327 // <<nb_full_blocks<<" "<<Mk<<" "<<Ncurr<<" "<<oldNcurr<<" "<<offset<<endl; 328 329 // for (size_t i= offset+1; i<oldNcurr; ++i) 330 // for (size_t j=0; j<nb_full_blocks+1; ++j){ 331 // // cerr<<"K + "<<i<<"*ldk + "<<j<<" = "<<(*(K+i*ldk+j))<<endl; 332 // if (!F.isZero( *(K2b+i*ldk+j) )){ 333 // std::cerr<<"FAIL C != 0 in preconditionning"<<std::endl; 334 // exit(-1); 335 // } 229 336 // } 230 231 // Selection of the last iterate of each of the block 232 size_t bk_idx = 0; 233 for (size_t i = 0; i < noc; ++i){ 234 #if DEBUG 235 std::cerr<<"degini ["<<i<<"] = "<<degini[i]<<std::endl; 236 #endif 237 fcopy (F, N, (K2+i*ldk), 1, (K2 + (bk_idx + degini[i]-1)*ldk), 1); 238 bk_idx+= degini[i]; 239 } 240 // for (size_t i = 0; i < c; ++i) 241 // cerr<<"degK["<<i<<"] = "<<degK[i]<<endl; 242 243 // K <- K A^T 244 fgemm( F, FflasNoTrans, FflasTrans, noc, N, N, one, K2, ldk, A, lda, zero, K2+noc*ldk, ldk); 245 246 // K <- K P^T 247 applyP (F, FflasRight, FflasTrans, noc, 0, R, K2+noc*ldk, ldk, Pk); 248 249 // K <- K U^-1 250 ftrsm (F, FflasRight, FflasUpper, FflasNoTrans, FflasNonUnit, noc, R, one, K, ldk, K2+noc*ldk, ldk); 251 252 // K <- K Q^T 253 applyP (F, FflasRight, FflasTrans, noc, 0, R, K2+noc*ldk, ldk, Qk); 254 255 // K <- K L^-1 256 //ftrsm(F, FflasRight, FflasLower, FflasNoTrans, FflasUnit, N, R 257 solveLB (F, FflasRight, noc, N, R, K, ldk, Qk, K2+noc*ldk, ldk); 337 338 if (R<N){ 339 340 std::cerr<<"Preconditionning failed; missing rank = "<<N-R<<" completing the Krylov matrix" 341 <<std::endl; 342 // exit(-1); 343 344 Nrest = N-R; 345 //cerr<<"Nrest = "<<Nrest<<endl; 346 typename Field::Element * K21 = K + R*ldk; 347 typename Field::Element * K22 = K21 + R; 348 typename Field::Element * Ki, *Ai; 349 // Compute the n-k last rows of A' = P A^T P^T in K2_ 350 // A = A . P^t 351 applyP( F, FflasRight, FflasTrans, N, 0, R, A, lda, Pk); 352 // Copy K2_ = (A'_2)^t 353 for (Ki = K21, Ai = A+R; Ki != K21 + Nrest*ldk; Ai++, Ki+=ldk-N) 354 for ( size_t j=0; j<N*lda; j+=lda ) 355 *(Ki++) = *(Ai+j); 356 357 //write_field (F, cerr<<"A = "<<endl, A, N, N, lda); 358 359 //write_field (F, cerr<<"K2_ = "<<endl, K21, Nrest, N, ldk); 360 // A = A . P : Undo the permutation on A 361 applyP( F, FflasRight, FflasNoTrans, N, 0, R, A, lda, Pk); 362 // K2_ = K2_ . P^t (= ( P A^t P^t )2_ ) 363 applyP( F, FflasRight, FflasTrans, Nrest, 0, R, K21, ldk, Pk); 364 //write_field (F, cerr<<"K2_ ( = P A^T P^T) = "<<endl, K21, Nrest, N, ldk); 365 // K21 = K21 . S1^-1 366 //write_field (F, cerr<<"S1 = "<<endl, K,R,R, ldk); 367 ftrsm(F, FflasRight, FflasUpper, FflasNoTrans, FflasNonUnit, Nrest, R, 368 one, K, ldk, K21, ldk); 369 //write_field (F, cerr<<"% S1^-1 = "<<endl, K21, Nrest, N, ldk); 370 typename Field::Element * Arec = new typename Field::Element[Nrest*Nrest]; 371 size_t ldarec = Nrest; 372 373 // Creation of the matrix A2 for recursive call 374 for (Ki = K22, Ai = Arec; 375 Ki != K22 + Nrest*ldk; 376 Ki += (ldk-Nrest) ) 377 for ( size_t j=0; j<Nrest; ++j ) 378 *(Ai++) = *(Ki++); 379 fgemm (F, FflasNoTrans, FflasNoTrans, Nrest, Nrest, R, mone, 380 K21, ldk, K+R, ldk, one, Arec, ldarec); 381 382 std::list<Polynomial> polyList; 383 polyList.clear(); 384 //write_field (F, cerr<<"Recursive call with A = "<<endl, Arec, Nrest, Nrest, Nrest); 385 386 CharpolyArithProg (F, polyList, Nrest, Arec, ldarec, 2); 387 //cerr<<"taille polyList = "<<polyList.size()<<endl; 388 //cerr<<"Apres recursive call"<<endl; 389 delete[] Arec; 390 frobeniusForm.merge(polyList); 391 //cerr<<"taille frob = "<<frobeniusForm.size()<<endl; 392 // typename list <Polynomial>::iterator pl_it = polyList.begin(); 393 // while (pl_it != polyList.end()) 394 // frobeniusForm.push_front(*(pl_it++)); 395 396 } 397 398 258 399 delete[] Pk; 259 400 delete[] Qk; 260 401 size_t deg = c+1; 261 size_t Ma = noc; 262 size_t Mk; 263 size_t Ncurr = N; 264 for (size_t i=0; i<noc; ++i) 265 dA[i] = degini[i]; 266 267 // size_t deg = 2; 268 // size_t Ma = N; 269 // size_t Mk; 270 // size_t Ncurr = N; 271 size_t block_idx, it_idx, rp_val, nb_full_blocks; 402 for (size_t i=0; i<Mk; ++i) 403 dA[i] = dK[i]; 404 272 405 bk_idx = 0; 273 406 274 407 // write_field(F,cerr<<"Apres preconditionnement, K = "<<endl, K2+noc*ldk, noc,N,ldk); 275 typename Field::Element *Arp = new typename Field::Element[N *Ma];276 typename Field::Element *Ac = new typename Field::Element[N *Ma];408 typename Field::Element *Arp = new typename Field::Element[Ncurr*Ma]; 409 typename Field::Element *Ac = new typename Field::Element[Ncurr*Ma]; 277 410 size_t ldac = Ma; 278 size_t ldarp = N ;279 280 for (size_t i=0; i < N ; ++i)411 size_t ldarp = Ncurr; 412 413 for (size_t i=0; i < Ncurr; ++i) 281 414 for (size_t j=0; j<Ma; ++j) 282 *( Ac + i*Ma +j) = *(K2 + i + (j+noc)*ldk);415 *(K+i*ldk+j) = *(Ac + i*Ma +j) = *(K2b + i + (j)*ldk); 283 416 // for (size_t i=0; i < noc; ++i){ 284 417 // for (size_t k=0; k < degini[i]; ++k){ … … 291 424 // } 292 425 293 //delete[] degK; 294 delete[] degini; 295 // write_field(F,cerr<<"Apres preconditionnement, Ac = "<<endl, Ac, N, noc, N); 296 297 do{ 426 //write_field(F,cerr<<"Apres preconditionnement, Ac = "<<endl, Ac, Ncurr, Ma, Ma); 427 428 size_t block_idx, it_idx, rp_val; 429 430 //cerr<<"Avant a boucle : Ma, Ncurr = "<<Ma<<" "<<Ncurr<<endl; 431 while ((nb_full_blocks >= 1) && (Mk > 1)) { 298 432 delete[] K; 299 433 delete[] K2; … … 313 447 if (R < Ncurr){ 314 448 std::cerr<<"FAIL R<Ncurr"<<std::endl; 315 exit(-1); 449 throw CharpolyFailed(); 450 //exit(-1); 316 451 } 317 452 // Computation of the degree vector dK … … 330 465 while ( /*(g<Ncurr ) &&*/ (rp[g] == rp_val) && (it_idx < deg )); 331 466 if ((block_idx)&&(it_idx > dK[block_idx-1])){ 467 throw CharpolyFailed(); 332 468 std::cerr<<"FAIL d non decroissant"<<std::endl; 333 exit(-1);469 //exit(-1); 334 470 } 335 471 dK[block_idx++] = it_idx; … … 407 543 // Copying the last rows of A times K 408 544 //cerr<<"// Copying the last rows of k "<<nb_full_blocks<<" "<<Mk<<endl; 409 size_toffset = (deg-2)*nb_full_blocks;545 offset = (deg-2)*nb_full_blocks; 410 546 for (size_t i = nb_full_blocks; i < Mk; ++i) { 411 547 //cerr<<"dK["<<i<<"] = "<<dK[i]<<" deg = "<<deg<<endl; … … 437 573 size_t *Q=new size_t[Mk]; 438 574 if (LUdivine (F, FflasNonUnit, Mk, Mk , K2 + (Ncurr-Mk)*ldk, ldk, P, Q, FfpackLQUP) < Mk){ 575 // should never happen (not a LAS VEGAS check) 439 576 std::cerr<<"FAIL R2 < MK"<<std::endl; 440 577 // exit(-1); … … 469 606 //write_field(F, cerr<<"K = "<<endl, K, Ncurr, Mk, ldk); 470 607 608 471 609 // Recovery of the completed invariant factors 472 610 //cerr<<"// Recovery of the completed invariant factors"<<endl; … … 476 614 for (size_t i=Mk-1; i>=nb_full_blocks+1; --i) 477 615 if (dK[i] >= 1){ 478 Polynomial * P = new Polynomial(dK [i]);616 Polynomial P (dK [i]); 479 617 for (size_t j=0; j < dK[i]; ++j) 480 F.neg( P ->operator[](dK[i]-j-1), *(K + i + (offset-j)*ldk));481 frobeniusForm.push_front( *P);618 F.neg( P[dK[i]-j-1], *(K + i + (offset-j)*ldk)); 619 frobeniusForm.push_front(P); 482 620 offset -= dK[i]; 483 621 Ncurr -= dK[i]; … … 493 631 if (!F.isZero( *(K+i*ldk+j) )){ 494 632 std::cerr<<"FAIL C != 0"<<std::endl; 495 exit(-1); 633 throw CharpolyFailed(); 634 //exit(-1); 496 635 } 497 636 } … … 523 662 deg++; 524 663 525 } while ((nb_full_blocks >= 1) && (Mk > 1));664 } 526 665 527 666 // Recovery of the first invariant factor 528 667 //cerr<<"// Recovery of the first invariant factor"<<endl; 529 Polynomial * P = new Polynomial(dK [0]);668 Polynomial Pl(dK [0]); 530 669 for (size_t j=0; j < dK[0]; ++j) 531 F.neg( P ->operator[](j), *(K + j*ldk));532 frobeniusForm.push_front( *P);670 F.neg( Pl[j], *(K + j*ldk)); 671 frobeniusForm.push_front(Pl); 533 672 delete[] rp; 534 673 delete[] Arp;
