Esempio n. 1
0
void centerMatrix(DenseMatrix& matrix)
{
	DenseVector col_means = matrix.colwise().mean().transpose();
	DenseMatrix::Scalar grand_mean = matrix.mean();
	matrix.array() += grand_mean;
	matrix.rowwise() -= col_means.transpose();
	matrix.colwise() -= col_means;
}
Esempio n. 2
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;
}