I'm trying to transform a float3 array by using containers into a container of a specific structure. Code below:
#include <thrust/device_ptr.h>
#include <thrust/extrema.h>
#include <thrust/reduce.h>
#include <thrust/execution_policy.h>
#include <thrust/functional.h>
// Ouput structure for thrust::transform
struct cloud_point_index_idx {
unsigned int idx;
float3 cloud_point;
cloud_point_index_idx(unsigned int idx_, float3 cloud_point_) :
idx(idx_), cloud_point(cloud_point_) {}
bool operator < (const cloud_point_index_idx &p) const {
return (idx < p.idx);
}
};
// Functor for thrust::transform
struct point2voxelcentroid {
float3 leaf_size;
int min_x, min_y, min_z;
point2voxelcentroid(float3 leaf_size,int min_x, int min_y, int min_z) {
this->leaf_size = leaf_size;
this->min_x = min_x; this->min_y = min_y; this->min_z = min_z;
}
__host__ __device__
cloud_point_index_idx operator()(const float3 point) const {
int ijk0 = static_cast<int>(floor(point.x / leaf_size.x) -
static_cast<float>(min_x));
int ijk1 = static_cast<int>(floor(point.y / leaf_size.y) -
static_cast<float>(min_y));
int ijk2 = static_cast<int>(floor(point.z / leaf_size.z) -
static_cast<float>(min_z));
int voxel_idx = ijk0 + ijk1 + ijk2;
return cloud_point_index_idx(static_cast<unsigned int>(voxel_idx), point);
}
};
int main() { // Example
int num_points = 5;
float3 data[5] = {{1, 0, 2}, {2, 1, 3}, {1, 1, -5}, {-1, 3, -2}, {-5, -2, 0}}; // Set the data
int min_b_[3] = {-5, -2, -5};
float3 leaf_size = {0.5, 0.5, 0.5};
thrust::device_vector<float3> d_ptr(data, data + num_points); // Wrap it into a device_vector
thrust::device_vector<cloud_point_index_idx> voxel_idx_vector; // Output
voxel_idx_vector.reserve(num_points);
thrust::transform(
thrust::device,
d_ptr.begin(), d_ptr.end(),
voxel_idx_vector.begin(),
point2voxelcentroid(leaf_size, min_b_[0], min_b_[1], min_b_[2]));
thrust::host_vector<cloud_point_index_idx> indices; // Host vector to verify
indices.reserve(num_points);
thrust::copy(voxel_idx_vector.begin(), voxel_idx_vector.end(), indices.begin()); // Copy device to host
// Print out values
std::cout << "\n---\nAfter assignment\n";
for (int i = 0; i < num_points; i++) {
std::cout << "Voxel idx: " << indices[i].idx << ". Point: [" << indices[i].cloud_point.x << ", "
<< indices[i].cloud_point.y << ", " << indices[i].cloud_point.z << std::endl;
}
}
I inspected my functor values and they seem to correctly parse the data but when I print my host_vector I get really weird values, nothing related to what my output must be. I suspect I'm not initializing my output host/device vectors correctly. I tried other methods to initialize them but they all give me errors when compiling. I'm not sure what I'm doing wrong.
There are a couple of problems here, but the most severe is the use of reserve which doesn't actually allocate memory for a thrust container.
What you need to do is define a default constructor and explicitly allocate a size at instantiation. Something like this:
struct cloud_point_index_idx {
int idx;
float3 cloud_point;
cloud_point_index_idx()=default;
__host__ __device__
cloud_point_index_idx(unsigned int idx_, float3 cloud_point_) :
idx(idx_), cloud_point(cloud_point_) {}
__host__ __device__
bool operator < (const cloud_point_index_idx &p) const {
return (idx < p.idx);
}
};
(requires -std=c++11) will define a default constructor on both device and host which the container must call during initialization of each class instance.
This modification of your code works for me:
$ cat bodgey.cu
#include <thrust/device_vector.h>
#include <thrust/device_ptr.h>
#include <thrust/extrema.h>
#include <thrust/reduce.h>
#include <thrust/execution_policy.h>
#include <thrust/functional.h>
#include <iostream>
// Ouput structure for thrust::transform
struct cloud_point_index_idx {
int idx;
float3 cloud_point;
cloud_point_index_idx()=default;
__host__ __device__
cloud_point_index_idx(unsigned int idx_, float3 cloud_point_) :
idx(idx_), cloud_point(cloud_point_) {}
__host__ __device__
bool operator < (const cloud_point_index_idx &p) const {
return (idx < p.idx);
}
};
// Functor for thrust::transform
struct point2voxelcentroid {
float3 leaf_size;
int min_x, min_y, min_z;
point2voxelcentroid(float3 leaf_size,int min_x, int min_y, int min_z) {
this->leaf_size = leaf_size;
this->min_x = min_x; this->min_y = min_y; this->min_z = min_z;
}
__host__ __device__
cloud_point_index_idx operator()(const float3 point) const {
int ijk0 = static_cast<int>(floor(point.x / leaf_size.x) -
static_cast<float>(min_x));
int ijk1 = static_cast<int>(floor(point.y / leaf_size.y) -
static_cast<float>(min_y));
int ijk2 = static_cast<int>(floor(point.z / leaf_size.z) -
static_cast<float>(min_z));
int voxel_idx = ijk0 + ijk1 + ijk2;
return cloud_point_index_idx(voxel_idx, point);
}
};
int main() { // Example
int num_points = 5;
float3 data[5] = {{1, 0, 2}, {2, 1, 3}, {1, 1, -5}, {-1, 3, -2}, {-5, -2, 0}}; // Set the data
int min_b_[3] = {-5, -2, -5};
float3 leaf_size = {0.5, 0.5, 0.5};
thrust::device_vector<float3> d_ptr(data, data + num_points); // Wrap it into a device_vector
thrust::device_vector<cloud_point_index_idx> voxel_idx_vector(num_points); // Output
thrust::transform(
thrust::device,
d_ptr.begin(), d_ptr.end(),
voxel_idx_vector.begin(),
point2voxelcentroid(leaf_size, min_b_[0], min_b_[1], min_b_[2]));
thrust::host_vector<cloud_point_index_idx> indices(num_points); // Host vector to verify
thrust::copy(voxel_idx_vector.begin(), voxel_idx_vector.end(), indices.begin()); // Copy device to host
// Print out values
std::cout << "\n---\nAfter assignment\n";
for (int i = 0; i < num_points; i++) {
std::cout << "Voxel idx: " << indices[i].idx << ". Point: [" << indices[i].cloud_point.x << ", "
<< indices[i].cloud_point.y << ", " << indices[i].cloud_point.z << std::endl;
}
}
$ nvcc -std=c++11 -arch=sm_52 -o bodgey bodgey.cu
$ ./bodgey
---
After assignment
Voxel idx: 18. Point: [1, 0, 2
Voxel idx: 24. Point: [2, 1, 3
Voxel idx: 6. Point: [1, 1, -5
Voxel idx: 12. Point: [-1, 3, -2
Voxel idx: -2. Point: [-5, -2, 0
Related
I need to write constructors for my 3x3 matrix class. I'm not sure whether I'm doing it efficiently and I do not know how to use initializer_list.. I would like a constructor that creates by default the identity matrix, and receives parameteres to set a diagonal matrix. Then I'd also like a constructor that takes a list of cofficients (with initialization_list) and puts them in the matrix. This is what I have:
#include <iostream>
#include <array>
#include <cmath>
#include <initializer_list>
#include "Vecteur.h"
using namespace std;
class Matrice33 {
private :
array<array<double,3>,3> matrice;
public :
Matrice33(double a = 1, double b=1, double c=1)
{ matrice[0][0] = a; matrice[1][1]= b; matrice [2][2]= c;
matrice[0][1] = 0; matrice[0][2] = 0;
matrice[1][0] = 0; matrice[1][2] = 0;
matrice[2][0] = 0; matrice[2][1] = 0;} \\ IS THIS THE ONLY WAY TO SET THE MATRIX OR IS
\\THERE A QUICKER ONE?
Matrice33(initilizer_liste<double> cosnt& coeff)
{ for( auto c : coeff) \\ I DON'T KNOW HOW TO WRITE THIS CONSTRUCTOR...
void affiche() const { for(auto m : matrice){
for(auto n : m) {
cout<<n<<" ";}
cout<<endl;}}
};
int main(){
Matrice33 mat(1.1, 1.2, 1.3,
2.1, 2.2, 2.3,
3.1, 3.2, 3.3); \\I'D LIKE THIS TO BE TAKEN AS THE LIST BY MY CONSTRUCTOR, FOR
\\EXAMPLE
Matrice33 m(2.0,3.0,1.0);
m.affiche(); \\ WHEN I EXECUTE I DON'T GET ANY OUTPUT..
return 0;
}
This is changed version of your code that is just working.
#include <iostream>
#include <array>
#include <cmath>
#include <initializer_list>
#include <vector>
using namespace std;
class Matrice33
{
public:
Matrice33(double a = 1, double b = 1, double c = 1)
: matrice{{ {{a, 0, 0}}, {{0, b, 0}}, {{0, 0, c}} }}
{
}
Matrice33(const std::initializer_list<std::initializer_list<double>> & coeff)
{
int counter = 0;
for (auto row : coeff)
{
copy(row.begin(), row.end(), matrice[counter++].begin());
}
}
void affiche()
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << matrice[i][j] << " ";
}
cout << endl;;
}
}
private:
array<array<double, 3>, 3> matrice;
};
int main()
{
Matrice33 mat{ {1.1, 1.2, 1.3},{2.1, 2.2, 2.3},{3.1, 3.2, 3.3} };
mat.affiche();
Matrice33 m(2.0, 3.0, 1.0);
m.affiche();
return 0;
}
You can use perfect forwarding and template constructor here.
template<typename... Args>
Matrice33(Args&&... args) : matrice(std::forward<Args>(args)...) {}
then initialization will be same as intitialization of std::array.
So I have the following class KdTree:
#include <nanoflann.hpp>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <cstdlib>
#include <iostream>
struct PointCloud
{
struct Point
{
double x,y,z;
};
std::vector<Point> pts;
inline size_t kdtree_get_point_count() const { return pts.size(); }
inline double kdtree_get_pt(const size_t idx, const size_t dim) const
{
if (dim == 0) return pts[idx].x;
else if (dim == 1) return pts[idx].y;
else if (dim == 2) return pts[idx].z;
}
template <class BBOX>
bool kdtree_get_bbox(BBOX& /* bb */) const { return false; }
};
void generatePointCloud(PointCloud &point, const std::vector<std::vector<double>>& given)
{
point.pts.resize(given.size());
for (size_t i = 0; i < given.size(); ++i) {
point.pts[i].x = given[i][0];
point.pts[i].y = given[i][1];
point.pts[i].z = given[i][2];
}
}
using namespace nanoflann;
using Points = std::vector<std::vector<double>>;
class KdTree {
public:
KdTree(const Points& points) {
PointCloud cloud;
generatePointCloud(cloud, points); // just puts points into cloud format
index = std::make_shared<my_kd_tree>(3 /*dim*/, cloud, KDTreeSingleIndexAdaptorParams(10 /* max leaf */) );
index->buildIndex();
}
size_t GetNearest(const std::vector<double>& pt) const {
double query_pt[3] = { pt[0], pt[1], pt[2] };
const size_t num_results = 1;
size_t ret_index;
double out_dist_sqr;
nanoflann::KNNResultSet<double > resultSet(num_results);
resultSet.init(&ret_index, &out_dist_sqr );
index->findNeighbors(resultSet, &query_pt[0], nanoflann::SearchParams(10));
std::cout << "knnSearch(nn="<<num_results<<"): \n";
std::cout << "ret_index=" << ret_index << " out_dist_sqr=" << out_dist_sqr << endl;
return ret_index;
}
typedef KDTreeSingleIndexAdaptor<
L2_Simple_Adaptor<double , PointCloud > ,
PointCloud,
3 /* dim */
> my_kd_tree;
std::shared_ptr<my_kd_tree> index = nullptr;
};
The problem is that the following code raises segfault:
int main()
{
srand(static_cast<unsigned int>(time(nullptr)));
Points points{{1, 5, 8}, {3, 3, 3}, {1, 1, 0}};
KdTree tree(points);
tree.GetNearest({1, 1, 1});
return 0;
}
But if I put GetNearest code in constructor (so that I construct index and find pt's neighbor in constructor itself), or just write constructor and GetNearest code in main, then everything works just fine.
I am new to nanoflann, can't figure what's wrong. Thanks for the help in advance!
I had to dig into the source nanoflann.hpp to find that the second parameter to the constructor for KDTreeSingleIndexAdaptor (cloud in your KdTree constructor) is passed by reference and stored as a reference. This means that the cloud data you pass to nanoflann needs to stay around until you delete the KDTreeSingleIndexAdaptor object.
Because you declare PointCloud cloud as a local variable within your KdTree constructor, it will be destroyed when the constructor ends leaving the kdtree pointed to by index with an dangling internal reference.
One solution is to make cloud a member of KdTree.
Given a vector, how to find all subsets of the vector accompanied by the original indices from the vector?
For example given the vector,
vector<float> numbers {1.3, 0.5, 2.4};
get subsets:
{}, {1.3}, {0.5}, {2.4}, {1.3, 2.4}, {0.5, 2.4}, {1.3, 0.5}, {1.3, 0.5, 2.4}
and corresponding indices for each subset:
{}, {0}, {1}, {2}, {0, 2}, {1, 2}, {0, 1}, {0, 1, 2}.
Is this a homework assignment? :-P
The following function will generate index subsets. The indices argument is just a temporary scratch variables.
void getIndexSubsets(
int l, int u, std::vector<int>* indices,
std::vector<std::vector<int>>* result) {
if (l == u) {
result->push_back(*indices);
} else {
int next = l + 1;
getIndexSubsets(next, u, indices, result);
indices->push_back(l);
getIndexSubsets(next, u, indices, result);
indices->pop_back();
}
}
It is used like this:
std::vector<float> numbers{1.3, 0.5, 2.4};
std::vector<int> indices;
std::vector<std::vector<int>> indexResult;
getIndexSubsets(0, numbers.size(), &indices, &indexResult);
The index subsets will be output in indexResult. Given the index subsets, we can compute the value subsets using this function:
std::vector<std::vector<float>> getValueSubsets(
const std::vector<float>& srcValues,
const std::vector<std::vector<int>>& src) {
std::vector<std::vector<float>> dst;
for (const auto& inds: src) {
std::vector<float> x;
for (auto i: inds) {
x.push_back(srcValues[i]);
}
dst.push_back(x);
}
return dst;
}
Invoking it like this:
std::vector<std::vector<float>> valueResult = getValueSubsets(numbers, indexResult);
The full solution reads like this.
#include <iostream>
#include <vector>
void getIndexSubsets(
int l, int u, std::vector<int>* indices,
std::vector<std::vector<int>>* result) {
if (l == u) {
result->push_back(*indices);
} else {
int next = l + 1;
getIndexSubsets(next, u, indices, result);
indices->push_back(l);
getIndexSubsets(next, u, indices, result);
indices->pop_back();
}
}
std::vector<std::vector<float>> getValueSubsets(
const std::vector<float>& srcValues,
const std::vector<std::vector<int>>& src) {
std::vector<std::vector<float>> dst;
for (const auto& inds: src) {
std::vector<float> x;
for (auto i: inds) {
x.push_back(srcValues[i]);
}
dst.push_back(x);
}
return dst;
}
template <typename T>
std::ostream& operator<<(std::ostream& s, const std::vector<T>& src) {
s << "{";
bool f = true;
for (auto x: src) {
s << (f? "" : " ") << x;
f = false;
}
s << "}";
return s;
}
int main() {
std::vector<float> numbers{1.3, 0.5, 2.4};
std::vector<int> indices;
std::vector<std::vector<int>> indexResult;
getIndexSubsets(0, numbers.size(), &indices, &indexResult);
std::vector<std::vector<float>> valueResult = getValueSubsets(numbers, indexResult);
for (int i = 0; i < indexResult.size(); i++) {
std::cout << "Subset inds=" << indexResult[i] << " values=" << valueResult[i] << std::endl;
}
return 0;
}
When executed, it will output this:
Subset inds={} values={}
Subset inds={2} values={2.4}
Subset inds={1} values={0.5}
Subset inds={1 2} values={0.5 2.4}
Subset inds={0} values={1.3}
Subset inds={0 2} values={1.3 2.4}
Subset inds={0 1} values={1.3 0.5}
Subset inds={0 1 2} values={1.3 0.5 2.4}
Below is the code I use to compute the intersection of two polyhedra with cgal. I know it's big but I did the best I could to minimize.
This code works for one example, but for the example included below, it crashes. The compilation runs fine but when I run the executable it crashes. When I run it from Haskell I get the error message "Access violation in generated code when reading xxx" (where xxx is an address).
The program firstly builds two polyhedra P1 and P2. There's no problem at this step. Then the problem occurs when the program reaches this line:
Nef_polyhedron nef1(P1);
I would appreciate any help to figure out what happens.
#include <vector>
#include <fstream>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polyhedron_incremental_builder_3.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
typedef Polyhedron::HalfedgeDS HalfedgeDS;
typedef CGAL::Surface_mesh<Kernel::Point_3> Surface_mesh;
typedef CGAL::Nef_polyhedron_3<Kernel, CGAL::SNC_indexed_items> Nef_polyhedron;
// helper functions to convert arrays to vectors
std::vector<int> iarray2vector(int* array, size_t n){
std::vector<int> out;
for(size_t i=0; i<n; i++){
out.push_back(array[i]);
}
return out;
}
std::vector<double> darray2vector(double* array, size_t n){
std::vector<double> out;
for(size_t i=0; i<n; i++){
out.push_back(array[i]);
}
return out;
}
// A modifier creating a polyhedron with the incremental builder.
class polyhedron_builder : public CGAL::Modifier_base<HalfedgeDS> {
public:
std::vector<double> &coords;
std::vector<int> &faces;
std::vector<int> &facesizes;
polyhedron_builder(
std::vector<double> &_coords,
std::vector<int> &_faces,
std::vector<int> &_facesizes
) : coords(_coords), faces(_faces), facesizes(_facesizes) {}
void operator()( HalfedgeDS& hds) {
typedef typename HalfedgeDS::Vertex Vertex;
typedef typename Vertex::Point Point;
/* create a cgal incremental builder */
CGAL::Polyhedron_incremental_builder_3<HalfedgeDS> B( hds, true);
B.begin_surface( coords.size()/3, faces.size());
/* add the polyhedron vertices */
for(int i=0; i<(int)coords.size(); i+=3){
B.add_vertex( Point( coords[i+0], coords[i+1], coords[i+2] ) );
}
/* add the polyhedron faces */
int i=0;
for(int k=0; k<(int)facesizes.size(); k++){
int fs = facesizes[k];
B.begin_facet();
for(int j=0; j<fs; j++){
B.add_vertex_to_facet( faces[i+j] );
}
B.end_facet();
i += fs;
}
/* finish up the surface */
B.end_surface();
}
};
Polyhedron buildPolyhedron(
double* vertices,
size_t nvertices,
int* faces,
int* facesizes,
size_t nfaces)
{
/* calculate length of `faces`*/
size_t l = 0;
for(size_t i=0; i < nfaces; i++){
l += facesizes[i];
}
/* make vectors from arrays */
std::vector<double> vs = darray2vector(vertices, 3*nvertices);
std::vector<int> fs = iarray2vector(faces, l);
std::vector<int> fzs = iarray2vector(facesizes, nfaces);
/* build the polyhedron */
Polyhedron P;
polyhedron_builder builder(vs, fs, fzs);
P.delegate( builder );
/**/
return P;
}
void intersectPolyhedra(Polyhedron P1, Polyhedron P2){
/* convert polyhedra to nefs */
printf("make nef1\n");
Nef_polyhedron nef1(P1);
printf("make nef2\n");
Nef_polyhedron nef2(P2);
/* compute the intersection */
printf("make nefs intersection\n");
Nef_polyhedron nef = nef1*nef2;
/* surface mesh */
Surface_mesh smesh;
CGAL::convert_nef_polyhedron_to_polygon_mesh(nef, smesh);
/* write OFF file */
std::ofstream outfile;
outfile.open("intersection.off");
outfile << smesh;
outfile.close();
}
void intersectionTwoPolyhedra(
double* vertices1,
size_t nvertices1,
int* faces1,
int* facesizes1,
size_t nfaces1,
double* vertices2,
size_t nvertices2,
int* faces2,
int* facesizes2,
size_t nfaces2)
{
printf("build P1\n");
Polyhedron P1 = buildPolyhedron(vertices1, nvertices1, faces1, facesizes1, nfaces1);
printf("P1 is closed: %u\n", P1.is_closed());
std::cout << P1;
printf("build P2\n");
Polyhedron P2 = buildPolyhedron(vertices2, nvertices2, faces2, facesizes2, nfaces2);
printf("P2 is closed: %u\n", P2.is_closed());
std::cout << P2;
printf("run intersection\n");
intersectPolyhedra(P1, P2);
}
int main(){
double x = (1 + sqrt(5))/2;
double y = x - 1;
double vertices[60] = { -1, 1, 1,
0, y, x,
y, x, 0,
-y, x, 0,
0, y, -x,
0, -y, x,
1, -1, 1,
x, 0, y,
1, 1, 1,
1, 1, -1,
x, 0, -y,
y, -x, 0,
1, -1, -1,
-1, -1, 1,
-x, 0, y,
-1, 1, -1,
-x, 0, -y,
-1, -1, -1,
-y, -x, 0,
0, -y, -x };
int faces1[24] = { 3,1,7,9,
1,3,16,13,
9,19,16,3,
16,19,11,13,
1,13,11,7,
9,7,11,19 };
int faces2[24] = { 2,4,16,0,
2,7,12,4,
2,0,5,7,
4,12,18,16,
0,16,18,5,
7,5,18,12 };
int facesizes[6] = { 4, 4, 4, 4, 4, 4};
intersectionTwoPolyhedra(
vertices,
20,
faces1,
facesizes,
6,
vertices,
20,
faces2,
facesizes,
6
);
return 0;
}
Both calls P1.is_valid() and P2.is_valid() return false. So it seems your input polyhedra are not valid.
I suggest that you try to use the more user friendly polygon_soup_to_polygon_mesh() function to create your polyhedra.
Also you might want to use directly Surface_mesh and the Boolean operations available in the polygon mesh processing package. See here.
I need to solve some quadratic programs using CGAL by specifying the problem through iterators. Below is a dummy example which runs fine (problem is infeasible). The problem is when I change the constraints to be ">=":
std::array<CGAL::Comparison_result, numAConstraints> relationships
= { CGAL::LARGER,CGAL::LARGER,CGAL::LARGER,CGAL::LARGER, };
Then I get:
"basis-inverse check: failed (row=0 | col=1)" from qp_solver_imp.h line 1155.
This is the sample code that runs without crashing, all constraints are "<=":
#include "stdafx.h"
#include <array>
#include <iterator>
#include <vector>
#include <CGAL/basic.h>
#include <CGAL/QP_models.h>
#include <CGAL/QP_functions.h>
#include <CGAL/MP_Float.h>
typedef double ET;
int main(){
const int numAConstraints = 4;
const int numVariables = 3;
typedef CGAL::Quadratic_program_from_iterators
<double**, // for A
double*, // for b
std::array<CGAL::Comparison_result, numAConstraints>::const_iterator, // for r
bool*, // for fl
double*, // for l
bool*, // for fu
double*, // for u
double**, // for D
double*> // for c
Program;
typedef CGAL::Quadratic_program_solution<ET> Solution;
double Ax[] = { 1, -1, -1, 1 }; // column for x
double Ay[] = { -2, -2, 2, -1 };
double Az[] = { 1, 0.0, -5, 5 };
double* A[] = { Ax, Ay, Az }; // A comes columnwise
double b[] = { -2.4, -6, -2, 1.0 }; // right-hand side
std::array<CGAL::Comparison_result, numAConstraints> relationships
= { CGAL::SMALLER,CGAL::SMALLER,CGAL::SMALLER, CGAL::SMALLER };
bool fl[] = { true, true, true }; // both x, y are lower-bounded
double l[] = { 0, 0, 0 };
bool fu[] = { false, false, false }; // only y is upper-bounded
double u[] = { 0, 0, 0 }; // x's u-entry is ignored
double D1[] = { 1 }; // 2D_{1,1}
double D2[] = { 0, 0.1 };
double D3[] = { 10, 0.0, 100.0 };
double* D[] = { D1, D2, D3 }; // D-entries on/below diagonal ROWISE
double c[] = { -200, -5, -25 };
double c0 = 64;
Program qp(numVariables, numAConstraints, A, b, relationships.begin(), fl, l, fu, u, D, c, c0);
// solve the program, using ET as the exact type
Solution s = CGAL::solve_quadratic_program(qp, ET());
std::cout << s;
return 0;
}