00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef SYNAPS_ARITHM_ALGEBRAIC_BSOLVER_H
00017 #define SYNAPS_ARITHM_ALGEBRAIC_BSOLVER_H
00018
00019 #include <synaps/init.h>
00020 #include <synaps/usolve/Algebraic.h>
00021 #include <synaps/usolve/algebraic/sign_fct_2.h>
00022
00023 #include <synaps/mpol/MPoly_2_2.h>
00024
00025 #include <synaps/usolve/sturm/solve_small.h>
00026
00027 #include <synaps/linalg/VectDse.h>
00028
00029
00030 __ALGEBRAIC_BEGIN_NAMESPACE
00031
00033
00034
00035
00036 template<class A>
00037 VectDse<A> make_vector(const A& a, const A& b)
00038 {
00039 VectDse<A> res(2,AsSize());
00040 res[0]=a;res[1]=b;
00041 return res;
00042 }
00043
00044
00045
00046 template < typename SOLVER,
00047 typename OutputIterator >
00048 OutputIterator
00049 solve_for_circles( const typename SOLVER::MPoly_2_2& f1,
00050 const typename SOLVER::MPoly_2_2& f2,
00051 OutputIterator res,
00052 const SOLVER& mth)
00053 {
00054 typedef typename SOLVER::Poly POLY;
00055 typedef typename SOLVER::RO_t RO_t;
00056 typedef typename SOLVER::FT FT;
00057
00058 POLY Rx = resultant_y<POLY>(f1, f2);
00059 POLY Ry = resultant_x<POLY>(f1, f2);
00060
00061
00062
00063 Seq<RO_t> solX;
00064 Seq<RO_t> solY;
00065
00066 solve(Rx, std::back_inserter(solX.rep()), mth);
00067 solve(Ry, std::back_inserter(solY.rep()), mth);
00068
00069
00070 if ((solX.size() == 0) || (solY.size() == 0)) return res;
00071
00072
00073 if ((solX.size() == 1) && (solY.size() == 1)){
00074 *res++ = std::make_pair( make_vector(solX[0], solY[0]), static_cast<unsigned>(2) );
00075 return res;
00076 }
00077
00078
00079 if ((solX.size() == 1) && (solY.size() == 2)) {
00080 *res++ = std::make_pair( make_vector(solX[0], solY[0]), static_cast<unsigned>(1) );
00081 *res++ = std::make_pair( make_vector(solX[0], solY[1]), static_cast<unsigned>(1) );
00082 return res;
00083 }
00084
00085
00086 if ((solX.size() == 2) && (solY.size() == 1)) {
00087 *res++ = std::make_pair( make_vector(solX[0], solY[0]), static_cast<unsigned>(1) );
00088 *res++ = std::make_pair( make_vector(solX[1], solY[0]), static_cast<unsigned>(1) );
00089 return res;
00090 }
00091
00092
00093 FT dx = f2.xc() - f1.xc();
00094 FT dy = f2.yc() - f1.yc();
00095
00096
00097 bool slope = (sign(dx) * sign(dy) <= 0);
00098 if (slope) {
00099 *res++ = std::make_pair( make_vector(solX[0], solY[0]),static_cast<unsigned>(1) );
00100 *res++ = std::make_pair( make_vector(solX[1], solY[1]),static_cast<unsigned>(1) );
00101 } else {
00102 *res++ = std::make_pair( make_vector(solX[0], solY[1]),static_cast<unsigned>(1) );
00103 *res++ = std::make_pair( make_vector(solX[1], solY[0]),static_cast<unsigned>(1) );
00104 }
00105
00106 return res;
00107 }
00108
00109
00110
00111 template < typename SOLVER,
00112 typename OutputIterator >
00113 OutputIterator
00114 fast_solve(const typename SOLVER::MPoly_2_2& f1,
00115 const typename SOLVER::MPoly_2_2& f2,
00116 OutputIterator ii,
00117 const SOLVER& mth)
00118 {
00119 typedef typename SOLVER::Poly POLY;
00120 typedef typename SOLVER::RO_t RO_t;
00121 typedef typename SOLVER::FT FT;
00122
00123 POLY Rx = resultant_y<POLY>(f1, f2);
00124 POLY Ry = resultant_x<POLY>(f1, f2);
00125
00126
00127
00128 Seq<RO_t> solx = Solve(Rx, mth);
00129 Seq<RO_t> soly = Solve(Ry, mth);
00130
00131
00132 std::vector<int> x_multiplicity(solx.size());
00133 for (unsigned int i = 0; i < solx.size(); ++i) {
00134 x_multiplicity[i] = solx[i].multiplicity();
00135 }
00136
00137 std::vector<int> y_multiplicity(soly.size());
00138 for (unsigned int i = 0; i < soly.size(); ++i) {
00139 y_multiplicity[i] = soly[i].multiplicity();
00140 }
00141
00142
00143 typename Seq<RO_t>::const_iterator tx, ty;
00144 int i = 0;
00145 for (tx = solx.begin(); tx != solx.end(); ++tx, ++i) {
00146
00147 POLY xPoly(tx->poly());
00148 FT x_lisol = tx->left();
00149 std::vector<POLY> f1_leftStHa =
00150 compute_StHa_x_cx2y2(f1, xPoly, numerator(x_lisol), denominator(x_lisol));
00151
00152 FT x_risol = tx->right();
00153 std::vector<POLY> f1_rightStHa =
00154 compute_StHa_x_cx2y2(f1, xPoly, numerator(x_risol), denominator(x_risol));
00155
00156 std::vector<POLY> f2_leftStHa;
00157 std::vector<POLY> f2_rightStHa;
00158 bool second_computed = false;
00159
00160 int j = 0;
00161 for (ty = soly.begin(); ty != soly.end(); ++ty, ++j) {
00162
00163 if ((x_multiplicity[i] == 0) || (y_multiplicity[j] == 0)) continue;
00164
00165
00166 int sgn_a = opposite((tx->degree()-1-tx->which()) % 2 ? NEGATIVE : POSITIVE);
00167 int sgn_b = opposite(sgn_a);
00168
00169 int V1;
00170 if (tx->degree() == 1) {
00171 V1 = sign_at(f1_leftStHa[1], *ty);
00172 } else {
00173 int Va = sign_on_StHa(f1_leftStHa, sgn_a, *ty);
00174 int Vb = sign_on_StHa(f1_rightStHa, sgn_b, *ty);
00175 V1 = Va - Vb;
00176 }
00177
00178 if (V1) continue;
00179
00180 if (!second_computed) {
00181
00182 f2_leftStHa =
00183 compute_StHa_x_cx2y2(f2, xPoly, numerator(x_lisol), denominator(x_lisol));
00184
00185 f2_rightStHa =
00186 compute_StHa_x_cx2y2(f2, xPoly, numerator(x_risol), denominator(x_risol));
00187 second_computed = true;
00188 }
00189 int V2;
00190 if (tx->degree() == 1) {
00191 V2 = sign_at(f2_leftStHa[1], *ty);
00192 } else {
00193 int Va = sign_on_StHa(f2_leftStHa, sgn_a, *ty);
00194 int Vb = sign_on_StHa(f2_rightStHa, sgn_b, *ty);
00195 V2 = Va - Vb;
00196 }
00197
00198 if (V2) continue;
00199
00200
00201 *ii++ = make_vector(*tx, *ty);
00202 --x_multiplicity[i];
00203 --y_multiplicity[j];
00204 }
00205
00206 }
00207 return ii;
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 template < typename SOLVER,
00219 typename OutputIterator >
00220 OutputIterator
00221 trivial_solve(const typename SOLVER::MPoly_2_2& f1,
00222 const typename SOLVER::MPoly_2_2& f2,
00223 OutputIterator res,
00224 const SOLVER& mth)
00225 {
00226 std::cout << __FUNCTION__ << std::endl;
00227
00228 typedef typename SOLVER::Poly POLY;
00229 typedef typename SOLVER::RO_t RO_t;
00230
00231 POLY Rx = resultant_y<POLY>(f1, f2);
00232 POLY Ry = resultant_x<POLY>(f1, f2);
00233
00234 Seq<RO_t> Xsol = Solve(Rx, mth);
00235 Seq<RO_t> Ysol = Solve(Ry, mth);
00236
00237 Seq<int> Xmult(Xsol.size());
00238 for (int i = 0; i < Xmult.size(); ++i) Xmult[i] = Xsol[i].multiplicity();
00239
00240 Seq<int> Ymult(Ysol.size());
00241 for (int i = 0; i < Ymult.size(); ++i) Ymult[i] = Ysol[i].multiplicity();
00242
00243 for (int i = 0; i < Xsol.size(); ++i) {
00244 for (int j = 0; j < Ysol.size(); ++j) {
00245 if (Ymult[j] == 0) continue;
00246 if (Xmult[i] == 0) break;
00247 if ( (sign_at(f1, Xsol[i], Ysol[j]) == ZERO) &&
00248 (sign_at(f2, Xsol[i], Ysol[j]) == ZERO) ) {
00249 *res++ = make_vector( Xsol[i], Ysol[j] );
00250 --Xmult[i];
00251 --Ymult[j];
00252 }
00253 }
00254 }
00255 return res;
00256 }
00257
00258
00259
00260
00261
00262
00263 template < typename RO_t >
00264 int
00265 check_where(const RO_t& y, const RO_t& x,
00266 const typename RO_t::POLY& A,
00267 const typename RO_t::POLY& B)
00268 {
00269 typedef typename RO_t::RT RT;
00270 typedef typename RO_t::FT FT;
00271 typedef typename RO_t::POLY POLY;
00272
00273 POLY P;
00274 FT q;
00275
00276
00277 #if 0
00278
00279
00280 double xx = to_double(x);
00281 double apx = UPOLDAR::eval_horner(-B, xx) /
00282 UPOLDAR::eval_horner(A, xx);
00283
00284 if (y.interval().lower() > apx) return SMALLER;
00285 if (y.interval().upper() < apx) return LARGER;
00286 return EQUAL;
00287 #endif
00288
00289 q = y.left();
00290 P = -B * denominator(q) - A * numerator(q);
00291 if (sign_at(P, x) * sign_at(A, x) < 0) return SMALLER;
00292
00293 q = y.right();
00294 P = -B * denominator(q) - A * numerator(q);
00295 if (sign_at(P, x) * sign_at(A, x) > 0) return LARGER;
00296
00297 return EQUAL;
00298
00299 }
00300
00301
00302
00303 template < typename SOLVER,
00304 typename OutputIterator >
00305 OutputIterator
00306 solve(const typename SOLVER::MPoly_2_2& f1,
00307 const typename SOLVER::MPoly_2_2& f2,
00308 OutputIterator ii,
00309 const SOLVER& mth)
00310 {
00311 typedef typename SOLVER::RT RT;
00312 typedef typename SOLVER::FT FT;
00313
00314 typedef typename SOLVER::Poly POLY;
00315 typedef typename SOLVER::RO_t RO_t;
00316
00317 POLY Ax, Bx;
00318 POLY Rx;
00319 resultant_y(f1, f2, Ax, Bx, Rx);
00320
00321 POLY Ay, By;
00322 POLY Ry;
00323 resultant_x(f1, f2, Ay, By, Ry);
00324
00325
00326 std::vector<RO_t> solx;
00327 solve_small_degree(Rx, 1, std::back_inserter(solx), mth);
00328
00329 std::vector<RO_t> soly;
00330 solve_small_degree(Ry, 1, std::back_inserter(soly), mth);
00331
00332
00333 bool x_has_multiplicities = false;
00334 bool y_has_multiplicities = false;
00335
00336
00337 std::vector<int> x_multiplicity(solx.size());
00338 for (unsigned int i = 0; i < solx.size(); ++i) {
00339 x_multiplicity[i] = solx[i].multiplicity();
00340 if (x_multiplicity[i] > 1) x_has_multiplicities = true;
00341 }
00342
00343 std::vector<int> y_multiplicity(soly.size());
00344 for (unsigned int i = 0; i < soly.size(); ++i) {
00345 y_multiplicity[i] = soly[i].multiplicity();
00346 if (y_multiplicity[i] > 1) y_has_multiplicities = true;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 bool revert = false;
00363 bool solve_by_subres = false;
00364
00365 if ( (!x_has_multiplicities) && (!y_has_multiplicities) ) {
00366 solve_by_subres = true;
00367 }
00368
00369 POLY A, B, R;
00370 if (!revert) {
00371 A = Ax; B = Bx; R = Rx;
00372 } else {
00373 std::swap(solx, soly);
00374 A = Ay; B = By; R = Ry;
00375 }
00376
00377
00378 if (solve_by_subres) {
00379 for (typename std::vector<RO_t>::iterator xt = solx.begin(); xt != solx.end(); ++xt) {
00380 int start = 0;
00381 int end = soly.size() - 1;
00382
00383 while (start <= end) {
00384 int mid = static_cast<int>(std::ceil((end-start)/2.0));
00385 int pos = start + mid;
00386
00387 int result = check_where(soly[pos], *xt, A, B);
00388 if (result == EQUAL) {
00389 if (!revert) { *ii++ = make_vector(*xt, soly[pos]); }
00390 else { *ii++ = make_vector(soly[pos], *xt); }
00391 typename std::vector<RO_t>::iterator jt = soly.begin() + pos;
00392 soly.erase(jt);
00393 break;
00394 }
00395 if (result == SMALLER) {
00396 end = pos - 1;
00397 continue;
00398 }
00399
00400 start = pos + 1;
00401 }
00402 }
00403 return ii;
00404 }
00405
00406
00407
00408 typename Seq<RO_t>::const_iterator tx, ty;
00409 int i = 0;
00410 for (tx = solx.begin(); tx != solx.end(); ++tx, ++i) {
00411
00412 POLY xPoly(tx->poly());
00413 FT x_lisol = tx->left();
00414 std::vector<POLY> f1_leftStHa =
00415 compute_StHa_x_cx2y2(f1, xPoly, numerator(x_lisol), denominator(x_lisol));
00416
00417 FT x_risol = tx->right();
00418 std::vector<POLY> f1_rightStHa =
00419 compute_StHa_x_cx2y2(f1, xPoly, numerator(x_risol), denominator(x_risol));
00420
00421 std::vector<POLY> f2_leftStHa;
00422 std::vector<POLY> f2_rightStHa;
00423 bool second_computed = false;
00424
00425 int j = 0;
00426 for (ty = soly.begin(); ty != soly.end(); ++ty, ++j) {
00427 if ((x_multiplicity[i] == 0) || (y_multiplicity[j] == 0)) continue;
00428
00429 int sgn_a = opposite((tx->degree()-1-tx->which()) % 2 ? NEGATIVE : POSITIVE);
00430 int sgn_b = opposite(sgn_a);
00431 int V1;
00432 if (tx->degree() == 1) {
00433 V1 = sign_at(f1_leftStHa[1], *ty);
00434 } else {
00435 int Va = sign_on_StHa(f1_leftStHa, sgn_a, *ty);
00436 int Vb = sign_on_StHa(f1_rightStHa, sgn_b, *ty);
00437 V1 = Va - Vb;
00438 }
00439 if (V1) continue;
00440
00441 if (!second_computed) {
00442 f2_leftStHa =
00443 compute_StHa_x_cx2y2(f2, xPoly, numerator(x_lisol), denominator(x_lisol));
00444
00445 f2_rightStHa =
00446 compute_StHa_x_cx2y2(f2, xPoly, numerator(x_risol), denominator(x_risol));
00447 second_computed = true;
00448 }
00449 int V2;
00450 if (tx->degree() == 1) {
00451 V2 = sign_at(f2_leftStHa[1], *ty);
00452 } else {
00453 int Va = sign_on_StHa(f2_leftStHa, sgn_a, *ty);
00454 int Vb = sign_on_StHa(f2_rightStHa, sgn_b, *ty);
00455 V2 = Va - Vb;
00456 }
00457 if (V2) continue;
00458
00459
00460 *ii++ = make_vector(*tx, *ty);
00461 --x_multiplicity[i];
00462 --y_multiplicity[j];
00463 }
00464
00465 }
00466
00467
00468 return ii;
00469 }
00470
00471
00472
00473 template < typename SOLVER,
00474 typename OutputIterator >
00475 OutputIterator
00476 solve_in_range(const typename SOLVER::MPoly_2_2& f1,
00477 const typename SOLVER::MPoly_2_2& f2,
00478 OutputIterator ii,
00479 const typename SOLVER::RO_t& start,
00480 const typename SOLVER::RO_t& end,
00481 const SOLVER& mth)
00482 {
00483 typedef typename SOLVER::RT RT;
00484 typedef typename SOLVER::FT FT;
00485
00486 typedef typename SOLVER::Poly POLY;
00487 typedef typename SOLVER::RO_t RO_t;
00488
00489 POLY Ax, Bx;
00490 POLY Rx;
00491 resultant_y(f1, f2, Ax, Bx, Rx);
00492
00493 POLY Ay, By;
00494 POLY Ry;
00495 resultant_x(f1, f2, Ay, By, Ry);
00496
00497 Seq<RO_t> solx = Solve(Rx, mth);
00498 Seq<RO_t> soly = Solve(Ry, mth);
00499
00500 bool x_has_multiplicities = false;
00501 bool y_has_multiplicities = false;
00502
00503
00504 std::vector<int> x_multiplicity(solx.size());
00505 for (unsigned int i = 0; i < solx.size(); ++i) {
00506 x_multiplicity[i] = solx[i].multiplicity();
00507 if (x_multiplicity[i] > 1) x_has_multiplicities = true;
00508 }
00509
00510 std::vector<int> y_multiplicity(soly.size());
00511 for (unsigned int i = 0; i < soly.size(); ++i) {
00512 y_multiplicity[i] = soly[i].multiplicity();
00513 if (y_multiplicity[i] > 1) y_has_multiplicities = true;
00514 }
00515
00516 bool solve_by_subres = false;
00517
00518 if ( (!x_has_multiplicities) && (!y_has_multiplicities) ) {
00519 solve_by_subres = true;
00520 }
00521
00522 POLY A(Ax);
00523 POLY B(Bx);
00524 POLY R(Rx);
00525
00526
00527 if (solve_by_subres) {
00528 for (typename Seq<RO_t>::const_iterator xt = solx.begin(); xt != solx.end(); ++xt) {
00529 if ((*xt >= start) && (*xt <= end)) {
00530 int start = 0;
00531 int end = soly.size() - 1;
00532
00533 while (start <= end) {
00534 int mid = static_cast<int>(std::ceil((end-start)/2.0));
00535 int pos = start + mid;
00536
00537 int result = check_where(soly[pos], *xt, A, B);
00538 if (result == EQUAL) {
00539 *ii++ = make_vector(*xt, soly[pos]);
00540 break;
00541 }
00542 if (result == SMALLER) {
00543 end = pos - 1;
00544 continue;
00545 }
00546
00547 start = pos + 1;
00548 }
00549 }
00550 }
00551 return ii;
00552 }
00553
00554
00555
00556 typename Seq<RO_t>::const_iterator tx, ty;
00557 int i = 0;
00558 for (tx = solx.begin(); tx != solx.end(); ++tx, ++i) {
00559 if ((*tx >= start) && (*tx <= end)) {
00560
00561 POLY xPoly(tx->poly());
00562 FT x_lisol = tx->left();
00563 std::vector<POLY> f1_leftStHa =
00564 compute_StHa_x_cx2y2(f1, xPoly, numerator(x_lisol), denominator(x_lisol));
00565
00566 FT x_risol = tx->right();
00567 std::vector<POLY> f1_rightStHa =
00568 compute_StHa_x_cx2y2(f1, xPoly, numerator(x_risol), denominator(x_risol));
00569
00570 std::vector<POLY> f2_leftStHa;
00571 std::vector<POLY> f2_rightStHa;
00572 bool second_computed = false;
00573
00574 int j = 0;
00575 for (ty = soly.begin(); ty != soly.end(); ++ty, ++j) {
00576 if ((x_multiplicity[i] == 0) || (y_multiplicity[j] == 0)) continue;
00577
00578 int sgn_a = opposite((tx->degree()-1-tx->which()) % 2 ? NEGATIVE : POSITIVE);
00579 int sgn_b = opposite(sgn_a);
00580 int V1;
00581 if (tx->degree() == 1) {
00582 V1 = sign_at(f1_leftStHa[1], *ty);
00583 } else {
00584 int Va = sign_on_StHa(f1_leftStHa, sgn_a, *ty);
00585 int Vb = sign_on_StHa(f1_rightStHa, sgn_b, *ty);
00586 V1 = Va - Vb;
00587 }
00588 if (V1) continue;
00589
00590 if (!second_computed) {
00591 f2_leftStHa =
00592 compute_StHa_x_cx2y2(f2, xPoly, numerator(x_lisol), denominator(x_lisol));
00593
00594 f2_rightStHa =
00595 compute_StHa_x_cx2y2(f2, xPoly, numerator(x_risol), denominator(x_risol));
00596 second_computed = true;
00597 }
00598 int V2;
00599 if (tx->degree() == 1) {
00600 V2 = sign_at(f2_leftStHa[1], *ty);
00601 } else {
00602 int Va = sign_on_StHa(f2_leftStHa, sgn_a, *ty);
00603 int Vb = sign_on_StHa(f2_rightStHa, sgn_b, *ty);
00604 V2 = Va - Vb;
00605 }
00606 if (V2) continue;
00607
00608
00609 *ii++ = make_vector(*tx, *ty);
00610 --x_multiplicity[i];
00611 --y_multiplicity[j];
00612 }
00613
00614 }
00615 }
00616 return ii;
00617 }
00618
00619
00620
00630 template < typename SOLVER, typename O, typename R >
00631 Seq< VectDse< typename SOLVER::RO_t > >
00632 Solve_with_sign( const MPol<typename SOLVER::RT, O, R>& s1,
00633 const MPol<typename SOLVER::RT, O, R>& s2,
00634 const SOLVER& mth)
00635 {
00636
00637 assert((NbVar(s1) <= 2) && (NbVar(s2) <= 2));
00638
00639 typedef typename SOLVER::Poly Poly;
00640 typedef typename SOLVER::Poly_2 Poly_2;
00641 typedef typename SOLVER::RO_t RO_t;
00642
00643 Poly_2 f1x = let::convert_to_upoly_2(s1, POLY_wrt_Y);
00644 Poly_2 f2x = let::convert_to_upoly_2(s2, POLY_wrt_Y);
00645
00646 SturmSeq<Poly> stha(f1x, f2x, HABICHT());
00647 Poly Rx = stha[stha.size() - 1][0];
00648 Seq<RO_t> solx = Solve(Rx, SOLVER());
00649
00650
00651 Poly_2 f1y = let::convert_to_upoly_2(s1, POLY_wrt_X);
00652 Poly_2 f2y = let::convert_to_upoly_2(s2, POLY_wrt_X);
00653
00654 SturmSeq<Poly> sthb(f1y, f2y, HABICHT());
00655 Poly Ry = sthb[sthb.size() - 1][0];
00656 Seq< RO_t > soly = Solve(Ry, SOLVER());
00657
00658 #if 0
00659 std::cout << "Rx: " << Rx << std::endl;
00660 std::cout << "Ry: " << Ry << std::endl;
00661 for (int i = 0; i < solx.size(); ++i) {
00662 std::cout << to_double(solx[i]) << std::endl;
00663 }
00664 std::cout << "-------" << std::endl;
00665 for (int i = 0; i < soly.size(); ++i) {
00666 std::cout << to_double(soly[i]) << std::endl;
00667 }
00668 #endif
00669
00670 typedef typename Seq<RO_t>::const_iterator IT;
00671 std::vector< VectDse<RO_t> > sol;
00672 for (IT xt = solx.begin(); xt != solx.end(); ++xt) {
00673 for (IT yt = soly.begin(); yt != soly.end(); ++yt) {
00674 if ((sign_at(f1x, *xt, *yt) == ZERO) && (sign_at(f2x, *xt, *yt) == ZERO)) {
00675 sol.push_back( make_vector(*xt, *yt) );
00676 }
00677 }
00678 }
00679
00680 return sol;
00681 }
00682
00683
00684
00685
00695 template < typename SOLVER, typename O, typename R >
00696 Seq< std::pair< typename SOLVER::RO_t, typename SOLVER::RO_t > >
00697 Solve_with_subres( const MPol<typename SOLVER::RT, O, R>& F1,
00698 const MPol<typename SOLVER::RT, O, R>& F2,
00699 const SOLVER& mth)
00700 {
00701 assert((NbVar(F1) <= 2) && (NbVar(F2) <= 2));
00702
00703 typedef typename SOLVER::RT RT;
00704
00705 typedef MPol<RT, O, R> MPoly;
00706
00707 typedef typename SOLVER::Poly Poly;
00708 typedef typename SOLVER::Poly_2 Poly_2;
00709 typedef typename SOLVER::RO_t RO_t;
00710
00711 Poly_2 f1y = let::convert_to_upoly_2(F1, POLY_wrt_Y);
00712 Poly_2 f2y = let::convert_to_upoly_2(F2, POLY_wrt_Y);
00713
00714 Poly_2 f1x = let::convert_to_upoly_2(F1, POLY_wrt_X);
00715 Poly_2 f2x = let::convert_to_upoly_2(F2, POLY_wrt_X);
00716
00717 int dg_1 = UPOLDAR::degree( UPOLDAR::lcoeff(f1y) );
00718 int dg_2 = UPOLDAR::degree( UPOLDAR::lcoeff(f2y) );
00719 if ((dg_1 >= 1) && (dg_2 >= 1))
00720 {
00721 std::cout << "Linear transformation" << std::endl;
00722 Poly_2 h = construct_X_minus_aY(RT(1));
00723 Poly_2 tf1y = compose(f1y, h);
00724 Poly_2 tf2y = compose(f2y, h);
00725
00726
00727
00728
00729
00730
00731
00732 Poly_2 tf1x = interchange_variables(tf1y);
00733 Poly_2 tf2x = interchange_variables(tf2y);
00734
00735 std::swap(f1y, tf1y);
00736 std::swap(f2y, tf2y);
00737 std::swap(f1x, tf1x);
00738 std::swap(f2x, tf2x);
00739 }
00740 if ((dg_1 >= 1) && (dg_2 < 1)) {
00741 std::cout << "Do a swap" << std::endl;
00742 std::swap(f1y, f2y);
00743 std::swap(f1x, f2x);
00744 }
00745
00746
00747 SturmSeq<Poly> StHa_Y(f1y, f2y, HABICHT());
00748 Poly Rx = StHa_Y[StHa_Y.size() - 1][0];
00749
00750
00751
00752 SturmSeq<Poly> StHa_X(f1x, f2x, HABICHT());
00753 Poly Ry = StHa_X[StHa_X.size() - 1][0];
00754 Seq<RO_t> solY = Solve(Ry, SOLVER());
00755
00756 Poly Resultant = SquareFree(Rx);
00757
00758 Seq<Poly> stha_list = CoeffStHa< Seq<Poly> >(StHa_Y);
00759 Seq<Poly> decomposition_list;
00760 Poly Fi = Resultant;
00761 for (int i = 0; i < stha_list.size() -1 ; ++i) {
00762 std::cout << Fi << ", " << stha_list[stha_list.size()-i-2]
00763 << " gcd = " << PGcd(Fi, stha_list[stha_list.size()-i-2]) << std::endl;
00764 Poly Fin = PGcd(Fi, stha_list[stha_list.size()-i-2]);
00765 std::cout << " / = " << (Fi / Fin) << std::endl;
00766 decomposition_list.push_back(Fi / Fin);
00767 Fi = Fin;
00768 }
00769
00770 #if 1
00771 {
00772 std::cout << "Rx: " << Rx << std::endl;
00773 Seq< Poly > dec = SquareFreeFactorization(Rx);
00774 for (int i = 0; i < dec.size(); ++i) {
00775 std::cout << i << ": " << dec[i] << std::endl;
00776 }
00777 std::cout << "-----------------------------" << std::endl;
00778 }
00779 {
00780 std::cout << "Ry: " << Ry << std::endl;
00781 Seq< Poly > dec = SquareFreeFactorization(Ry);
00782 for (int i = 0; i < dec.size(); ++i) {
00783 std::cout << i << ": " << dec[i] << std::endl;
00784 }
00785 std::cout << "-----------------------------" << std::endl;
00786 std::cout << "Done resultants" << std::endl;
00787 }
00788
00789 std::cout << "psc: " << std::endl;
00790 for (int i = 0; i < stha_list.size(); ++i) {
00791 std::cout << i << ": " << stha_list[i] << std::endl;
00792 }
00793 std::cout << std::endl;
00794 std::cout << "decomp" << std::endl;
00795 for (int i = 0; i < decomposition_list.size(); ++i) {
00796 std::cout << i << ": " << decomposition_list[i] << std::endl;
00797 }
00798 std::cout << std::endl;
00799 #endif
00800
00801
00802 Seq< VectDse< RO_t > > solutions;
00803
00804
00805 for (int j = 0; j < decomposition_list.size(); ++j) {
00806 if (UPOLDAR::degree(decomposition_list[j]) < 1) continue;
00807
00808
00809
00810
00811 Seq<RO_t> solX = Solve(decomposition_list[j], SOLVER());
00812
00813
00814 Poly_2 tp = StHa_Y[ StHa_Y.size() - j - 2 ];
00815 if ((UPOLDAR::degree(tp) >= j) && (j < (StHa_Y.size() - 3))) {
00816
00817
00818
00819
00820
00821
00822
00823 Poly B = tp[j];
00824 Poly A = tp[j+1] * (j+1);
00825 for (int k = 0; k < solX.size(); ++k) {
00826 int start = 0;
00827 int end = solY.size() - 1;
00828 while (start <= end) {
00829 int mid = static_cast<int>(std::ceil((end-start)/2.0));
00830 int pos = start + mid;
00831
00832 int result = check_where(solY[pos], solX[k], A, B);
00833 if (result == EQUAL) {
00834 solutions.push_back(make_vector(solX[k], solY[pos]));
00835 std::cout << "solution\n";
00836 std::cout << to_double(solX[k]) << ", "
00837 << to_double(solY[pos])
00838 << " mu ="<< j+1 << std::endl;
00839 break;
00840 }
00841 if (result == SMALLER) {
00842 end = pos - 1;
00843 continue;
00844 }
00845
00846 start = pos + 1;
00847 }
00848 }
00849 } else {
00850 std::cout << "Degenerate case ?" << std::endl;
00851 }
00852
00853 }
00854 return solutions;
00855 }
00856
00857
00858
00859
00861
00862
00863
00864
00865
00866
00867
00868 template < typename SOLVER >
00869 int
00870 pos_wrt_point( std::pair< typename SOLVER::FT, int >& isol_point,
00871 const typename SOLVER::RO_t& r,
00872 const typename SOLVER::Poly& A,
00873 const typename SOLVER::Poly& B,
00874 const SOLVER& )
00875 {
00876 typedef typename SOLVER::RT RT;
00877 typedef typename SOLVER::FT FT;
00878 typedef typename SOLVER::Poly Poly;
00879 typedef typename SOLVER::RO_t RO_t;
00880
00881 if (isol_point.second != UNKNOWN) return isol_point.second;
00882
00883 int sgnA = sign_at(A, r);
00884
00885 FT q = isol_point.first;
00886 Poly P = B * denominator(q) + A * numerator(q);
00887
00888 if (sign_at(P, r) * sgnA > 0) isol_point.second = SMALLER;
00889 else isol_point.second = LARGER;
00890
00891 return isol_point.second;
00892 }
00893
00894
00895 template < typename SOLVER >
00896 int
00897 compute_y_in_generic_position( const Seq< typename SOLVER::FT >& IP,
00898 const typename SOLVER::RO_t& r,
00899 const typename SOLVER::Poly& A,
00900 const typename SOLVER::Poly& B,
00901 const SOLVER& )
00902 {
00903 typedef typename SOLVER::RT RT;
00904 typedef typename SOLVER::FT FT;
00905 typedef typename SOLVER::Poly Poly;
00906 typedef typename SOLVER::RO_t RO_t;
00907
00908 for (int i = 0; i < IP.size(); ++i) {
00909 std::cout << to_double(IP[i]) << " ";
00910 }
00911 std::cout << std::endl;
00912 double apx = - UPOLDAR::eval_horner(B, to_double(r))
00913 / UPOLDAR::eval_horner(A, to_double(r));
00914 std::cout << "(" << to_double(r) << ", " << apx << ")" << std::endl;
00915
00916
00917
00918
00919 Seq< std::pair<FT, int> > P(IP.size());
00920 for (int i = 0; i < IP.size(); ++i) {
00921 P[i] = make_vector( IP[i], UNKNOWN );
00922 }
00923 P[0].second = LARGER;
00924 P[P.size()-1].second = SMALLER;
00925
00926 int start = 0;
00927 int end = P.size() - 1;
00928 while (start <= end) {
00929 if ((end - start) == 1) {
00930 assert( (P[start].second == LARGER) && (P[end].second == SMALLER));
00931 return start;
00932 }
00933
00934 int pos = static_cast<int>( std::ceil((start+end)/2.0) );
00935 int result = pos_wrt_point(P[pos], r, A, B, SOLVER());
00936
00937 std::cout << "s, p, e : " << start << ", " << pos << ", " << end << std::endl;
00938 std::cout << "In " << to_double(IP[start]) << ", " << to_double(IP[end]) << std::endl;
00939 std::cout << "Testing point: " << to_double(P[pos].first)
00940 << " found " << result << std::endl;
00941 if (result == SMALLER) {
00942 end = pos;
00943 continue;
00944 }
00945 if (result == LARGER) {
00946 start = pos;
00947 continue;
00948 }
00949 }
00950 std::cout << "We must always find a solution" << std::endl;
00951 return -1;
00952 }
00953
00954
00955
00956
00957 template < typename SOLVER,
00958 typename OutputIterator >
00959 OutputIterator
00960 New_solve(const typename SOLVER::MPoly_2_2& f1,
00961 const typename SOLVER::MPoly_2_2& f2,
00962 OutputIterator res,
00963 const SOLVER& mth)
00964 {
00965 std::cout << __FUNCTION__ << std::endl;
00966
00967 typedef typename SOLVER::RT RT;
00968 typedef typename SOLVER::FT FT;
00969
00970 typedef typename SOLVER::Poly Poly;
00971 typedef typename SOLVER::RO_t RO_t;
00972
00973 Poly Ax, Bx;
00974 Poly Rx;
00975 resultant_y(f1, f2, Ax, Bx, Rx);
00976
00977 Poly Ay, By;
00978 Poly Ry;
00979 resultant_x(f1, f2, Ay, By, Ry);
00980
00981
00982 Seq<RO_t> Xsol = Solve(Rx, SOLVER());
00983 Seq<RO_t> Ysol = Solve(Ry, SOLVER());
00984
00985 if ((Xsol.size() == 0) || (Ysol.size() == 0)) return res;
00986
00987
00988 std::vector<int> Xmult( Xsol.size() );
00989 for (int i = 0; i < Xmult.size(); ++i) Xmult[i] = Xsol[i].multiplicity();
00990 std::vector<int> possible_x_roots = Xmult;
00991
00992
00993 std::vector<int> Ymult( Ysol.size() );
00994 for (int i = 0; i < Ymult.size(); ++i) Ymult[i] = Ysol[i].multiplicity();
00995 std::vector<int> possible_y_roots = Ymult;
00996
00997 unsigned sol_matrix[4][4] = { {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0} };
00998
00999 Seq<FT> Y_isol_points;
01000 compute_intermediate_points(Ysol, Y_isol_points);
01001
01002
01003
01004
01005
01006
01007
01008
01009 Poly A(Ax);
01010 Poly B(Bx);
01011 Poly R(Rx);
01012
01013 for (int i = 0; i < Xsol.size(); ++i) {
01014 if (Xsol[i].multiplicity() == 1) {
01015 std::cout << "We are in generic position" << std::endl;
01016 int j = compute_y_in_generic_position(Y_isol_points, Xsol[i], A, B, SOLVER());
01017 sol_matrix[i][j] = 1;
01018
01019 --possible_x_roots[i];
01020 --possible_y_roots[j];
01021 continue;
01022 }
01023
01024 if (Xsol[i].is_rational()) {
01025 std::cout << "Check with rational" << std::endl;
01026
01027 FT r = Xsol[i].left();
01028
01029 Poly sf1 = specialize_x<Poly>(f1, r);
01030 Poly sf2 = specialize_x<Poly>(f2, r);
01031
01032 for (int j = 0; ((j < Ysol.size()) && possible_x_roots[i]); ++j) {
01033 if (possible_y_roots[j]) {
01034 if ((sign_at(sf1, Ysol[j]) == ZERO) && (sign_at(sf2, Ysol[j]) == ZERO)) {
01035 --possible_x_roots[i];
01036 --possible_y_roots[j];
01037 sol_matrix[i][j] = 1;
01038 }
01039 }
01040 }
01041 continue;
01042 }
01043
01044 std::cout << "Check with sign_at" << std::endl;
01045 for (int j = 0; ((j < Ysol.size()) && possible_x_roots[i]); ++j) {
01046 if (possible_y_roots[j]) {
01047 if ( (sign_at(f1, Xsol[i], Ysol[j]) == ZERO) &&
01048 (sign_at(f2, Xsol[i], Ysol[j]) == ZERO) ) {
01049 --possible_x_roots[i];
01050 --possible_y_roots[j];
01051 sol_matrix[i][j] = 1;
01052 }
01053 }
01054 }
01055
01056 }
01057 for (int i = 0; i < Xsol.size(); ++i) {
01058 for (int j = 0; j < Ysol.size(); ++j) {
01059 if (sol_matrix[i][j] == 1)
01060 *res++ = make_vector( Xsol[i], Ysol[j] );
01061 }
01062 }
01063 return res;
01064 }
01065
01066
01067
01068
01069
01070 __ALGEBRAIC_END_NAMESPACE
01071
01072 #endif // SYNAPS_ARITHM_ALGEBRAIC_BSOLVER_H
01073