// Slow convolution, multiplying two polynomials.
// Complexity: O(nu * nv).
void conv(const Poly& u, const Poly& v, Poly& w) {
    int nu = u.size(), nv = v.size();
    w.assign(nu + nv - 1, 0.0);
    for(int i = 0; i < nu; i++)
        for(int j = 0; j < nv; j++)
            w[i+j] += u[i] * v[j];
}
// Add b to a or Subs b from a.
void sub(Poly& a, const Poly& b) {
    if(a.size() < b.size())
        a.resize(b.size(), 0);
    for(int i = 0; i < b.size(); ++i)
        a[i] ^= b[i];
    tidy(a);
}
示例#3
0
Point centerMass( Poly &p ){
	Point c( 0 , 0 ) ;
	for( int i = 0; i < p.size(); i++ ) {
		c.x += p[i].x ;/// (double)p.size();
		c.y += p[i].y ;/// (double)p.size();
	}
	return c / (double) p.size();
}
示例#4
0
Poly naiveShiftRight(const Poly& p, int i) {
    Poly res(p.size() - i);
    for (unsigned j = i; j < p.size(); j++) {
        res.setBit(j - i, p.bit(j));
    }
    res.computeDegree();
    return res;
}
示例#5
0
Poly naiveShiftLeft(const Poly& p, int i) {
    Poly res(p.size() + i);
    for (unsigned j = 0; j < p.size(); j++) {
        res.setBit(i + j, p.bit(j));
    }
    res.computeDegree();
    return res;
}
// Slow convolution, multiplying two polynomials.
// Complexity: O(nu * nv).
void conv(const Poly& u, const Poly& v, Poly& w) {
    if(u.empty() || v.empty()) {w.clear(); return;}
    int nu = u.size(), nv = v.size();
    w.assign(nu + nv - 1, 0);
    for(int i = 0; i < nu; i++)
        for(int j = 0; j < nv; j++)
            w[i+j] ^= (u[i] & v[j]);
    tidy(w);
}
示例#7
0
vector<p2t::Point*> getP2Tpoints(const Poly &poly)
{
  vector<p2t::Point*> points(poly.size());
  for (uint i=0; i<poly.size(); i++)  {
    points[i] = new p2t::Point(poly.vertices[i].x(),
			       poly.vertices[i].y());
  }
  return points;
}
示例#8
0
文件: helper.cpp 项目: payload/gorge
void drawPoly(const Poly poly) {
	sf::VertexArray v(sf::Lines, 2);
	v[0].color = v[1].color = sf::Color::Red;
	for (size_t i = 0; i < poly.size(); i++) {
		v[0].position = poly[i];
		v[1].position = poly[(i + 1) % poly.size()];
		window.draw(v);
	}
}
示例#9
0
文件: poly.cpp 项目: luzpaz/scribus
Poly integral(Poly const & p) {
    Poly result;
    
    result.reserve(p.size()+1);
    result.push_back(0); // arbitrary const
    for(unsigned i = 0; i < p.size(); i++) {
        result.push_back(p[i]/(i+1));
    }
    return result;

}
示例#10
0
Poly operator*(Poly p, ll k)
{
  reduce(p);
  Poly res(p.size());
  for (auto i = 0; i < (int)p.size(); i++)
  {
    res[i] = (p[i] * k) % MOD;
  }
  reduce(res);
  return res;
}
示例#11
0
文件: poly.cpp 项目: luzpaz/scribus
Poly gcd(Poly const &a, Poly const &b, const double tol) {
	if(a.size() < b.size())
		return gcd(b, a);
	if(b.empty())
		return a;
	if(b.size() == 1)
		return a;
	Poly r;
	divide(a, b, r);
	return gcd(b, r);
}
示例#12
0
文件: poly.cpp 项目: luzpaz/scribus
Poly derivative(Poly const & p) {
    Poly result;
    
    if(p.size() <= 1)
        return Poly(0);
    result.reserve(p.size()-1);
    for(unsigned i = 1; i < p.size(); i++) {
        result.push_back(i*p[i]);
    }
    return result;
}
// Slow deconvolution, polynomial dividing.
// q returns the quotient, r returns the remainder.
void deconv(const Poly& u, const Poly& v, Poly& q, Poly& r) {
    int n = u.size() - 1;
    int nv = v.size() - 1;
    q.assign(n+1, 0.0);
    r = u;
    for(int k = n-nv; k >= 0; k--) {
        q[k] = r[nv+k] / v[nv];
        for(int j = nv+k-1; j >= k; j--)
            r[j] -= q[k] * v[j-k];
    }
    r.resize(nv);
}
// Slow deconvolution, polynomial dividing.
// q returns the quotient, r returns the remainder.
void deconv(const Poly& u, const Poly& v, Poly& q, Poly& r) {
    int n = u.size() - 1;
    int nv = v.size() - 1;
    q.assign(n + 1, 0);
    r = u;
    for(int k = n-nv; k >= 0; k--) {
        q[k] = r[nv+k];
        for(int j = nv+k-1; j >= k; j--)
            r[j] ^= (q[k] & v[j-k]);
    }
    r.resize(nv);
    tidy(q);
    tidy(r);
}
示例#15
0
std::vector<cdouble >
laguerre(Poly p, const double tol) {
    std::vector<cdouble > solutions;
    //std::cout << "p = " << p << " = ";
    while(p.size() > 1)
    {
        double x0 = 0;
        bool quad_root = false;
        cdouble sol = laguerre_internal_complex(p, x0, tol, quad_root);
        //if(abs(sol) > 1) break;
        Poly dvs;
        if(quad_root) {
            dvs.push_back((sol*conj(sol)).real());
            dvs.push_back(-(sol + conj(sol)).real());
            dvs.push_back(1.0);
            //std::cout << "(" <<  dvs << ")";
            //solutions.push_back(sol);
            //solutions.push_back(conj(sol));
        } else {
            //std::cout << sol << std::endl;
            dvs.push_back(-sol.real());
            dvs.push_back(1.0);
            solutions.push_back(sol);
            //std::cout << "(" <<  dvs << ")";
        }
        Poly r;
        p = divide(p, dvs, r);
        //std::cout << r << std::endl;
    }
    return solutions;
}
示例#16
0
void simplePolygon( Poly &p ){
	Point c = centerMass( p ) ;
	for( int i = 0; i < p.size(); i++){
		p[i].ang = atan2( c.x - p[i].x , c.y - p[i].y );
	}
	sort( p.begin(), p.end() );
}
示例#17
0
vector<Poly> triangulate( const Poly &p ){
	vector<Poly> res;
	int n = p.size();
	vector<int> l, r;
	for( int i = 0; i < n; i++){
		l.push_back( ( i - 1 + n) % n );
		r.push_back( ( i + 1) % n );
	}
	int i = n - 1, cagao = 0;
	while( res.size() < n - 2 ){
		if ( cagao >= n ) return vector<Poly>();
		i = r[i];
		Poly tmp;
		tmp.push_back( p[l[i]] );
		tmp.push_back( p[i] );
		tmp.push_back( p[r[i]] );

		if ( can( tmp, p , l[i], i , r[i] ) ){
			res.push_back( tmp );
			l[ r[i] ] = l[i];
			r[ l[i] ] = r[i];
			cagao = 0;
		}else cagao++;
	}
	return res;
}
示例#18
0
// debe ser antihorario
vector<Poly> triangulate( const Poly &p ){
	vector<Poly> res;
	int n = p.size();
	vector<int> l, r;
	for( int i = 0; i < n; i++){
		l.push_back( ( i - 1 + n) % n );
		r.push_back( ( i + 1) % n ); // crea una lista doblemente enlazada
	}
	int i = n - 1, cagao = 0;
	while( res.size() < n - 2 ){
		if ( cagao >= n ) return vector<Poly>();
		i = r[i]; // avanza tipo un i++
		Poly tmp; 
		tmp.push_back( p[l[i]] );
		tmp.push_back( p[i] );
		tmp.push_back( p[r[i]] ); // crea un triangulo

		if ( can( tmp, p , l[i], i , r[i] ) ){ // checa si sirve
			res.push_back( tmp ); // guardamos la solucion
			l[ r[i] ] = l[i];
			r[ l[i] ] = r[i]; // con estas dos operaciones en O(1) borramos el punto del "medio" del triangulo
			cagao = 0; // no fallo
		}else cagao++; // se fue al carajo
	}
	return res;
}
示例#19
0
Poly divide(Poly const &a, Poly const &b, Poly &r) {
    Poly c;
    r = a; // remainder
    assert(b.size() > 0);
    
    const unsigned k = a.degree();
    const unsigned l = b.degree();
    c.resize(k, 0.);
    
    for(unsigned i = k; i >= l; i--) {
        assert(i >= 0);
        double ci = r.back()/b.back();
        c[i-l] += ci;
        Poly bb = ci*b;
        //std::cout << ci <<"*(" << b.shifted(i-l) << ") = " 
        //          << bb.shifted(i-l) << "     r= " << r << std::endl;
        r -= bb.shifted(i-l);
        r.pop_back();
    }
    //std::cout << "r= " << r << std::endl;
    r.normalize();
    c.normalize();
    
    return c;
}
i64 Count(int L, int P, Poly &fab)
{
    i64 r = 0;
    for(int i=0; i<fab.size(); i++)
        r += gpow[i % (P-1)] < L ? fab[i] : 0;
    return r;
}
void put(const Poly& p) {
    int N = p.size() - 1;    
    cout << N;
    for(int i = N; i >= 0; --i)
        cout << ' ' << p[i];
    puts("");
}
示例#22
0
// nearest connection point indices of this and other poly
// if poly is not closed, only test first and last point
void Poly::nearestIndices(const Poly &p2, int &thisindex, int &otherindex) const
{
  double mindist = INFTY;
  for (uint i = 0; i < size(); i++) {
    if (!closed && i != 0 && i != size()-1) continue;
    for (uint j = 0; j < p2.size(); j++) {
      if (!p2.closed && j != 0 && j != p2.size()-1) continue;
      double d = vertices[i].squared_distance(p2.vertices[j]);
      if (d < mindist) {
	mindist = d;
	thisindex = i;
	otherindex= j;
      }
    }
  }
}
示例#23
0
cdouble laguerre_internal_complex(Poly const & p,
                                  double x0,
                                  double tol,
                                  bool & quad_root) {
    cdouble a = 2*tol;
    cdouble xk = x0;
    double n = p.degree();
    quad_root = false;
    const unsigned shuffle_rate = 10;
//    static double shuffle[] = {0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 1.0};
    unsigned shuffle_counter = 0;
    while(std::norm(a) > (tol*tol)) {
        //std::cout << "xk = " << xk << std::endl;
        cdouble b = p.back();
        cdouble d = 0, f = 0;
        double err = abs(b);
        double abx = abs(xk);
        for(int j = p.size()-2; j >= 0; j--) {
            f = xk*f + d;
            d = xk*d + b;
            b = xk*b + p[j];
            err = abs(b) + abx*err;
        }

        err *= 1e-7; // magic epsilon for convergence, should be computed from tol

        cdouble px = b;
        if(abs(b) < err)
            return xk;
        //if(std::norm(px) < tol*tol)
        //    return xk;
        cdouble G = d / px;
        cdouble H = G*G - f / px;

        //std::cout << "G = " << G << "H = " << H;
        cdouble radicand = (n - 1)*(n*H-G*G);
        //assert(radicand.real() > 0);
        if(radicand.real() < 0)
            quad_root = true;
        //std::cout << "radicand = " << radicand << std::endl;
        if(G.real() < 0) // here we try to maximise the denominator avoiding cancellation
            a = - sqrt(radicand);
        else
            a = sqrt(radicand);
        //std::cout << "a = " << a << std::endl;
        a = n / (a + G);
        //std::cout << "a = " << a << std::endl;
        if(shuffle_counter % shuffle_rate == 0)
		{
			//a *= shuffle[shuffle_counter / shuffle_rate];
		}
        xk -= a;
        shuffle_counter++;
        if(shuffle_counter >= 90)
            break;
    }
    //std::cout << "xk = " << xk << std::endl;
    return xk;
}
示例#24
0
Poly operator%(Poly p, Poly q)
{
  reduce(p);
  reduce(q);
  if (p.size() < q.size())
  {
    return p;
  }
  if (!is_monic(q))
  {
    return p % monic(q);
  }
  Poly s_q = shift(q, p.size() - q.size());
  Poly res = (p - p.back() * s_q);
  reduce(res);
  return res % q;
}
示例#25
0
double area( Poly &p ){
	double res = 0.0;
	int n = p.size();
	for( int i = 0; i < n; i++){
		res += p[ i ] % p[ ( i + 1 ) % n ];
	}
	return fabs(res / 2.0 );
}
示例#26
0
// triangular un poligono en O(2*n^2) devuelve un vector de triangulos
bool can( const Poly &t, const  Poly &p, int i , int j , int k ){
	if(ccw(t[0], t[1], t[2]) <= 0) return false;
	for(int l = 0; l < p.size(); l++){
		if(l != i && l != j && l != k)
			if( inTriang(t, p[l]))	return false;
	}
	return true;
}
示例#27
0
// triangular un poligono en O(2*n^2) devuelve un vector de triangulos
bool can( const Poly &t, const  Poly &p, int i , int j , int k ){
	if(ccw(t[0], t[1], t[2]) <= 0) return false; // si esta tipo para afuera cago ps
	for(int l = 0; l < p.size(); l++){ // revisa que ningun punto este dentro del triangulo que formamos
		if(l != i && l != j && l != k)
			if( inTriang(t, p[l]))	return false;
	}
	return true;
}
示例#28
0
文件: poly.cpp 项目: luzpaz/scribus
Poly compose(Poly const & a, Poly const & b) {
    Poly result;
    
    for(unsigned i = a.size(); i > 0; i--) {
        result = Poly(a[i-1]) + result * b;
    }
    return result;
    
}
示例#29
0
Poly operator+(Poly p, Poly q)
{
  reduce(p);
  reduce(q);
  if (p.size() < q.size())
  {
    return q + p;
  }
  else
  {
    for (auto i = 0; i < (int)q.size(); i++)
    {
      p[i] += q[i];
      p[i] %= MOD;
    }
  }
  reduce(p);
  return p;
}
示例#30
0
Poly operator*(Poly p, Poly q)
{
  reduce(p);
  reduce(q);
  Poly res(p.size() + q.size() - 1, 0);
  for (auto i = 0; i < (int)res.size(); i++)
  {
    for (auto j = 0; j <= i; j++)
    {
      if (j < (int)p.size() && i - j < (int)q.size())
      {
        res[i] += (p[j] * q[i - j]) % MOD;
        res[i] %= MOD;
      }
    }
  }
  reduce(res);
  return res;
}