Changeset f613a24 in git
- Timestamp:
- Jun 13, 2012, 9:31:39 AM (11 years ago)
- Branches:
- (u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'a800fe4b3e9d37a38c5a10cc0ae9dfa0c15a4ee6')
- Children:
- 02d8afb153e54b4dca7a1c7e782b73b7df40b090
- Parents:
- ae1e243d742c878b2d7dcb278a6785540ef2b894
- Location:
- Singular
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/minpoly.cc
rae1e24 rf613a24 1 /*********************************************** 2 * Copyright (C) 2011 Sebastian Jambor * 3 * sebastian@momo.math.rwth-aachen.de * 4 ***********************************************/ 1 /************************************************* 2 * Author: Sebastian Jambor, 2011 * 3 * GPL (e-mail from June 6, 2012, 17:00:31 MESZ) * 4 * sebastian@momo.math.rwth-aachen.de * 5 ************************************************/ 5 6 6 7 … … 8 9 #include "config.h" 9 10 #include<kernel/mod2.h> 11 10 12 //#include<iomanip> 11 13 … … 67 69 for(int j = piv; j < n + rows + 1; j++) 68 70 { 69 unsigned long tmp = multMod (matrix[i][j], x, p); 70 tmp = p - tmp; 71 tmprow[j] += tmp; 72 tmprow[j] %= p; 71 if (matrix[i][j] != 0) 72 { 73 unsigned long tmp = multMod (matrix[i][j], x, p); 74 tmp = p - tmp; 75 tmprow[j] += tmp; 76 if (tmprow[j] >= p) 77 { 78 tmprow[j] -= p; 79 } 80 } 73 81 } 74 82 } … … 182 190 183 191 pivots = new unsigned[n]; 192 193 nonPivots = new unsigned[n]; 194 195 for (int i = 0; i < n; i++) 196 { 197 nonPivots[i] = i; 198 } 199 184 200 rows = 0; 185 201 } … … 187 203 NewVectorMatrix::~NewVectorMatrix () 188 204 { 205 delete nonPivots; 189 206 delete pivots; 190 207 … … 226 243 { 227 244 // subtract row[i] times the i-th row 228 for(int j = piv; j < n; j++) 229 { 230 unsigned long tmp = multMod (matrix[i][j], x, p); 231 tmp = p - tmp; 232 row[j] += tmp; 233 row[j] %= p; 245 // only the non-pivot entries have to be considered 246 // (and also the first entry) 247 row[piv] = 0; 248 249 int smallestNonPivIndex = 0; 250 while (nonPivots[smallestNonPivIndex] < piv) 251 { 252 smallestNonPivIndex++; 253 } 254 255 for (int j = smallestNonPivIndex; j < n-rows; j++) 256 { 257 unsigned ind = nonPivots[j]; 258 if (matrix[i][ind] != 0) 259 { 260 unsigned long tmp = multMod (matrix[i][ind], x, p); 261 tmp = p - tmp; 262 row[ind] += tmp; 263 if (row[ind] >= p) 264 { 265 row[ind] -= p; 266 } 267 } 234 268 } 235 269 } … … 240 274 if(piv != -1) 241 275 { 242 // normalize and insert row into the matrix 276 // Normalize and insert row into the matrix. 277 // Then reduce upwards. 243 278 normalizeRow (row, piv); 244 279 for(int i = 0; i < n; i++) … … 247 282 } 248 283 284 285 for (int i = 0; i < rows; i++) 286 { 287 unsigned x = matrix[i][piv]; 288 // if the corresponding entry in the matrix is zero, 289 // there is nothing to do 290 if (x != 0) 291 { 292 for (int j = piv; j < n; j++) 293 { 294 if (row[j] != 0) 295 { 296 unsigned long tmp = multMod(row[j], x, p); 297 tmp = p - tmp; 298 matrix[i][j] += tmp; 299 if (matrix[i][j] >= p) 300 { 301 matrix[i][j] -= p; 302 } 303 } 304 } 305 } 306 } 307 249 308 pivots[rows] = piv; 309 310 // update nonPivots 311 for (int i = 0; i < n-rows; i++) 312 { 313 if (nonPivots[i] == piv) 314 { 315 // shift everything one position to the left 316 for (int j = i; j < n-rows-1; j++) 317 { 318 nonPivots[j] = nonPivots[j+1]; 319 } 320 321 break; 322 } 323 } 324 250 325 rows++; 251 326 } … … 255 330 void NewVectorMatrix::insertMatrix (LinearDependencyMatrix & mat) 256 331 { 257 // The matrix in LinearDependencyMatrix is already in reduced form. 258 // Thus, if the current matrix is empty, we can simply copy the other matrix. 259 if(rows == 0) 260 { 261 for(int i = 0; i < mat.rows; i++) 262 { 263 for(int j = 0; j < n; j++) 264 { 265 matrix[i][j] = mat.matrix[i][j]; 266 267 rows = mat.rows; 268 for(int i = 0; i < rows; i++) 269 { 270 pivots[i] = mat.pivots[i]; 271 } 272 } 273 } 274 } 275 else 276 { 277 for(int i = 0; i < mat.rows; i++) 278 { 279 insertRow (mat.matrix[i]); 280 } 332 for(int i = 0; i < mat.rows; i++) 333 { 334 insertRow (mat.matrix[i]); 281 335 } 282 336 } 283 337 284 338 int NewVectorMatrix::findSmallestNonpivot () 339 { 340 // This method isn't very efficient, but it is called at most a few times, 341 // so efficiency is not important. 342 if(rows == n) 343 return -1; 344 345 for(int i = 0; i < n; i++) 346 { 347 bool isPivot = false; 348 for(int j = 0; j < rows; j++) 349 { 350 if(pivots[j] == i) 351 { 352 isPivot = true; 353 break; 354 } 355 } 356 357 if(!isPivot) 358 { 359 return i; 360 } 361 } 362 } 363 364 int NewVectorMatrix::findLargestNonpivot () 285 365 { 286 366 // This method isn't very efficient, but it is called at most a few times, so efficiency is not important. … … 288 368 return -1; 289 369 290 for(int i = 0; i < n; i++)370 for(int i = n-1; i >= 0; i--) 291 371 { 292 372 bool isPivot = false; … … 309 389 310 390 void vectorMatrixMult (unsigned long *vec, unsigned long **mat, 391 unsigned **nonzeroIndices, unsigned *nonzeroCounts, 311 392 unsigned long *result, unsigned n, unsigned long p) 312 393 { 313 394 unsigned long tmp; 395 314 396 for(int i = 0; i < n; i++) 315 397 { 316 398 result[i] = 0; 317 for(int j = 0; j < n ; j++)318 { 319 tmp = multMod (vec[ j], mat[j][i], p);399 for(int j = 0; j < nonzeroCounts[i]; j++) 400 { 401 tmp = multMod (vec[nonzeroIndices[i][j]], mat[nonzeroIndices[i][j]][i], p); 320 402 result[i] += tmp; 321 result[i] %= p; 403 if (result[i] >= p) 404 { 405 result[i] -= p; 406 } 322 407 } 323 408 } … … 358 443 359 444 360 int i = 0; 445 // Store the indices where the matrix has non-zero entries. 446 // This has a huge impact on spares matrices. 447 unsigned* nonzeroCounts = new unsigned[n]; 448 unsigned** nonzeroIndices = new unsigned*[n]; 449 for (int i = 0; i < n; i++) 450 { 451 nonzeroIndices[i] = new unsigned[n]; 452 nonzeroCounts[i] = 0; 453 for (int j = 0; j < n; j++) 454 { 455 if (matrix[j][i] != 0) 456 { 457 nonzeroIndices[i][nonzeroCounts[i]] = j; 458 nonzeroCounts[i]++; 459 } 460 } 461 } 462 463 int i = n-1; 361 464 362 465 unsigned long *vec = new unsigned long[n]; 363 466 unsigned long *vecnew = new unsigned long[n]; 364 467 468 unsigned loopsEven = true; 365 469 while(i != -1) 366 470 { … … 382 486 } 383 487 384 vectorMatrixMult (vec, matrix, vecnew, n, p);488 vectorMatrixMult (vec, matrix, nonzeroIndices, nonzeroCounts, vecnew, n, p); 385 489 unsigned long *swap = vec; 386 490 vec = vecnew; … … 426 530 { 427 531 newvectormat.insertMatrix (lindepmat); 428 i = newvectormat.findSmallestNonpivot (); 429 } 430 } 431 } 432 433 // TODO: take lcms of the different monomials! 532 533 // choose new unit vector from the front or the end, alternating 534 // for each round. If the matrix is the companion matrix for x^n, 535 // then taking vectors from the end is best. If it is the transpose, 536 // taking vectors from the front is best. 537 // This tries to take the middle way 538 if (loopsEven) 539 { 540 i = newvectormat.findSmallestNonpivot (); 541 } 542 else 543 { 544 i = newvectormat.findLargestNonpivot (); 545 } 546 } 547 } 548 549 loopsEven = !loopsEven; 550 } 551 552 for (int i = 0; i < n; i++) 553 { 554 delete[] nonzeroIndices[i]; 555 } 556 delete[] nonzeroIndices; 557 delete[] nonzeroCounts; 558 434 559 435 560 delete[]vecnew; … … 453 578 long tmp = p - multMod (factor, q[i], p); 454 579 a[d + i] += tmp; 455 a[d + i] %= p; 456 } 457 458 while(a[dega] == 0 && dega >= 0) 580 if (a[d + i] >= p) 581 { 582 a[d + i] -= p; 583 } 584 } 585 586 while(dega >= 0 && a[dega] == 0) 459 587 { 460 588 dega--; … … 470 598 unsigned long *result = new unsigned long[degres + 1]; 471 599 600 // initialize to zero 601 for (int i = 0; i <= degres; i++) 602 { 603 result[i] = 0; 604 } 605 472 606 while(degq <= dega) 473 607 { 474 608 unsigned d = dega - degq; 475 long inv = modularInverse (q[degq], p);609 unsigned long inv = modularInverse (q[degq], p); 476 610 result[d] = multMod (a[dega], inv, p); 477 611 for(int i = degq; i >= 0; i--) 478 612 { 479 long tmp = p - multMod (result[d], q[i], p);613 unsigned long tmp = p - multMod (result[d], q[i], p); 480 614 a[d + i] += tmp; 481 a[d + i] %= p; 482 } 483 484 while(a[dega] == 0 && dega >= 0) 615 if (a[d + i] >= p) 616 { 617 a[d + i] -= p; 618 } 619 } 620 621 while(dega >= 0 && a[dega] == 0) 485 622 { 486 623 dega--; … … 515 652 { 516 653 result[i + j] += multMod (a[i], b[j], p); 517 result[i + j] %= p; 654 if (result[i + j] >= p) 655 { 656 result[i + j] -= p; 657 } 518 658 } 519 659 } -
Singular/minpoly.h
rae1e24 rf613a24 1 1 /*********************************************************************************** 2 * Copyright (C) 2011 Sebastian Jambor * 2 * Author: Sebastian Jambor, 2011 * 3 * (C) GPL (e-mail from June 6, 2012, 17:00:31 MESZ) * 3 4 * sebastian@momo.math.rwth-aachen.de * 4 5 * * … … 110 111 unsigned long **matrix; 111 112 unsigned *pivots; 113 unsigned *nonPivots; 112 114 unsigned rows; 113 115 … … 135 137 // If no such number exists, return -1. 136 138 int findSmallestNonpivot(); 139 140 int findLargestNonpivot(); 137 141 }; 138 142 … … 161 165 unsigned long modularInverse(long long x, long long p); 162 166 163 void vectorMatrixMult(unsigned long* vec, unsigned long **mat, unsigned long* result, unsigned n, unsigned long p);167 void vectorMatrixMult(unsigned long* vec, unsigned long **mat, unsigned **nonzeroIndices, unsigned *nonzeroCounts, unsigned long* result, unsigned n, unsigned long p); 164 168 165 169 // a is a vector of length at least dega + 1, and q is a vector of length at least degq + 1,
Note: See TracChangeset
for help on using the changeset viewer.