Exemplo n.º 1
0
 interval interval_relation_plugin::meet(interval const& src1, interval const& src2, bool& isempty) {
     isempty = false;
     if (is_empty(0, src1) || is_infinite(src2)) {
         return src1;
     }
     if (is_empty(0, src2) || is_infinite(src1)) {
         return src2;
     }
     bool l_open = src1.is_lower_open();
     bool r_open = src1.is_upper_open();
     ext_numeral low = src1.inf();
     ext_numeral high = src1.sup();
     if (src2.inf() > low || (src2.inf() == low && !l_open)) {
         low = src2.inf();
         l_open = src2.is_lower_open();
     }
     if (src2.sup() < high || (src2.sup() == high && !r_open)) {
         high = src2.sup();
         r_open = src2.is_upper_open();
     }
     if (low > high || (low == high && (l_open || r_open))) {
         isempty = true;
         return interval(dep());
     }
     else {
         return interval(dep(), low, l_open, nullptr, high, r_open, nullptr);
     }
 }
Exemplo n.º 2
0
inline int floating_point_decimals(T t)
{
    BOOST_STATIC_ASSERT(boost::is_float<T>::value);
#if defined LMI_MSVCRT
    // COMPILER !! This C runtime not only writes infinity as "1.#INF"
    // instead of "inf" but also "respects" the precision specifier
    // when doing so, truncating it to "1." if this function were to
    // return zero.
    if(is_infinite(t))
        {
        return 4;
        }
#endif // defined LMI_MSVCRT
    // Avoid taking the logarithm of zero or infinity.
    if(0 == t || is_infinite(t))
        {
        return 0;
        }
// TODO ?? As this is written on 2005-11-03, cygwin lacks fabsl().
// It would be far better to write replacements for this and other
// such functions in one unit-tested module, and use them here as
// well as in 'round_to.hpp'.
#if !defined __CYGWIN__
    long double z = std::numeric_limits<T>::epsilon() * fabsl(t);
    return std::max(0, static_cast<int>(-log10l(z)));
#else  // defined __CYGWIN__
    long double z = std::numeric_limits<T>::epsilon() * t;
    if(t < 0.0)
        {
        z = -z;
        }
    return std::max(0, static_cast<int>(-log10(z)));
#endif // defined __CYGWIN__
}
static void tst3() {
    unsynch_mpq_manager m; 
    scoped_mpq a(m);      
    SASSERT(is_zero(m, a, EN_NUMERAL));
    SASSERT(!is_zero(m, a, EN_PLUS_INFINITY));
    SASSERT(!is_zero(m, a, EN_MINUS_INFINITY));
    SASSERT(!is_pos(m, a, EN_NUMERAL));
    SASSERT(is_pos(m, a, EN_PLUS_INFINITY));
    SASSERT(!is_pos(m, a, EN_MINUS_INFINITY));
    SASSERT(!is_infinite(EN_NUMERAL));
    SASSERT(is_infinite(EN_PLUS_INFINITY));
    SASSERT(is_infinite(EN_MINUS_INFINITY));
    SASSERT(!is_neg(m, a, EN_NUMERAL));
    SASSERT(!is_neg(m, a, EN_PLUS_INFINITY));
    SASSERT(is_neg(m, a, EN_MINUS_INFINITY));
    m.set(a, 10);
    SASSERT(!is_zero(m, a, EN_NUMERAL));
    SASSERT(is_pos(m, a, EN_NUMERAL));
    SASSERT(!is_neg(m, a, EN_NUMERAL));
    SASSERT(!is_infinite(EN_NUMERAL));
    m.set(a, -5);
    SASSERT(!is_zero(m, a, EN_NUMERAL));
    SASSERT(!is_pos(m, a, EN_NUMERAL));
    SASSERT(is_neg(m, a, EN_NUMERAL));
    SASSERT(!is_infinite(EN_NUMERAL));
    ext_numeral_kind ak;
    ak = EN_MINUS_INFINITY;
    reset(m, a, ak);
    SASSERT(is_zero(m, a, EN_NUMERAL));
    {
        std::ostringstream buffer;        
        display(buffer, m, a, ak); 
        SASSERT(buffer.str() == "0");
    }
    {
        std::ostringstream buffer;        
        m.set(a, -10);
        display(buffer, m, a, ak); 
        SASSERT(buffer.str() == "-10");
    }
    {
        std::ostringstream buffer;        
        display(buffer, m, a, EN_PLUS_INFINITY); 
        SASSERT(buffer.str() == "oo");
    }
    {
        std::ostringstream buffer;        
        display(buffer, m, a, EN_MINUS_INFINITY); 
        SASSERT(buffer.str() == "-oo");
    }
}
Exemplo n.º 4
0
void Foam::cellShapeControlMesh::barycentricCoords
(
    const Foam::point& pt,
    barycentric& bary,
    Cell_handle& ch
) const
{
    // Use the previous cell handle as a hint on where to start searching
    // Giving a hint causes strange errors...
    ch = locate(toPoint(pt));

    if (dimension() > 2 && !is_infinite(ch))
    {
        oldCellHandle_ = ch;

        tetPointRef tet
        (
            topoint(ch->vertex(0)->point()),
            topoint(ch->vertex(1)->point()),
            topoint(ch->vertex(2)->point()),
            topoint(ch->vertex(3)->point())
        );

        bary = tet.pointToBarycentric(pt);
    }
}
Exemplo n.º 5
0
void ext_numeral::inv() {
    SASSERT(!is_zero());
    if (is_infinite()) {
        m_kind = FINITE;
        m_value.reset();
    }
    else {
        m_value = rational(1) / m_value;
    }
}
Exemplo n.º 6
0
ext_numeral & ext_numeral::operator-=(ext_numeral const & other) {
    SASSERT(!is_infinite() || !other.is_infinite() || (m_kind != other.m_kind));
    if (is_infinite())
        return *this;
    SASSERT(m_kind == FINITE);
    switch (other.m_kind) {
    case MINUS_INFINITY:
        m_kind = PLUS_INFINITY;
        m_value.reset();
        return *this;
    case FINITE:
        m_value -= other.m_value;
        return *this;
    case PLUS_INFINITY:
        m_kind = MINUS_INFINITY;
        m_value.reset();
        return *this;
    }
    UNREACHABLE();
    return *this;
}
Exemplo n.º 7
0
void Foam::CV2D::fast_restore_Delaunay(Vertex_handle vh)
{
    int i;
    Face_handle f = vh->face(), next, start(f);

    do
    {
        i=f->index(vh);
        if (!is_infinite(f))
        {
            if (!internal_flip(f, cw(i))) external_flip(f, i);
            if (f->neighbor(i) == start) start = f;
        }
        f = f->neighbor(cw(i));
    } while (f != start);
}
Exemplo n.º 8
0
ext_numeral & ext_numeral::operator*=(ext_numeral const & other) {
    if (is_zero() || other.is_zero()) {
        m_kind = FINITE;
        m_value.reset();
        return *this;
    }
    
    if (is_infinite() || other.is_infinite()) {
        if (sign() == other.sign())
            m_kind = PLUS_INFINITY;
        else
            m_kind = MINUS_INFINITY;
        m_value.reset();
        return *this;
    }

    SASSERT(m_kind == FINITE);
    m_value *= other.m_value;
    return *this;
}
Exemplo n.º 9
0
/*
 * Get relative position of value in a length histogram bin in [0,1] range.
 */
