コード例 #1
0
ファイル: nearestpoint.cpp プロジェクト: mental/lib2geom
/*
 *  FindRoots :
 *	Given a 5th-degree equation in Bernstein-Bezier form, find
 *	all of the roots in the interval [0, 1].  Return the number
 *	of roots found.
 */
static int FindRoots(
    Geom::Point 	*w,			/* The control points		*/
    int 	degree,		/* The degree of the polynomial	*/
    double 	*t,			/* RETURN candidate t-values	*/
    int 	depth)		/* The depth of the recursion	*/
{  
    int 	i;
    Geom::Point 	Left[W_DEGREE+1],	/* New left and right 		*/
        Right[W_DEGREE+1];	/* control polygons		*/
    int 	left_count,		/* Solution count from		*/
        right_count;		/* children			*/
    double 	left_t[W_DEGREE+1],	/* Solutions from kids		*/
        right_t[W_DEGREE+1];

    switch (CrossingCount(w, degree)) {
    case 0 : {	/* No solutions here	*/
        return 0;	
        break;
    }
    case 1 : {	/* Unique solution	*/
        /* Stop recursion when the tree is deep enough	*/
        /* if deep enough, return 1 solution at midpoint 	*/
        if (depth >= MAXDEPTH) {
            t[0] = (w[0][Geom::X] + w[W_DEGREE][Geom::X]) / 2.0;
            return 1;
        }
        if (ControlPolygonFlatEnough(w, degree)) {
            t[0] = ComputeXIntercept(w, degree);
            return 1;
        }
        break;
    }
    }

    /* Otherwise, solve recursively after	*/
    /* subdividing control polygon		*/
    Bez(w, degree, 0.5, Left, Right);
    left_count  = FindRoots(Left,  degree, left_t, depth+1);
    right_count = FindRoots(Right, degree, right_t, depth+1);


    /* Gather solutions together	*/
    for (i = 0; i < left_count; i++) {
        t[i] = left_t[i];
    }
    for (i = 0; i < right_count; i++) {
        t[i+left_count] = right_t[i];
    }

    /* Send back total number of solutions	*/
    return (left_count+right_count);
}
コード例 #2
0
Maybe<Real> NewtonPolySolve::FindSmallestPositiveRoot(const RPolynomial& p, const Real /*lastSmallestPositive*/) {
	if (NumberOfSignChanges(p) == 0)
		return Maybe<Real>();

	const CPolynomial q(p);
	//{
	//	bool converged;
	//	RPolynomial t = RPolynomial::MakeT();
	//	Scalar x = NextRoot(q, Scalar(lastSmallestPositive), &converged);
	//	if (converged && IsReal(x) && x.real() > 0 && NumberOfSignChanges(p.EvaluateAt(t + x.real() + .1)) == 0)
	//		return x.real();

	//	/*if (converged && )
	//		return x;*/
	//}

	
	const ScalarList roots = FindRoots(q);
	Maybe<Real> result;
	for (int i = 0 ; i < (int)roots.size() ; i++) {
		if (IsReal(roots[i]) && roots[i].real() > 0) {
			if (result.IsValid()) {
				result = std::min(result.Get(), roots[i].real());
			} else {
				result = roots[i].real();
			}
		}
	}
	return result;
}
コード例 #3
0
ScalarList NewtonPolySolve::FindRoots(const CPolynomial& poly, const ScalarList& guessListIn) {
	
	if (poly.Degree() == 0) {
		if (poly[0] == Scalar(0))
			return ScalarList(1,0);
		else 
			throw Exception("No solution");
	}
		
	Scalar x(0);
	
	ScalarList guessList = guessListIn;

	if (!guessList.empty()) {
		x = guessList.back();
		guessList.pop_back();
	}
	
	bool converged;
	x = NextRoot(poly, x, &converged);
	
	ScalarList answers;
	if (poly.Degree() > 1)
		ScalarList answers = FindRoots(poly.RemoveRoot(x), guessList);

	answers.push_back(x);
	return answers;
}
コード例 #4
0
ファイル: nearestpoint.cpp プロジェクト: mental/lib2geom
/*
 *  NearestPointOnCurve :
 *  	Compute the parameter value of the point on a Bezier
 *		curve segment closest to some arbtitrary, user-input point.
 *		Return the point on the curve at that parameter value.
 *
 Geom::Point 	P;			The user-supplied point
 Geom::Point 	*V;			Control points of cubic Bezier
*/
double NearestPointOnCurve(Geom::Point P, Geom::Point *V)
{
    double 	t_candidate[W_DEGREE];	/* Possible roots		*/     

    /*  Convert problem to 5th-degree Bezier form	*/
    Geom::Point	*w = ConvertToBezierForm(P, V);
    
    /* Find all possible roots of 5th-degree equation */
    int n_solutions = FindRoots(w, W_DEGREE, t_candidate, 0);
    std::free((char *)w);
    
    /* Check distance to end of the curve, where t = 1 */
    double dist = SquaredLength(P - V[DEGREE]);
    double t = 1.0;

    /* Find distances for candidate points	*/
    for (int i = 0; i < n_solutions; i++) {
        Geom::Point p = Bez(V, DEGREE, t_candidate[i], NULL, NULL);
        double new_dist = SquaredLength(P - p);
        if (new_dist < dist) {
            dist = new_dist;
            t = t_candidate[i];
        }
    }

    /*  Return the parameter value t */
    return t;
}
コード例 #5
0
/*
 *  FindRoots :
 *	Given a 5th-degree equation in Bernstein-Bezier form, find
 *	all of the roots in the interval [0, 1].  Return the number
 *	of roots found.
 */
