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; }
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); } }
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(); }
bool Node::hasConverged(double epsilon) const { if (std::abs(objUpperBound - objLowerBound) < epsilon) return true; if (assertNear(objUpperBound, objLowerBound, epsilon)) return true; return false; }
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); } }
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(); }
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; }
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 }
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; }