static double
get_len_position(double value, double hist1, double hist2)
{
	if (!is_infinite(hist1) && !is_infinite(hist2))
	{
		/*
		 * Both bounds are finite. The value should be finite too, because it
		 * lies somewhere between the bounds. If it doesn't, just return
		 * something.
		 */
		if (is_infinite(value))
			return 0.5;

		return 1.0 - (hist2 - value) / (hist2 - hist1);
	}
	else if (is_infinite(hist1) && !is_infinite(hist2))
	{
		/*
		 * Lower bin boundary is -infinite, upper is finite.
		 * Return 1.0 to indicate the value is infinitely far from the lower
		 * bound.
		 */
		return 1.0;
	}
	else if (is_infinite(hist1) && is_infinite(hist2))
	{
		/* same as above, but in reverse */
		return 0.0;
	}
	else
	{
		/*
		 * If both bin boundaries are infinite, they should be equal to each
		 * other, and the value should also be infinite and equal to both
		 * bounds. (But don't Assert that, to avoid crashing unnecessarily
		 * if the caller messes up)
		 *
		 * Assume the value to lie in the middle of the infinite bounds.
		 */
		return 0.5;
	}
}
Exemplo n.º 10
0
void main(){
  
  //Programming chaismus. I could have reordered it, but it's
  //the little things in life. 
  FILE *out1;
  int seed = 6750236;
  out1  = fopen("out_put.out", "w");
  rinitialize(seed);
  float temp = 0;
  int count = 0;
  for(int i = 0; i < 100; i++){
    for(int j = 0; j < 10; j++){
      printf("i");
      run_a_job();
      if(is_infinite()){
        count++;
      }
    }
    temp+=count/10.0;
  }
  fprintf(out1,"%6.4f",temp/100.0);
}
Exemplo n.º 11
0
void Foam::CV2D::calcDual
(
    point2DField& dualPoints,
    faceList& dualFaces,
    wordList& patchNames,
    labelList& patchSizes,
    EdgeMap<label>& mapEdgesRegion,
    EdgeMap<label>& indirectPatchEdge
) const
{
    // Dual points stored in triangle order.
    dualPoints.setSize(number_of_faces());
    label dualVerti = 0;

    for
    (
        Triangulation::Finite_faces_iterator fit = finite_faces_begin();
        fit != finite_faces_end();
        ++fit
    )
    {
        if
        (
            fit->vertex(0)->internalOrBoundaryPoint()
         || fit->vertex(1)->internalOrBoundaryPoint()
         || fit->vertex(2)->internalOrBoundaryPoint()
        )
        {
            fit->faceIndex() = dualVerti;

            dualPoints[dualVerti++] = toPoint2D(circumcenter(fit));
        }
        else
        {
            fit->faceIndex() = -1;
        }
    }

    dualPoints.setSize(dualVerti);

    extractPatches(patchNames, patchSizes, mapEdgesRegion, indirectPatchEdge);

    forAll(patchNames, patchi)
    {
        Info<< "Patch " << patchNames[patchi]
            << " has size " << patchSizes[patchi] << endl;
    }

    // Create dual faces
    // ~~~~~~~~~~~~~~~~~

    dualFaces.setSize(number_of_vertices());
    label dualFacei = 0;
    labelList faceVerts(maxNvert);

    for
    (
        Triangulation::Finite_vertices_iterator vit = finite_vertices_begin();
        vit != finite_vertices_end();
        ++vit
    )
    {
        if (vit->internalOrBoundaryPoint())
        {
            Face_circulator fcStart = incident_faces(vit);
            Face_circulator fc = fcStart;
            label verti = 0;

            do
            {
                if (!is_infinite(fc))
                {
                    if (fc->faceIndex() < 0)
                    {
                        FatalErrorInFunction
                         << "Dual face uses vertex defined by a triangle"
                            " defined by an external point"
                            << exit(FatalError);
                    }

                    // Look up the index of the triangle
                    faceVerts[verti++] = fc->faceIndex();
                }
            } while (++fc != fcStart);

            if (faceVerts.size() > 2)
            {
                dualFaces[dualFacei++] =
                    face(labelList::subList(faceVerts, verti));
            }
            else
            {
                Info<< "From triangle point:" << vit->index()
                    << " coord:" << toPoint2D(vit->point())
                    << " generated illegal dualFace:" << faceVerts
                    << endl;
            }
        }
    }

    dualFaces.setSize(dualFacei);
}
Exemplo n.º 12
0
void Foam::CV2D::writeFaces(const fileName& fName, bool internalOnly) const
{
    Info<< "Writing dual faces to " << fName << nl << endl;
    OFstream str(fName);

    label dualVerti = 0;

    for
    (
        Triangulation::Finite_faces_iterator fit = finite_faces_begin();
        fit != finite_faces_end();
        ++fit
    )
    {
        if
        (
            !internalOnly
         || (
                fit->vertex(0)->internalOrBoundaryPoint()
             || fit->vertex(1)->internalOrBoundaryPoint()
             || fit->vertex(2)->internalOrBoundaryPoint()
            )
        )
        {
            fit->faceIndex() = dualVerti++;
            meshTools::writeOBJ(str, toPoint3D(circumcenter(fit)));
        }
        else
        {
            fit->faceIndex() = -1;
        }
    }

    for
    (
        Triangulation::Finite_vertices_iterator vit = finite_vertices_begin();
        vit != finite_vertices_end();
        ++vit
    )
    {
        if (!internalOnly || vit->internalOrBoundaryPoint())
        {
            Face_circulator fcStart = incident_faces(vit);
            Face_circulator fc = fcStart;

            str<< 'f';

            do
            {
                if (!is_infinite(fc))
                {
                    if (fc->faceIndex() < 0)
                    {
                        FatalErrorInFunction
                         << "Dual face uses vertex defined by a triangle"
                            " defined by an external point"
                            << exit(FatalError);
                    }

                    str<< ' ' << fc->faceIndex() + 1;
                }
            } while (++fc != fcStart);

            str<< nl;
        }
    }
}
Exemplo n.º 13
0
/***********************************************************************//**
 * @brief Perform Romberg integration
 *
 * @param[in] a Left integration boundary.
 * @param[in] b Right integration boundary.
 * @param[in] k Integration order (default: k=5)
 *
 * Returns the integral of the integrand from a to b. Integration is
 * performed by Romberg's method of order 2K, where e.g. K=2 in Simpson's
 * rule.
 * The number of iterations is limited by m_max_iter. m_eps specifies the
 * requested fractional accuracy. By default it is set to 1e-6.
 *
 * @todo Check that k is smaller than m_max_iter
 * @todo Make use of std::vector class
 ***************************************************************************/
