Polynomial Legendre(unsigned i) { if(i==0) return Polynomial({1.0f}); else if(i==1) return Polynomial({0.0f, 1.0f}); else return (Legendre(i-1)*Polynomial({0.0f, 2.0f*(i-1)+1.0f})-Legendre(i-2)*float(i-1))/float(i); }
void GLL::LagrangeDerivativeMatrix(basics::Matrix& A, const basics::Vector& grid) { assert( A.rows() == A.cols() && A.rows() == grid.length()); int N=grid.length(); for( int i=0;i<N;++i ) for( int j=0;j<N;++j ) { if( i == j ) A[j][i] = 0; else A[j][i] = Legendre(grid[i],N-1)/(Legendre(grid[j],N-1)*(grid[i]-grid[j])); } A[0][0] = -N*(N-1)/4.f; A[N-1][N-1] = N*(N-1)/4.f; }
void eval_legendre(Expr *expr) { expr->l->l->fn(expr->l->l); expr->l->r->fn(expr->l->r); expr->r->fn(expr->r); expr->v.x = Legendre((int)expr->l->l->v.x, (int)expr->l->r->v.x, expr->r->v.x); }
void GLL::GaussLobattoLegendreWeights(basics::Vector& weight, const basics::Vector& grid) { assert( grid.length() == weight.length() ); int N = grid.length(); for( int i=0;i<N;++i ) { Real L=Legendre(grid[i],N-1); weight[i] = 2.f/(((Real)N-1)*N*L*L); } }
void GLL::GaussLobattoLegendreGrid(basics::Vector& grid) { #define TOLERANCE 1.e-15f grid[0] = -1.f; grid[grid.length()-1] = 1.f; // Lobatto if( grid.length() == 2 ) return; basics::Vector GLgrid("Gauss Legendre Grid",grid.length()-1,false); GaussLegendreGrid(GLgrid); for( int i=1;i<grid.length()-1;i++ ) { grid[i] = (GLgrid[i-1]+GLgrid[i])/2.f; Real old = 0.f; while( fabs(old-grid[i]) > TOLERANCE ) { old = grid[i]; Real L = Legendre(old,grid.length()-1); Real Ld = LegendreDerivative(old,grid.length()-1); grid[i] += (1.f-old*old)*Ld/(((Real)grid.length()-1.f)*(Real)grid.length()*L); } } }
void ShLegendre::Calc(int n_max, double arg, double arg_2) { if (_n != n_max || _arg != arg) { Legendre.resize((n_max+1)*(n_max+1)); Legendre.setZero(); Legendre(0) = 1; // P_0^0 // computes the legendre functions P_n^m(arg) for m=n // from P_0^0 // Zotter Diss page 19 for (int n=1; n <= n_max; n++) { // P_n^m with m=n //correct!! Legendre((n+1)*(n+1)-1) = -(2*n-1) * Legendre(n*n-1) * arg_2; // P_n^m with m=n-1 Legendre((n+1)*(n+1)-2) = (2*n-1) * arg * Legendre(n*n-1); } // rest P_n^m with 3<=n<=n_max and 0 <= m <= n-2 for (int n=2; n <= n_max; n++) { for (int m=0; m <= n-2; m++) { if (m+2 <= n) { Legendre(n*(n+1)+m) = ((2*n-1)*arg*Legendre((n)*(n-1)+m)-(n+m-1)*Legendre((n-2)*(n-1)+m))/(n-m); } else { Legendre(n*(n+1)+m) = ((2*n-1)*arg*Legendre((n)*(n-1)+m))/(n-m); } } } // mirror coefficients for m<0 for (int n=1; n <= n_max; n++) { int n0 = n*(n+1); // index of m=0 coefficients for (int m=1; m <= n; m++) { Legendre(n0-m) = Legendre(n0+m); } } // std::cout << "Legendre vector size: " << Legendre.size() << std::endl << "Vector: " << std::endl << Legendre << std::endl; _arg = arg; _n = n_max; } }
// {{{ linear_algebra() void linear_algebra( GNFS::Polynomial &polynomial, GNFS::Target &target, FactorBase &fb, Matrix &matrix, const std::vector<int> &av, const std::vector<int> &bv) { NTL::ZZ aZ; NTL::ZZ bZ; NTL::ZZ pZ; NTL::ZZ valZ; NTL::ZZ numZ; int i; int j; int k; int u = polynomial.d*target.t; // Initialize sM for(j = 0; j <= matrix.sM.NumCols()-1; j++) { // Initialize row for(k = 0; k < matrix.sM.NumCols()-1; k++) matrix.sM[k][j] = 0; // Set the first column aZ = av[j]; bZ = bv[j]; valZ = aZ + bZ * polynomial.m; if(valZ < 0) { valZ *= -1; matrix.sM[0][j] = 1; } // Set a RFB row i = 0; while(i < target.t && valZ != 1) { pZ = fb.RFB[i]; if(valZ % pZ == 0) { if(matrix.sM[1+i][j]==0) matrix.sM[1+i][j]=1; else matrix.sM[1+i][j]=0; valZ = valZ / pZ; } else i++; } // Set a AFB row valZ = algebraic_norm(polynomial, av[j], bv[j]); if(valZ < 0) valZ *= -1; i = 0; while(i<u && valZ!=1) { pZ = fb.AFB[i]; if(valZ % pZ == 0) { numZ = fb.AFBr[i]; //while((aZ + bZ * numZ) % pZ != 0 && i<target.t) // TODO while((aZ + bZ * numZ) % pZ != 0) // TODO { pZ = fb.AFB[++i]; numZ = fb.AFBr[i]; } if(matrix.sM[1+target.t+i][j]==0) matrix.sM[1+target.t+i][j]=1; else matrix.sM[1+target.t+i][j]=0; valZ = valZ / pZ; } else i++; } // Set a QCB row for(i=0; i<target.digits; i++) { numZ = fb.QCB[i]; valZ = fb.QCBs[i]; valZ = aZ + bZ * valZ; if(Legendre(valZ, numZ) != 1) { matrix.sM[1+target.t+u+i][j]=1; } } } std::cout << "\tSize: " << matrix.sM.NumRows() << "x" << matrix.sM.NumCols() << std::endl; gaussian_elimination(matrix.sM); matrix.sfreeCols = get_freecols(matrix.sM); }