int LUfactor(Matrix A, int *indexarray) { int dim = A->dim, i, j, k, i_max, k_max; Vector scale; double mx, tmp; scale = new_vector(dim); for (i = 0; i < dim; i++) indexarray[i] = i; for (i = 0; i < dim; i++) { mx = 0.; for (j = 0; j < dim; j++) { tmp = fabs(M_VAL(A, i, j)); if (mx < tmp) mx = tmp; } scale->ve[i] = mx; } k_max = dim - 1; for (k = 0; k < k_max; k++) { mx = 0.; i_max = -1; for (i = k; i < dim; i++) { if (fabs(scale->ve[i]) >= Tiny * fabs(M_VAL(A, i, k))) { tmp = fabs(M_VAL(A, i, k)) / scale->ve[i]; if (mx < tmp) { mx = tmp; i_max = i; } } } if (i_max == -1) { M_VAL(A, k, k) = 0.; continue; } if (i_max != k) { SWAPI(indexarray[i_max], indexarray[k]); for (j = 0; j < dim; j++) SWAPD(M_VAL(A, i_max, j), M_VAL(A, k, j)); } for (i = k + 1; i < dim; i++) { tmp = M_VAL(A, i, k) = M_VAL(A, i, k) / M_VAL(A, k, k); for (j = k + 1; j < dim; j++) M_VAL(A, i, j) -= tmp * M_VAL(A, k, j); } } return 0; }
static double triang_area(double rx0, double ry0, double rx1, double ry1, double tx0, double ty0, double tx1, double ty1, int tt) { /* rx0,ry0,rx1,ry1: rectangle boundaries */ /* tx0,ty0,tx1,ty1: triangle boundaries */ /* tt: triangle type */ double a,b,c,d; double lx0,ly0,lx1,ly1; /* Convert everything to a NW triangle */ if (tt & STH) { double t; SWAPI(ry0,ry1); SWAPI(ty0,ty1); } if (tt & EST) { double t; SWAPI(rx0,rx1); SWAPI(tx0,tx1); } /* Compute overlapping box */ if (tx0 > rx0) rx0 = tx0; if (ty0 > ry0) ry0 = ty0; if (tx1 < rx1) rx1 = tx1; if (ty1 < ry1) ry1 = ty1; if (rx1 <= rx0 || ry1 <= ry0) return 0.0; /* Need to compute diagonal line intersection with the box */ /* First compute co-efficients to formulas x = a + by and y = c + dx */ b = (tx1 - tx0)/(ty1 - ty0); a = tx0 - b * ty0; d = (ty1 - ty0)/(tx1 - tx0); c = ty0 - d * tx0; /* compute top or right intersection */ tt = 0; ly1 = ry1; lx1 = a + b * ly1; if (lx1 <= rx0) return (rx1 - rx0) * (ry1 - ry0); else if (lx1 > rx1) { /* could be right hand side */ lx1 = rx1; ly1 = c + d * lx1; if (ly1 <= ry0) return (rx1 - rx0) * (ry1 - ry0); tt = 1; /* right hand side intersection */ } /* compute left or bottom intersection */ lx0 = rx0; ly0 = c + d * lx0; if (ly0 >= ry1) return (rx1 - rx0) * (ry1 - ry0); else if (ly0 < ry0) { /* could be right hand side */ ly0 = ry0; lx0 = a + b * ly0; if (lx0 >= rx1) return (rx1 - rx0) * (ry1 - ry0); tt |= 2; /* bottom intersection */ } if (tt == 0) { /* top and left intersection */ /* rectangle minus triangle */ return ((rx1 - rx0) * (ry1 - ry0)) - (0.5 * (lx1 - rx0) * (ry1 - ly0)); } else if (tt == 1) { /* right and left intersection */ return ((rx1 - rx0) * (ly0 - ry0)) + (0.5 * (rx1 - rx0) * (ly1 - ly0)); } else if (tt == 2) { /* top and bottom intersection */ return ((rx1 - lx1) * (ry1 - ry0)) + (0.5 * (lx1 - lx0) * (ry1 - ry0)); } else { /* tt == 3 */ /* right and bottom intersection */ /* triangle */ return (0.5 * (rx1 - lx0) * (ly1 - ry0)); } }
int LLLoperations::doLLL(MutableMatrix *A, MutableMatrix *Achange, MutableMatrix *LLLstate, int nsteps) { int n = A->n_cols(); if (n == 0) return COMP_DONE; // Extract the state from LLLstate: int k, kmax; ring_elem a, alphaTop, alphaBottom; buffer o; if (LLLstate->get_entry(0,n,a)) k = globalZZ->coerce_to_int(a); else k = 0; if (LLLstate->get_entry(0,n+1,a)) kmax = globalZZ->coerce_to_int(a); else kmax = 0; LLLstate->get_entry(0,n+2,alphaTop); // Don't free alphaTop! LLLstate->get_entry(0,n+3,alphaBottom); while (k < n && nsteps != 0 && !system_interrupted()) { if (M2_gbTrace >= 1) { o.reset(); o << "."; if (M2_gbTrace >= 2) o << k; if (nsteps % 20 == 0) o << newline; emit(o.str()); } nsteps--; if (k > kmax) { if (M2_gbTrace == 1) { o.reset(); o << "." << k; if (nsteps % 20 == 0) o << newline; emit(o.str()); } kmax = k; for (int j=0; j<=k; j++) { ring_elem u; A->dot_product(k,j,u); for (int i=0; i<=j-1; i++) { // u = (D#i * u - lambda#(k,i) * lambda#(j,i)) // D#(i-1) ring_elem Di, mki, mji, Di1; LLLstate->get_entry(i,i,Di); globalZZ->mult_to(u, Di); if (LLLstate->get_entry(i,k,mki) && LLLstate->get_entry(i,j,mji)) { ring_elem t1 = globalZZ->mult(mki,mji); globalZZ->subtract_to(u,t1); } if (i > 0) { LLLstate->get_entry(i-1,i-1,Di1); // Cannot be zero!! ring_elem t1 = globalZZ->divide(u,Di1); globalZZ->remove(u); u = t1; } } // At this point we have our element: LLLstate->set_entry(j,k,u); if (j == k && globalZZ->is_zero(u)) { ERROR("LLL vectors not independent"); return COMP_ERROR; } } } // end of the k>kmax initialization REDI(k,k-1,A,Achange,LLLstate); if (Lovasz(LLLstate,k,alphaTop,alphaBottom)) { SWAPI(k,kmax,A,Achange,LLLstate); k--; if (k == 0) k = 1; } else { for (int ell=k-2; ell>=0; ell--) REDI(k,ell,A,Achange,LLLstate); k++; } } // Before returning, reset k,kmax: LLLstate->set_entry(0,n,globalZZ->from_int(k)); LLLstate->set_entry(0,n+1,globalZZ->from_int(kmax)); if (k >= n) return COMP_DONE; if (nsteps == 0) return COMP_DONE_STEPS; return COMP_INTERRUPTED; }