double GIntegral::romb(const double& a, const double& b, const int& k)
{
    // Initialise result
    double result = 0.0;
    
    // Continue only if integration range is valid
    if (b > a) {

        // Initialise variables
        bool   converged = false;
        double ss        = 0.0;
        double dss       = 0.0;

        // Allocate temporal storage
        double* s = new double[m_max_iter+2];
        double* h = new double[m_max_iter+2];

        // Initialise step size
        h[1] = 1.0;
        s[0] = 0.0;

        // Iterative loop
        for (m_iter = 1; m_iter <= m_max_iter; ++m_iter) {

            // Integration using Trapezoid rule
            s[m_iter] = trapzd(a, b, m_iter, s[m_iter-1]);

            // Compile option: Check for NaN/Inf
            #if defined(G_NAN_CHECK)
            if (is_notanumber(s[m_iter]) || is_infinite(s[m_iter])) {
                std::cout << "*** ERROR: GIntegral::romb";
                std::cout << "(a=" << a << ", b=" << b << ", k=" << k << "):";
                std::cout << " NaN/Inf encountered";
                std::cout << " (s[" << m_iter << "]=" << s[m_iter] << ")";
                std::cout << std::endl;
            }
            #endif

            // Starting from iteration k on, use polynomial interpolation
            if (m_iter >= k) {
                ss = polint(&h[m_iter-k], &s[m_iter-k], k, 0.0, &dss);
                if (std::abs(dss) <= m_eps * std::abs(ss)) {
                    converged = true;
                    result    = ss;
                    break;
                }
            }

            // Reduce step size
            h[m_iter+1]= 0.25 * h[m_iter];

        } // endfor: iterative loop

        // Free temporal storage
        delete [] s;
        delete [] h;

        // Dump warning
        if (!m_silent) {
            if (!converged) {
                std::string msg = "Integration uncertainty "+
                                  gammalib::str(std::abs(dss))+
                                  " exceeds tolerance of "+
                                  gammalib::str(m_eps * std::abs(ss))+
                                  " after "+gammalib::str(m_iter)+
                                  " iterations. Result "+
                                  gammalib::str(result)+
                                  " is inaccurate.";
                gammalib::warning(G_ROMB, msg);
            }
        }
    
    } // endif: integration range was valid

    // Return result
    return result;
}
Exemplo n.º 14
0
/*
 * Calculate the average of function P(x), in the interval [length1, length2],
 * where P(x) is the fraction of tuples with length < x (or length <= x if
 * 'equal' is true).
 */