int Measurement::FindRoots(QPointF* w, int degree,double *t,int depth)
{
    int 	i;
    QPointF 	Left[W_DEGREE+1],	/* New left and right 		*/
            Right[W_DEGREE+1];	/* control polygons		*/
    int 	left_count,		/* Solution count from		*/
            right_count;		/* children			*/
    double 	left_t[W_DEGREE+1],	/* Solutions from kids		*/
            right_t[W_DEGREE+1];

    switch (CrossingCount(w, degree)) {
    case 0 : {	/* No solutions here	*/
        return 0;
    }
    case 1 : {	/* Unique solution	*/
        /* Stop recursion when the tree is deep enough	*/
        /* if deep enough, return 1 solution at midpoint 	*/
        if (depth >= MAXDEPTH) {
            t[0] = (w[0].rx() + w[W_DEGREE].rx()) / 2.0;
            return 1;
        }
        if (ControlPolygonFlatEnough(w, degree)) {
            t[0] = ComputeXIntercept(w, degree);
            return 1;
        }
        break;
    }
    }

    /* Otherwise, solve recursively after	*/
    /* subdividing control polygon		*/
    Bezier(w, degree, 0.5, Left, Right);
    left_count  = FindRoots(Left,  degree, left_t, depth+1);
    right_count = FindRoots(Right, degree, right_t, depth+1);


    /* Gather solutions together	*/
    for (i = 0; i < left_count; i++) {
        t[i] = left_t[i];
    }
    for (i = 0; i < right_count; i++) {
        t[i+left_count] = right_t[i];
    }

    /* Send back total number of solutions	*/
    return (left_count+right_count);
}
コード例 #6
0
ファイル: PAlgebra.cpp プロジェクト: Kverma517/HElib
void PAlgebraModDerived<type>::mapToFt(RX& w,
			     const RX& G,unsigned long t,const RX* rF1) const
{
  if (isDryRun()) {
    w = RX::zero();
    return;
  }
  long i = zMStar.indexOfRep(t);
  if (i < 0) { clear(w); return; }


  if (rF1==NULL) {               // Compute the representation "from scratch"
    // special case
    if (G == factors[i]) {
      SetX(w);
      return;
    }

    //special case
    if (deg(G) == 1) {
      w = -ConstTerm(G);
      return;
    }

    // the general case: currently only works when r == 1
    assert(r == 1);  

    REBak bak; bak.save();
    RE::init(factors[i]);        // work with the extension field GF_p[X]/Ft(X)
    REX Ga;
    conv(Ga, G);                 // G as a polynomial over the extension field

    vec_RE roots;
    FindRoots(roots, Ga);        // Find roots of G in this field
    RE* first = &roots[0];
    RE* last = first + roots.length();
    RE* smallest = min_element(first, last);
                                // make a canonical choice
    w=rep(*smallest);         
    return;
  }
  // if rF1 is set, then use it instead, setting w = rF1(X^t) mod Ft(X)
  RXModulus Ft(factors[i]);
  //  long tInv = InvMod(t,m);
  RX X2t = PowerXMod(t,Ft);    // X2t = X^t mod Ft
  w = CompMod(*rF1,X2t,Ft);      // w = F1(X2t) mod Ft

  /* Debugging sanity-check: G(w)=0 in the extension field (Z/2Z)[X]/Ft(X)
  RE::init(factors[i]);
  REX Ga;
  conv(Ga, G); // G as a polynomial over the extension field
  RE ra;
  conv(ra, w);         // w is an element in the extension field
  eval(ra,Ga,ra);  // ra = Ga(ra)
  if (!IsZero(ra)) {// check that Ga(w)=0 in this extension field
    cout << "rF1(X^t) mod Ft(X) != root of G mod Ft, t=" << t << endl;
    exit(0);    
  }*******************************************************************/
}
コード例 #7
0
ファイル: geomNearestBezier.cpp プロジェクト: wf225/MyCAD
// FindRoots :
//      Given a 5th-degree equation in Bernstein-Bezier form, find
//      all of the roots in the interval [0, 1].  Return the number
//      of roots found.
// Parameters :
//      w: The control points
//      degree: The degree of the polynomial
//      t: output candidate t-values
//      depth: The depth of the recursion
//
static int FindRoots(const Point2d* w, int degree, float* t, int depth)
{
    int i;
    Point2d Left[W_DEGREE+1];   // New left and right
    Point2d Right[W_DEGREE+1];  // control polygons
    int     left_count;         // Solution count from children
    int     right_count;
    float  left_t[W_DEGREE+1]; // Solutions from kids
    float  right_t[W_DEGREE+1];

    switch (CrossingCount(w, degree))
    {
    case 0 :    // No solutions here
        return 0;

    case 1 :    // Unique solution
        // Stop recursion when the tree is deep enough
        // if deep enough, return 1 solution at midpoint
        if (depth >= MAXDEPTH)
        {
            t[0] = (w[0].x + w[W_DEGREE].x) / 2;
            return 1;
        }
        if (ControlPolygonFlatEnough(w, degree)) {
            t[0] = ComputeXIntercept(w, degree);
            return 1;
        }
        break;
    }

    // Otherwise, solve recursively after subdividing control polygon
    BezierPoint(w, degree, 0.5f, Left, Right);
    left_count  = FindRoots(Left,  degree, left_t, depth+1);
    right_count = FindRoots(Right, degree, right_t, depth+1);

    // Gather solutions together
    for (i = 0; i < left_count; i++) {
        t[i] = left_t[i];
    }
    for (i = 0; i < right_count; i++) {
        t[i+left_count] = right_t[i];
    }

    // Send back total number of solutions
    return (left_count+right_count);
}
コード例 #8
0
double Measurement::NearestPointOnCurve(QPointF P, vector<QPointF> V)

