예제 #1
0
SparseMatrix BSplineBasis1D::refineKnotsLocally(double x)
{
    if (!insideSupport(x))
        throw Exception("BSplineBasis1D::refineKnotsLocally: Cannot refine outside support!");

    if (getNumBasisFunctions() >= getNumBasisFunctionsTarget()
            || assertNear(knots.front(), knots.back()))
    {
        unsigned int n = getNumBasisFunctions();
        DenseMatrix A = DenseMatrix::Identity(n,n);
        return A.sparseView();
    }

    // Refined knot vector
    std::vector<double> refinedKnots = knots;

    auto upper = std::lower_bound(refinedKnots.begin(), refinedKnots.end(), x);

    // Check left boundary
    if (upper == refinedKnots.begin())
        std::advance(upper, degree+1);

    // Get previous iterator
    auto lower = std::prev(upper);

    // Do not insert if upper and lower bounding knot are close
    if (assertNear(*upper, *lower))
    {
        unsigned int n = getNumBasisFunctions();
        DenseMatrix A = DenseMatrix::Identity(n,n);
        return A.sparseView();
    }

    // Insert knot at x
    double insertVal = x;

    // Adjust x if it is on or close to a knot
    if (knotMultiplicity(x) > 0
            || assertNear(*upper, x, 1e-6, 1e-6)
            || assertNear(*lower, x, 1e-6, 1e-6))
    {
        insertVal = (*upper + *lower)/2.0;
    }

    // Insert new knot
    refinedKnots.insert(upper, insertVal);

    if (!isKnotVectorRegular(refinedKnots) || !isRefinement(refinedKnots))
        throw Exception("BSplineBasis1D::refineKnotsLocally: New knot vector is not a proper refinement!");

    // Build knot insertion matrix
    SparseMatrix A = buildKnotInsertionMatrix(refinedKnots);

    // Update knots
    knots = refinedKnots;

    return A;
}
예제 #2
0
void CLSimulator::assertConvolutionResults()
{
    std::unique_ptr<float[]> sumFootprintAMPA_tmp(new float[_numNeurons]);
    _err = _wrapper.getQueue().enqueueReadBuffer(_sumFootprintAMPA_cl, CL_FALSE, 0, _numNeurons * sizeof(float), sumFootprintAMPA_tmp.get(), NULL, NULL);
    std::unique_ptr<float[]> sumFootprintNMDA_tmp(new float[_numNeurons]);
    _err = _wrapper.getQueue().enqueueReadBuffer(_sumFootprintNMDA_cl, CL_TRUE, 0, _numNeurons * sizeof(float), sumFootprintNMDA_tmp.get(), NULL, NULL);

    for (size_t i = 0; i < _numNeurons; ++i)
    {
        assertNear(_sumFootprintAMPA[i], sumFootprintAMPA_tmp[i], 0.00001);
        assertNear(_sumFootprintNMDA[i], sumFootprintNMDA_tmp[i], 0.00001);
    }
}
예제 #3
0
bool ConstraintBSpline::reduceVariableRanges() const
{
    // Update bound of y in f(x) - y = 0
    DenseVector minControlPoints = controlPoints.rowwise().minCoeff();
    DenseVector maxControlPoints = controlPoints.rowwise().maxCoeff();

    for (unsigned int i = variables.size()-numConstraints; i < variables.size(); i++)
    {
        assert(minControlPoints(i) <= maxControlPoints(i));

        // Fix for B-splines with collapsed bounds
        double xlb = variables.at(i)->getLowerBound();
        double xub = variables.at(i)->getUpperBound();

        if (assertNear(xlb, xub))
            continue;

        double newlb = std::max(xlb, minControlPoints(i));
        double newub = std::min(xub, maxControlPoints(i));

        // Detect constraint infeasibility or update bounds
        if (!variables.at(i)->updateBounds(newlb, newub))
            return false;
    }

    // Compute and check variable bounds
    return controlPointBoundsDeduction();
}
예제 #4
0
파일: node.cpp 프로젝트: bgrimstad/censo
bool Node::hasConverged(double epsilon) const
{
    if (std::abs(objUpperBound - objLowerBound) < epsilon)
        return true;

    if (assertNear(objUpperBound, objLowerBound, epsilon))
        return true;

    return false;
}
예제 #5
0
void CLSimulator::assertInitializationResults()
{
    boost::scoped_array<float> distances_real(new float[_nFFT]);
    boost::scoped_array<float> distances_imag(new float[_nFFT]);
    boost::scoped_array<float> distances_f_real(new float[_nFFT]);
    boost::scoped_array<float> distances_f_imag(new float[_nFFT]);

    _err = _wrapper.getQueue().enqueueReadBuffer(_distances_real_cl, CL_TRUE, 0, _nFFT * sizeof(float), distances_real.get(), NULL, NULL);
    _err = _wrapper.getQueue().enqueueReadBuffer(_distances_imag_cl, CL_TRUE, 0, _nFFT * sizeof(float), distances_imag.get(), NULL, NULL);
    _err = _wrapper.getQueue().enqueueReadBuffer(_distances_f_real_cl, CL_TRUE, 0, _nFFT * sizeof(float), distances_f_real.get(), NULL, NULL);
    _err = _wrapper.getQueue().enqueueReadBuffer(_distances_f_imag_cl, CL_TRUE, 0, _nFFT * sizeof(float), distances_f_imag.get(), NULL, NULL);

    for (size_t i = 0; i < _nFFT; ++i)
    {
        assertAlmostEquals(_distances_split[i][0], distances_real[i]);
        assertAlmostEquals(_distances_split[i][1], distances_imag[i]);
        assertNear(_distances_f_split[i][0], distances_f_real[i], 0.000001);
        assertNear(_distances_f_split[i][1], distances_f_imag[i], 0.000001);
    }
}
예제 #6
0
void ConstraintBSpline::reduceBSplineDomain()
{
    std::vector<double> varlb, varub;
    for (unsigned int i = 0; i < bspline.getNumVariables(); i++)
    {
        varlb.push_back(variables.at(i)->getLowerBound());
        varub.push_back(variables.at(i)->getUpperBound());
    }

    std::vector<double> bslb = bspline.getDomainLowerBound();
    std::vector<double> bsub = bspline.getDomainUpperBound();

    // Hack for fixed input variables
    for (unsigned int i = 0; i < varlb.size(); i++)
    {
        if (assertNear(varlb.at(i), varub.at(i)))
        {
            /*
             * NOTE: Expand B-spline domain to avoid knot multiplicity
             * (the B-spline cannot have an empty domain).
             *
             * This is especially important when doing integer optimization,
             * where bounds often are collapsed (lb = ub).
             *
             * The bound threshold should be a very small number, but not
             * too small! It must allow a at least 1000 distinct knot values
             * between the lower and upper bound!
             */
            double boundThreshold = 100000*std::numeric_limits<double>::epsilon();
            varlb.at(i) = std::max(bslb.at(i), varlb.at(i)-boundThreshold);
            varub.at(i) = std::min(bsub.at(i), varub.at(i)+boundThreshold);
        }
    }

    // Reduce domain of B-spline
    bspline.reduceDomain(varlb, varub);

    // Refinement for low dimensional B-spline
    //if (bspline.getNumVariables() <= 2)
        bspline.globalKnotRefinement();

    // Update control points
    controlPoints = bspline.getControlPoints();
}
예제 #7
0
파일: obbt.cpp 프로젝트: bgrimstad/censo
bool OBBT::doTightening(ConstraintPtr constraints)
{
    // Get convex relaxation
    ConstraintPtr convexConstraints = constraints->getConvexRelaxation();

    assert(convexConstraints != nullptr);
    assert(convexConstraints->isConstraintConvex());

    // Tighten bounds of all complicating variables
    std::vector<VariablePtr> variables;
    for (auto var : constraints->getComplicatingVariables())
    {
        if (assertNear(var->getUpperBound(), var->getLowerBound()))
            continue;

        variables.push_back(var);
    }

    // Check if there are any variables to tighten
    if (variables.size() < 1)
        return true;

    // Tighten bounds
    return tightenBoundsSequential(convexConstraints, variables);
//    bool success = true;

//    if (doParallelComputing)
//    {
//        tightenBoundsParallel(convexConstraints, variables);
//    }
//    else
//    {
//        success = tightenBoundsSequential(convexConstraints, variables);
//    }

//    return success;
}
예제 #8
0
bool isInteger(double value)
{
    return assertNear(value, std::floor(value));
    //return (value == std::floor(value)); // Fast, to int precision
    // return (std::abs(value - round(value)) < 1e-9); // Slow, specified precision
}
예제 #9
0
bool ConstraintBSpline::controlPointBoundsDeduction() const
{
    // Get variable bounds
    auto xlb = bspline.getDomainLowerBound();
    auto xub = bspline.getDomainUpperBound();

    // Use these instead?
//    for (unsigned int i = 0; i < bspline.getNumVariables(); i++)
//    {
//        xlb.at(i) = variables.at(i)->getLowerBound();
//        xub.at(i) = variables.at(i)->getUpperBound();
//    }

    double lowerBound = variables.back()->getLowerBound(); // f(x) = y > lowerBound
    double upperBound = variables.back()->getUpperBound(); // f(x) = y < upperBound

    // Get knot vectors and basis degrees
    auto knotVectors = bspline.getKnotVectors();
    auto basisDegrees = bspline.getBasisDegrees();

    // Compute n value for each variable
    // Total number of control points is ns(0)*...*ns(d-1)
    std::vector<unsigned int> numBasisFunctions = bspline.getNumBasisFunctions();

    // Get matrix of coefficients
    DenseMatrix cps = controlPoints;
    DenseMatrix coeffs = cps.block(bspline.getNumVariables(), 0, 1, cps.cols());

    for (unsigned int d = 0; d < bspline.getNumVariables(); d++)
    {
        if (assertNear(xlb.at(d), xub.at(d)))
            continue;

        auto n = numBasisFunctions.at(d);
        auto p = basisDegrees.at(d);
        std::vector<double> knots = knotVectors.at(d);
        assert(knots.size() == n+p+1);

        // Tighten lower bound
        unsigned int i = 1;
        for (; i <= n; i++)
        {
            // Knot interval of interest: [t_0, t_i]

            // Selection matrix
            DenseMatrix S = DenseMatrix::Ones(1,1);

            for (unsigned int d2 = 0; d2 < bspline.getNumVariables(); d2++)
            {
                DenseMatrix temp(S);

                DenseMatrix Sd_full = DenseMatrix::Identity(numBasisFunctions.at(d2),numBasisFunctions.at(d2));
                DenseMatrix Sd(Sd_full);
                if (d == d2)
                    Sd = Sd_full.block(0,0,n,i);

                S = kroneckerProduct(temp, Sd);
            }

            // Control points that have support in [t_0, t_i]
            DenseMatrix selc = coeffs*S;
            DenseVector minCP = selc.rowwise().minCoeff();
            DenseVector maxCP = selc.rowwise().maxCoeff();
            double minv = minCP(0);
            double maxv = maxCP(0);

            // Investigate feasibility
            if (minv > upperBound || maxv < lowerBound)
                continue; // infeasible
            else
                break; // feasible
        }

        // New valid lower bound on x(d) is knots(i-1)
        if (i > 1)
        {
            if (!variables.at(d)->updateLowerBound(knots.at(i-1)))
                return false;
        }

        // Tighten upper bound
        i = 1;
        for (; i <= n; i++)
        {
            // Knot interval of interest: [t_{n+p-i}, t_{n+p}]

            // Selection matrix
            DenseMatrix S = DenseMatrix::Ones(1,1);

            for (unsigned int d2 = 0; d2 < bspline.getNumVariables(); d2++)
            {
                DenseMatrix temp(S);

                DenseMatrix Sd_full = DenseMatrix::Identity(numBasisFunctions.at(d2),numBasisFunctions.at(d2));
                DenseMatrix Sd(Sd_full);
                if (d == d2)
                    Sd = Sd_full.block(0,n-i,n,i);

                S = kroneckerProduct(temp, Sd);
            }

            // Control points that have support in [t_{n+p-i}, t_{n+p}]
            DenseMatrix selc = coeffs*S;
            DenseVector minCP = selc.rowwise().minCoeff();
            DenseVector maxCP = selc.rowwise().maxCoeff();
            double minv = minCP(0);
            double maxv = maxCP(0);

            // Investigate feasibility
            if (minv > upperBound || maxv < lowerBound)
                continue; // infeasible
            else
                break; // feasible
        }

        // New valid lower bound on x(d) is knots(n+p-(i-1))
        if (i > 1)
        {
            if (!variables.at(d)->updateUpperBound(knots.at(n+p-(i-1))))
                return false;
            // NOTE: the upper bound seems to not be tight! can we use knots.at(n+p-i)?
        }

    }

    return true;
}