static double
calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues,
					  double length1, double length2, bool equal)
{
	double		frac;
	double		A,
				B,
				PA,
				PB;
	double		pos;
	int			i;
	double		area;

	Assert(length2 >= length1);

	if (length2 < 0.0)
		return 0.0;				/* shouldn't happen, but doesn't hurt to check */

	/* All lengths in the table are <= infinite. */
	if (is_infinite(length2) && equal)
		return 1.0;

	/*----------
	 * The average of a function between A and B can be calculated by the
	 * formula:
	 *
	 *			B
	 *	  1		/
	 * -------	| P(x)dx
	 *	B - A	/
	 *			A
	 *
	 * The geometrical interpretation of the integral is the area under the
	 * graph of P(x). P(x) is defined by the length histogram. We calculate
	 * the area in a piecewise fashion, iterating through the length histogram
	 * bins. Each bin is a trapezoid:
	 *
	 *		 P(x2)
	 *		  /|
	 *		 / |
	 * P(x1)/  |
	 *	   |   |
	 *	   |   |
	 *	---+---+--
	 *	   x1  x2
	 *
	 * where x1 and x2 are the boundaries of the current histogram, and P(x1)
	 * and P(x1) are the cumulative fraction of tuples at the boundaries.
	 *
	 * The area of each trapezoid is 1/2 * (P(x2) + P(x1)) * (x2 - x1)
	 *
	 * The first bin contains the lower bound passed by the caller, so we
	 * use linear interpolation between the previous and next histogram bin
	 * boundary to calculate P(x1). Likewise for the last bin: we use linear
	 * interpolation to calculate P(x2). For the bins in between, x1 and x2
	 * lie on histogram bin boundaries, so P(x1) and P(x2) are simply:
	 * P(x1) =	  (bin index) / (number of bins)
	 * P(x2) = (bin index + 1 / (number of bins)
	 */

	/* First bin, the one that contains lower bound */
	i = length_hist_bsearch(length_hist_values, length_hist_nvalues, length1, equal);
	if (i >= length_hist_nvalues - 1)
		return 1.0;

	if (i < 0)
	{
		i = 0;
		pos = 0.0;
	}
	else
	{
		/* interpolate length1's position in the bin */
		pos = get_len_position(length1,
							   DatumGetFloat8(length_hist_values[i]),
							   DatumGetFloat8(length_hist_values[i + 1]));
	}
	PB = (((double) i) + pos) / (double) (length_hist_nvalues - 1);
	B = length1;

	/*
	 * In the degenerate case that length1 == length2, simply return
	 * P(length1). This is not merely an optimization: if length1 == length2,
	 * we'd divide by zero later on.
	 */
	if (length2 == length1)
		return PB;

	/*
	 * Loop through all the bins, until we hit the last bin, the one that
	 * contains the upper bound. (if lower and upper bounds are in the same
	 * bin, this falls out immediately)
	 */
	area = 0.0;
	for (; i < length_hist_nvalues - 1; i++)
	{
		double		bin_upper = DatumGetFloat8(length_hist_values[i + 1]);

		/* check if we've reached the last bin */
		if (!(bin_upper < length2 || (equal && bin_upper <= length2)))
			break;

		/* the upper bound of previous bin is the lower bound of this bin */
		A = B;
		PA = PB;

		B = bin_upper;
		PB = (double) i / (double) (length_hist_nvalues - 1);

		/*
		 * Add the area of this trapezoid to the total. The point of the
		 * if-check is to avoid NaN, in the corner case that PA == PB == 0,
		 * and B - A == Inf. The area of a zero-height trapezoid (PA == PB ==
		 * 0) is zero, regardless of the width (B - A).
		 */
		if (PA > 0 || PB > 0)
			area += 0.5 * (PB + PA) * (B - A);
	}

	/* Last bin */
	A = B;
	PA = PB;

	B = length2;				/* last bin ends at the query upper bound */
	if (i >= length_hist_nvalues - 1)
		pos = 0.0;
	else
	{
		if (DatumGetFloat8(length_hist_values[i]) == DatumGetFloat8(length_hist_values[i + 1]))
			pos = 0.0;
		else
			pos = get_len_position(length2, DatumGetFloat8(length_hist_values[i]), DatumGetFloat8(length_hist_values[i + 1]));
	}
	PB = (((double) i) + pos) / (double) (length_hist_nvalues - 1);

	if (PA > 0 || PB > 0)
		area += 0.5 * (PB + PA) * (B - A);

	/*
	 * Ok, we have calculated the area, ie. the integral. Divide by width to
	 * get the requested average.
	 *
	 * Avoid NaN arising from infinite / infinite. This happens at least if
	 * length2 is infinite. It's not clear what the correct value would be in
	 * that case, so 0.5 seems as good as any value.
	 */
	if (is_infinite(area) && is_infinite(length2))
		frac = 0.5;
	else
		frac = area / (length2 - length1);

	return frac;
}
Exemplo n.º 15
0
MYBOOL __WINAPI guess_basis(lprec *lp, REAL *guessvector, int *basisvector)
{
  MYBOOL status = FALSE;
  REAL   *values = NULL, *violation = NULL,
         *value, error, upB, loB, sortorder = 1.0;
  int    i, n, *rownr, *colnr;
  MATrec *mat = lp->matA;

  if(!mat_validate(lp->matA))
    return( status );

  /* Create helper arrays */
  if(!allocREAL(lp, &values, lp->sum+1, TRUE) ||
     !allocREAL(lp, &violation, lp->sum+1, TRUE))
    goto Finish;

  /* Compute values of slack variables for given guess vector */
  i = 0;
  n = get_nonzeros(lp);
  rownr = &COL_MAT_ROWNR(i);
  colnr = &COL_MAT_COLNR(i);
  value = &COL_MAT_VALUE(i);
  for(; i < n; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep)
    values[*rownr] += unscaled_mat(lp, my_chsign(is_chsign(lp, *rownr), *value), *rownr, *colnr) *
                      guessvector[*colnr];
  MEMMOVE(values+lp->rows+1, guessvector+1, lp->columns);

  /* Initialize constraint bound violation measures */
  for(i = 1; i <= lp->rows; i++) {
    upB = get_rh_upper(lp, i);
    loB = get_rh_lower(lp, i);
    error = values[i] - upB;
    if(error > lp->epsprimal)
      violation[i] = sortorder*error;
    else {
      error = loB - values[i];
      if(error > lp->epsprimal)
        violation[i] = sortorder*error;
      else if(is_infinite(lp, loB) && is_infinite(lp, upB))
        ;
      else if(is_infinite(lp, upB))
        violation[i] = sortorder*(loB - values[i]);
      else if(is_infinite(lp, loB))
        violation[i] = sortorder*(values[i] - upB);
      else
        violation[i] = - sortorder*MAX(upB - values[i], values[i] - loB);
    }
    basisvector[i] = i;
  }

  /* Initialize user variable bound violation measures */
  for(i = 1; i <= lp->columns; i++) {
    n = lp->rows+i;
    upB = get_upbo(lp, i);
    loB = get_lowbo(lp, i);
    error = guessvector[i] - upB;
    if(error > lp->epsprimal)
      violation[n] = sortorder*error;
    else {
      error = loB - values[n];
      if(error > lp->epsprimal)
        violation[n] = sortorder*error;
      else if(is_infinite(lp, loB) && is_infinite(lp, upB))
        ;
      else if(is_infinite(lp, upB))
        violation[n] = sortorder*(loB - values[n]);
      else if(is_infinite(lp, loB))
        violation[n] = sortorder*(values[n] - upB);
      else
        violation[n] = - sortorder*MAX(upB - values[n], values[n] - loB);
    }
    basisvector[n] = n;
  }

  /* Sort decending by violation; this means that variables with
     the largest violations will be designated as basic */
  sortByREAL(basisvector, violation, lp->sum, 1, FALSE);

  /* Adjust the non-basic indeces for the (proximal) bound state */
  error = lp->epsprimal;
  for(i = lp->rows+1, rownr = basisvector+i; i <= lp->sum; i++, rownr++) {
    if(*rownr <= lp->rows) {
      if(values[*rownr] <= get_rh_lower(lp, *rownr)+error)
        *rownr = -(*rownr);
    }
    else
      if(values[i] <= get_lowbo(lp, (*rownr)-lp->rows)+error)
        *rownr = -(*rownr);
  }

  /* Clean up and return status */
  status = (MYBOOL) (violation[1] == 0);
Finish:
  FREE(values);
  FREE(violation);


  return( status );
}
Exemplo n.º 16
0
void
compute_adjacencies_with_polygon
    (const Matrix &X,
     const Vector &weights,
     const Matrix &polygon,
     std::vector<std::vector<Segment>> &adjedges,
     std::vector<std::vector<size_t>> &adjverts)
{
  auto rt = MA::details::make_regular_triangulation(X,weights);

  int Np = polygon.rows();
  int Nv = X.rows();
  adjedges.assign(Nv, std::vector<Segment>());
  adjverts.assign(Nv, std::vector<size_t>());

  for (int p = 0; p < Np; ++p)
    {
      int pnext = (p + 1) % Np;
      //int pprev = (p + Np - 1) % Np;
      Point source(polygon(p,0), polygon(p,1));
      Point target(polygon(pnext,0), polygon(pnext,1));

      auto u = rt.nearest_power_vertex(source);
      auto v = rt.nearest_power_vertex(target);

      adjverts[u->info()].push_back(p);
      Point pointprev = source;

      auto  uprev = u;
      while (u != v)
	{
	  // find next vertex intersecting with  segment
	  auto c = rt.incident_edges(u), done(c);
	  do
	    {
	      if (rt.is_infinite(c))
		continue;

	      // we do not want to go back to the previous vertex!
	      auto unext = (c->first)->vertex(rt.ccw(c->second));
	      if (unext == uprev)
		continue;

	      // check whether dual edge (which can be a ray, a line
	      // or a segment) intersects with the constraint
	      Point point;
	      if (!edge_dual_and_segment_isect(rt.dual(c),
					       Segment(source,target),
					       point))
		continue;

	      adjedges[u->info()].push_back(Segment(pointprev,point));
	      pointprev = point;
	      uprev = u;
	      u = unext;

	      break;
	    }
	  while(++c != done);
	}

      adjverts[v->info()].push_back(pnext);
      adjedges[v->info()].push_back(Segment(pointprev, target));
    }
}