{
    QPointF	*w;			/* Ctl pts for 5th-degree eqn	*/
    double 	t_candidate[W_DEGREE];	/* Possible roots		*/
    int 	n_solutions;		/* Number of roots found	*/
    double	t;			/* Parameter value of closest pt*/

    QPointF v_arr[4];

    for(int i=0; i<4; i++)
        v_arr[i]=V[i];


    /*  Convert problem to 5th-degree Bezier form	*/
    w = ConvertToBezierForm(P, v_arr);

    /* Find all possible roots of 5th-degree equation */
    n_solutions = FindRoots(w, W_DEGREE, t_candidate, 0);
    free((char *)w);

    /* Compare distances of P to all candidates, and to t=0, and t=1 */
    {
        double 	dist, new_dist;
        QPointF 	p;
        QPointF  v;
        int		i;


        /* Check distance to beginning of curve, where t = 0	*/
        dist = V2SquaredLength(V2Sub(&P, &v_arr[0], &v));
        t = 0.0;

        /* Find distances for candidate points	*/
        for (i = 0; i < n_solutions; i++) {
            p = Bezier(v_arr, DEGREE, t_candidate[i],
                       (QPointF *)NULL, (QPointF *)NULL);
            new_dist = V2SquaredLength(V2Sub(&P, &p, &v));
            if (new_dist < dist) {
                dist = new_dist;
                t = t_candidate[i];
            }
        }

        /* Finally, look at distance to end point, where t = 1.0 */
        new_dist = V2SquaredLength(V2Sub(&P, &V[DEGREE], &v));
        if (new_dist < dist) {
            dist = new_dist;
            t = 1.0;
        }
    }

    /*  Return the point on the curve at parameter value t */
//    printf("t : %4.12f\n", t);
    QPointF b=Bezier(v_arr, DEGREE, t, (QPointF *)NULL, (QPointF *)NULL);
    return V2DistanceBetween2Points(&P,&b);

}
コード例 #9
0
ファイル: ntlwrap.cpp プロジェクト: saraedum/sage-renamed
static void ZZ_pX_linear_roots(struct ZZ_p*** v, long* n, struct ZZ_pX* f)
{
    long i;
    vec_ZZ_p w;
    FindRoots(w, *f);
    *n = w.length();
    (*v) = (ZZ_p**) malloc(sizeof(ZZ_p*)*(*n));
    for (i=0; i<(*n); i++) {
        (*v)[i] = new ZZ_p(w[i]);
    }
}
コード例 #10
0
void EDFSplit(vec_ZZ_pEX& v, const ZZ_pEX& f, const ZZ_pEX& b, long d)
{
   ZZ_pEX a, g, h;
   ZZ_pEXModulus F;
   vec_ZZ_pE roots;
   
   build(F, f);
   long n = F.n;
   long r = n/d;
   random(a, n);
   TraceMap(g, a, d, F, b);
   MinPolyMod(h, g, F, r);
   FindRoots(roots, h);
   FindFactors(v, f, g, roots);
}
コード例 #11
0
ファイル: geomNearestBezier.cpp プロジェクト: wf225/MyCAD
// 计算一点到三次贝塞尔曲线段上的最近点
// Parameters :
//      pt: The user-supplied point
//      pts: Control points of cubic Bezier
//      nearpt: output the point on the curve at that parameter value
//
GEOMAPI void mgNearestOnBezier(
    const Point2d& pt, const Point2d* pts, Point2d& nearpt)
{
    Point2d w[W_DEGREE+1];          // Ctl pts for 5th-degree eqn
    float  t_candidate[W_DEGREE];  // Possible roots
    int     n_solutions;            // Number of roots found
    float  t;                      // Parameter value of closest pt

    // Convert problem to 5th-degree Bezier form
    ConvertToBezierForm(pt, pts, w);

    // Find all possible roots of 5th-degree equation
    n_solutions = FindRoots(w, W_DEGREE, t_candidate, 0);

    // Compare distances of pt to all candidates, and to t=0, and t=1
    {
        float  dist, new_dist;
        Point2d p;
        int     i;


        // Check distance to beginning of curve, where t = 0
        dist = (pt - pts[0]).lengthSqrd();
        t = 0.0;

        // Find distances for candidate points
        for (i = 0; i < n_solutions; i++) {
            p = BezierPoint(pts, DEGREE, t_candidate[i],
                (Point2d *)NULL, (Point2d *)NULL);
            new_dist = (pt - p).lengthSqrd();
            if (new_dist < dist) {
                dist = new_dist;
                t = t_candidate[i];
            }
        }

        // Finally, look at distance to end point, where t = 1.0
        new_dist = (pt - pts[DEGREE]).lengthSqrd();
        if (new_dist < dist) {
            dist = new_dist;
            t = 1.0;
        }
    }

    // Return the point on the curve at parameter value t
    // printf("t : %4.12f\n", t);
    nearpt = (BezierPoint(pts, DEGREE, t, (Point2d *)NULL, (Point2d *)NULL));
}
コード例 #12
0
void RootEDF(vec_ZZ_pEX& factors, const ZZ_pEX& f, long verbose)
{
   vec_ZZ_pE roots;
   double t;

   if (verbose) { cerr << "finding roots..."; t = GetTime(); }
   FindRoots(roots, f);
   if (verbose) { cerr << (GetTime()-t) << "\n"; }

   long r = roots.length();
   factors.SetLength(r);
   for (long j = 0; j < r; j++) {
      SetX(factors[j]);
      sub(factors[j], factors[j], roots[j]);
   }
}
コード例 #13
0
ファイル: Vector.cpp プロジェクト: morukutsu/theabyss
bool RaySphereIntersection(const NVector& C, float r, const NVector& O, const NVector& D, float tmin, float tmax, float& t)
{
	float t0, t1;

	NVector H = (O - C);
	float  a = (D * D);
	float  b = (H * D) * 2.0f;
	float  c = (H * H) - r*r;

	if (!FindRoots(a, b, c, t0, t1))
		return false;

	if (t0 > tmax || t1 < tmin)
		return false;

	t = t0;

	if (t0 < tmin)
		t = t1;

	return true;
}
コード例 #14
0
ScalarList NewtonPolySolve::FindRoots(const RPolynomial& poly, const ScalarList& guessList) {
	return FindRoots(CPolynomial(poly), guessList);
}
コード例 #15
0
void SFBerlekamp(vec_ZZ_pX& factors, const ZZ_pX& ff, long verbose)
{
   ZZ_pX f = ff;

   if (!IsOne(LeadCoeff(f)))
      Error("SFBerlekamp: bad args");

   if (deg(f) == 0) {
      factors.SetLength(0);
      return;
   }

   if (deg(f) == 1) {
      factors.SetLength(1);
      factors[0] = f;
      return;
   }

   double t;

   const ZZ& p = ZZ_p::modulus();

   long n = deg(f);

   ZZ_pXModulus F;

   build(F, f);

   ZZ_pX g, h;

   if (verbose) { cerr << "computing X^p..."; t = GetTime(); }
   PowerXMod(g, p, F);
   if (verbose) { cerr << (GetTime()-t) << "\n"; }

   vec_long D;
   long r;

   vec_ZZVec M;

   if (verbose) { cerr << "building matrix..."; t = GetTime(); }
   BuildMatrix(M, n, g, F, verbose);
   if (verbose) { cerr << (GetTime()-t) << "\n"; }

   if (verbose) { cerr << "diagonalizing..."; t = GetTime(); }
   NullSpace(r, D, M, verbose);
   if (verbose) { cerr << (GetTime()-t) << "\n"; }


   if (verbose) cerr << "number of factors = " << r << "\n";

   if (r == 1) {
      factors.SetLength(1);
      factors[0] = f;
      return;
   }

   if (verbose) { cerr << "factor extraction..."; t = GetTime(); }

   vec_ZZ_p roots;

   RandomBasisElt(g, D, M);
   MinPolyMod(h, g, F, r);
   if (deg(h) == r) M.kill();
   FindRoots(roots, h);
   FindFactors(factors, f, g, roots);

   ZZ_pX g1;
   vec_ZZ_pX S, S1;
   long i;

   while (factors.length() < r) {
      if (verbose) cerr << "+";
      RandomBasisElt(g, D, M);
      S.kill();
      for (i = 0; i < factors.length(); i++) {
         const ZZ_pX& f = factors[i];
         if (deg(f) == 1) {
            append(S, f);
            continue;
         }
         build(F, f);
         rem(g1, g, F);
         if (deg(g1) <= 0) {
            append(S, f);
            continue;
         }
         MinPolyMod(h, g1, F, min(deg(f), r-factors.length()+1));
         FindRoots(roots, h);
         S1.kill();
         FindFactors(S1, f, g1, roots);
         append(S, S1);
      }
      swap(factors, S);
   }

   if (verbose) { cerr << (GetTime()-t) << "\n"; }

   if (verbose) {
      cerr << "degrees:";
      long i;
      for (i = 0; i < factors.length(); i++)
         cerr << " " << deg(factors[i]);
      cerr << "\n";
   }
}
コード例 #16
0
ファイル: bch.cpp プロジェクト: hbhdytf/Fuzzy-extractor
///////////////////////////////////////////////////////////////////////////
// PURPOSE:
// Given syndrome ssWithoutEvens of BCH code with design distance d,
// finds sparse vector (with no more than
// (d-1)/2 ones) with that syndrome
// (note that syndrome as well sparse vector
// representation are defined at BCHSyndromeCompute above).
// 'answer' returns positions of ones in the resulting vector.
// These positions are elements of GF2E (i.e., we view the vector
// as a vector whose positions are indexed by elements of GF2E).
// Returns false if no such vector exists, true otherwise
// The input syndrome is assumed to not have even powers, i.e., 
// has (d-1)/2 elements, such as the syndrome computed by BCHSyndromeCompute.
// 
// ASSUMPTIONS:
// Let m=GF2E::degree() (i.e., the field is GF(2^m)).
// This algorithm assumes that d is odd, greater than 1, and less than 2^m.
// (else BCH codes don't make sense).
// Assumes input is of length (d-1)/2. 
//
// ALGORITHM USED:
// Implements BCH decoding based on Euclidean algorithm;
// For the explanation of the algorithm, see
// Syndrome Encoding and Decoding of BCH Codes in Sublinear Time
// (Excerpted from Fuzzy Extractors:
//    How to Generate Strong Keys from Biometrics and Other Noisy Data)
// by Yevgeniy Dodis, Rafail Ostrovsky, Leonid Reyzin and Adam Smith
// or Theorem 18.7 of Victor Shoup's "A Computational Introduction to 
// Number Theory and Algebra" (first edition, 2005), or
// pp. 170-173 of "Introduction to Coding Theory" by Jurgen Bierbrauer.
//
//
// RUNNING TIME:
// If the output has e elements (i.e., the length of the output vector
// is e; note that e <= (d-1)/2), then
// the running time is O(d^2 + e^2 + e^{\log_2 3} m) operations in GF(2^m),
// each of which takes time O(m^{\log_2 3}) in NTL.  Note that 
// \log_2 3 is approximately 1.585.
//
bool BCHSyndromeDecode(vec_GF2E &answer, const vec_GF2E & ssWithoutEvens, long d)
{
        long i;	
	vec_GF2E ss;


	// This takes O(d) operation in GF(2^m)
	InterpolateEvens(ss, ssWithoutEvens);

	GF2EX r1, r2, r3, v1, v2, v3,  q, temp;
	GF2EX *Rold, *Rcur, *Rnew, *Vold, *Vcur, *Vnew, *tempPointer;

        // Use pointers to avoid moving polynomials around
        // An assignment of polynomials requires copying the coefficient vector;
        // we will not assign polynomials, but will swap pointers instead
	Rold = &r1;
	Rcur = &r2;
	Rnew = &r3;

	Vold = &v1;
	Vcur = &v2;
	Vnew = &v3;


	SetCoeff(*Rold, d-1, 1); // Rold holds z^{d-1}

	// Rcur=S(z)/z where S is the syndrome poly, Rcur = \sum S_j z^{j-1}
        // Note that because we index arrays from 0, S_j is stored in ss[j-1]
	for (i=0; i<d-1; i++) 
	  SetCoeff (*Rcur, i, ss[i]);

	// Vold is already 0 -- no need to initialize
	// Initialize Vcur to 1
	SetCoeff(*Vcur, 0, 1); // Vcur = 1

	// Now run Euclid, but stop as soon as degree of Rcur drops below
	// (d-1)/2
	// This will take O(d^2) operations in GF(2^m)

	long t = (d-1)/2;



	while (deg(*Rcur) >=  t) {
	  // Rold = Rcur*q + Rnew
	  DivRem(q, *Rnew, *Rold, *Rcur);

	  // Vnew = Vold - qVcur)
	  mul(temp, q, *Vcur);
	  sub (*Vnew, *Vold, temp);


          // swap everything
	  tempPointer = Rold;	
	  Rold = Rcur;
	  Rcur = Rnew;
	  Rnew = tempPointer;

	  tempPointer = Vold;
	  Vold = Vcur;
	  Vcur = Vnew;
	  Vnew = tempPointer;
	}



	// At the end of the loop, sigma(z) is Vcur
	// (up to a constant factor, which doesn't matter,
	// since we care about roots of sigma).
	// The roots of sigma(z) are inverses of the points we
	// are interested in.  


	// We will check that 0 is not
        // a root of Vcur (else its inverse won't exist, and hence
	// the right polynomial doesn't exist).
	if (IsZero(ConstTerm(*Vcur)))
	  return false;

	// Need sigma to be monic for FindRoots
	MakeMonic(*Vcur);

        // check if sigma(z) has distinct roots if not, return false
	// this will take O(e^{\log_2 3} m) operations in GF(2^m),
	// where e is the degree of sigma(z)
	if (CheckIfDistinctRoots(*Vcur) == false)
	  return false;

        // find roots of sigma(z)
	// this will take O(e^2 + e^{\log_2 3} m) operations in GF(2^m),
	// where e is the degree of sigma(z)
	answer = FindRoots(*Vcur);

        // take inverses of roots of sigma(z)
	for (i = 0; i < answer.length(); ++i)
		answer[i] = inv(answer[i]);


	// It is now necessary to verify if the resulting vector
	// has the correct syndrome: it is possible that it does
	// not even though the polynomial sigma(z) factors
	// completely
	// This takes O(de) operations in GF(2^m)
	vec_GF2E test;
	BCHSyndromeCompute (test, answer, d);

	return (test==ssWithoutEvens);
}