Floating-point precision selection in CGAL - cgal

I wonder that whether there is a way for me to select floating-point bit-width used in CGAL.
For example, the following code is just a convex hull example directly copied from CGAL manual:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/convex_hull_2.h>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;
typedef std::vector<Point_2> Points;
int main()
{
Points points, result;
points.push_back(Point_2(0,0));
points.push_back(Point_2(10,0));
points.push_back(Point_2(10,10));
points.push_back(Point_2(6,5));
points.push_back(Point_2(4,1));
CGAL::convex_hull_2( points.begin(), points.end(), std::back_inserter(result) );
std::cout << result.size() << " points on the convex hull" << std::endl;
return 0;
}
However, I cannot choose that the coordinates of points are stored in 32 or 64 bit floating-point numbers.
I also wish to choose that the convex hull is computed under 32 or 64 bit arithmetic.
(And, yes, I am willing to take the risk of high round-off error.)
Is there anyway to select floating-point precision either in runtime or compile-time?

You can look at the file Exact_predicates_inexact_constructions_kernel.h
and adapt it to create your own exact predicates inexact constructions but storing numbers in float

Related

CGAL: problem accessing the neighbors of every vertex using edge iterator in periodic triangulation

I am using periodic Delaunay triangulation in CGAL in my code, and producing for each vertex all neighboring vertices. For this I use Edge iterator, since in my case it will be much more faster than Vertex iterator.
Here is the code snippet,
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Periodic_2_triangulation_traits_2<Kernel> Gt;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned int, Gt> Vb;
typedef CGAL::Periodic_2_triangulation_face_base_2<Gt> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
typedef CGAL::Periodic_2_Delaunay_triangulation_2<Gt, Tds> Triangulation;
typedef Triangulation::Iso_rectangle Iso_rectangle;
typedef Triangulation::Edge_iterator Edge_iterator;
typedef Triangulation::Vertex_handle Vertex_handle;
typedef Triangulation::Point Point;
typedef vector<pair<Point, unsigned> > Vector_Paired;
Vector_Paired points;
Iso_rectangle domain(0,0,L,L);
for(int iat = 0; iat < N; iat++)
{
points.push_back(make_pair(Point(r_tot[iat][0],r_tot[iat][1]),iat));
}
Triangulation T(points.begin(), points.end(), domain);
for(Edge_iterator ei=T.finite_edges_begin(); ei!=T.finite_edges_end(); ei++)
{
Triangulation::Face& f = *(ei->first);
int ii = ei->second;
Vertex_handle vi = f.vertex(f.cw(ii));
Vertex_handle vj = f.vertex(f.ccw(ii));
int iat = vi->info();
int jat = vj->info();
VecInd[iat].push_back(jat);
VecInd[jat].push_back(iat);
}
But, sometimes instead of one special neighbors for each vertex I get 8 or 9 or ... copy of the same neighbor.
For example in VecInd which is a 2D vector containing neighboring indices I get some thing like this:
VecInd[0]=[2,2,2,2,4,4,4,...]
I couldn't find an example using edge iterator in CGAL website, and nothing related in stackoverflow.
I am wondering whether this implementation is correct? What should I add to my code in order to get one copy per each neighbor, I can use STL::sets, but I would like to know the source of problem.
Here is the answer that was posted on the CGAL-discuss mailing-list, by Mael:
If your point set is not geometrically well spaced, it's possible that the triangulation of these points do not form a simplicial complex over the flat torus (in other words, there are short cycles in the triangulation). In this case, the algorithm uses 8 copies of the triangulation to artificially create a simplicial complex. You can check if this is the case using the function is_triangulation_in_1_sheet() and read more about these mechanisms in the User Manual.
When copies are being used, iterating over the edges will indeed give you exactly what the underlying data structure has : 9 entities for each edge. To get unique ones, you can simply filter 8 out of the 9 by looking at the offset of the vertices of the edge. This is what is done in the iterator that returns unique periodic segments. Unfortunately, you want edges and this iterator converts directly to the geometry of the edge (the segment). Nevertheless, you can simply use the main filtering function from that iterator, that is: is_canonical(). This function will look at the offset of the two vertices of your edges, and keep only those that have at least one vertex in the first copy of the domain, which is enough to make it unique.

CGAL: Delaunay triangulation vs triangulation in CGAL's example

In my work, I need to obtain first shell of Voronoi neighbors for a focal particle. For this I use Delaunay triangulation which is the dual graph of Voronoi tessellation. The Version of CGAL which I use is 4.7. I always used the basic code in CGAL manual_4.7 as a template to create Delaunay triangulation. My problem is with the headers and typedefs in that example, because I recently discovered they are different from CGAL 4.14 which is the latest version available. In CGAL 4.7:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Periodic_2_Delaunay_triangulation_2.h>
#include <CGAL/Periodic_2_triangulation_traits_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Periodic_2_triangulation_traits_2<K> Gt;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned, Gt> Vb;
typedef CGAL::Periodic_2_triangulation_face_base_2<Gt> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
typedef CGAL::Periodic_2_Delaunay_triangulation_2<Gt, Tds> Delaunay;
typedef Delaunay::Point Point;
and in CGAL 4.14:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Periodic_2_Delaunay_triangulation_2.h>
#include <CGAL/Periodic_2_Delaunay_triangulation_traits_2.h>
#include <CGAL/Periodic_2_triangulation_face_base_2.h>
#include <CGAL/Periodic_2_triangulation_vertex_base_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <iostream>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Periodic_2_Delaunay_triangulation_traits_2<K> Gt;
typedef CGAL::Periodic_2_triangulation_vertex_base_2<Gt> Vbb;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned, Gt, Vbb> Vb;
typedef CGAL::Periodic_2_triangulation_face_base_2<Gt> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
typedef CGAL::Periodic_2_Delaunay_triangulation_2<Gt, Tds> Delaunay;
typedef Delaunay::Point Point;
then I double checked the manual to see if the explantions are different or not. As far as I understand, Software Design 4.14 and Software Design 4.7 are the same and match to second example. Since I need triangulation with empty circle property, and I just need to retrieve the indices of neighboring vertices in Delaunay triangulation, does the first also lead to the same results?
I can check them for some points, but I just doubt that if they produce the same results for every set of points?
This leads to exactly the same results.
For a more detailed explanation: the periodic triangulation expects a triangulation data structure with vertices and faces that provide a certain number of functions and members, described by concepts (see P2T2 concepts). In CGAL 4.7, the vertex and face classes did not meet these requirements: they were missing some periodic information that is only used in a few functions of P2T2. However everything compiled and ran just fine because the examples did not call these few functions. Some more recent compilers were over-zealous and decided they wanted to be able to compile all functions of the class, even if those that were not called, and thus the vertex and base classes that were being used were not satisfying anymore.
See also https://github.com/CGAL/cgal/pull/3624.

CGAL static AABB tree to intersect many spheres with rays

I would like to use CGAL's AABB Tree to compute intersection between many static spheres and rays. I am fairly new to CGAL and might need some guidance.
As there does not seem to be direct support for spheres in the AABB tree, I think need to complement the functionality by creating AABB_sphere_primitive. Is that the only thing that is needed to get something like AABB_tree/AABB_triangle_3_example.cpp, with spheres instead of triangles? Do I need to also define an analogue of Point_from_triangle_3_iterator_property_map?
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;
typedef K::Point_3 Point;
typedef K::Plane_3 Plane;
typedef K::Sphere_3 Sphere; // <-- this is done already
typedef std::list<Sphere>::iterator Iterator;
typedef CGAL::AABB_sphere_primitive<K,Iterator> Primitive; // <---- must be defined newly
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Tree;
The routine for intersection between sphere and ray is already implemented somewhere (Spherical_kernel_intersections.h?) and will be used?
Thanks for pointers.
You need to provide a new primitive type that is a model of the concept AABBPrimitive. Basically you can copy/paste the implementation of CGAL::AABB_triangle_primitive and adapt it to the case of a sphere.
The next tricky part is to provide the intersection predicate for a ray and a sphere as required by the AABBTraits concept.
If you are not looking for exact predicates, you can simply using the distance of the center of the sphere to the support line of the ray + the direction of the center of the sphere with reference to the source of the ray.
If you want exact predicates, the class Filtered_predicate can help you make your predicate robust.

CGFloat: round, floor, abs, and 32/64 bit precision

TLDR: How do I call standard floating point code in a way that compiles both 32 and 64 bit CGFloats without warnings?
CGFloat is defined as either double or float, depending on the compiler settings and platform. I'm trying to write code that works well in both situations, without generating a lot of warnings.
When I use functions like floor, abs, ceil, and other simple floating point operations, I get warnings about values being truncated. For example:
warning: implicit conversion shortens 64-bit value into a 32-bit value
I'm not concerned about correctness or loss of precision in of calculations, as I realize that I could just use the double precision versions of all functions all of the time (floor instead of floorf, etc); however, I would have to tolerate these errors.
Is there a way to write code cleanly that supports both 32 bit and 64 bit floats without having to either use a lot of #ifdef __ LP64 __ 's, or write wrapper functions for all of the standard floating point functions?
You may use those functions from tgmath.h.
#include <tgmath.h>
...
double d = 1.5;
double e = floor(d); // will choose the 64-bit version of 'floor'
float f = 1.5f;
float g = floor(f); // will choose the 32-bit version of 'floorf'.
If you only need a few functions you can use this instead:
#if CGFLOAT_IS_DOUBLE
#define roundCGFloat(x) round(x)
#define floorCGFloat(x) floor(x)
#define ceilCGFloat(x) ceil(x)
#else
#define roundCGFloat(x) roundf(x)
#define floorCGFloat(x) floorf(x)
#define ceilCGFloat(x) ceilf(x)
#endif

gcc memory alignment pragma

Does gcc have memory alignment pragma, akin #pragma vector aligned in Intel compiler?
I would like to tell compiler to optimize particular loop using aligned loads/store instructions. to avoid possible confusion, this is not about struct packing.
e.g:
#if defined (__INTEL_COMPILER)
#pragma vector aligned
#endif
for (int a = 0; a < int(N); ++a) {
q10 += Ix(a,0,0)*Iy(a,1,1)*Iz(a,0,0);
q11 += Ix(a,0,0)*Iy(a,0,1)*Iz(a,1,0);
q12 += Ix(a,0,0)*Iy(a,0,0)*Iz(a,0,1);
q13 += Ix(a,1,0)*Iy(a,0,0)*Iz(a,0,1);
q14 += Ix(a,0,0)*Iy(a,1,0)*Iz(a,0,1);
q15 += Ix(a,0,0)*Iy(a,0,0)*Iz(a,1,1);
}
Thanks
You can tell GCC that a pointer points to aligned memory by using a typedef to create an over-aligned type that you can declare pointers to.
This helps gcc but not clang7.0 or ICC19, see the x86-64 non-AVX asm they emit on Godbolt. (Only GCC folds a load into a memory operand for mulps, instead of using a separate movups). You have have to use __builtin_assume_aligned if you want to portably convey an alignment promise to GNU C compilers other than GCC itself.
From http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
typedef double aligned_double __attribute__((aligned (16)));
// Note: sizeof(aligned_double) is 8, not 16
void some_function(aligned_double *x, aligned_double *y, int n)
{
for (int i = 0; i < n; ++i) {
// math!
}
}
This won't make aligned_double 16 bytes wide. This will just make it aligned to a 16-byte boundary, or rather the first one in an array will be. Looking at the disassembly on my computer, as soon as I use the alignment directive, I start to see a LOT of vector ops. I am using a Power architecture computer at the moment so it's altivec code, but I think this does what you want.
(Note: I wasn't using double when I tested this, because there altivec doesn't support double floats.)
You can see some other examples of autovectorization using the type attributes here: http://gcc.gnu.org/projects/tree-ssa/vectorization.html
I tried your solution with g++ version 4.5.2 (both Ubuntu and Windows) and it did not vectorize the loop.
If the alignment attribute is removed then it vectorizes the loop, using unaligned loads.
If the function is inlined so that the array can be accessed directly with the pointer eliminated, then it is vectorized with aligned loads.
In both cases, the alignment attribute prevents vectorization. This is ironic: The "aligned_double *x" was supposed to enable vectorization but it does the opposite.
Which compiler was it that reported vectorized loops for you? I suspect it was not a gcc compiler?
Does gcc have memory alignment pragma, akin #pragma vector aligned
It looks like newer versions of GCC have __builtin_assume_aligned:
Built-in Function: void * __builtin_assume_aligned (const void *exp, size_t align, ...)
This function returns its first argument, and allows the compiler to assume that the returned pointer is at least align bytes aligned.
This built-in can have either two or three arguments, if it has three,
the third argument should have integer type, and if it is nonzero
means misalignment offset. For example:
void *x = __builtin_assume_aligned (arg, 16);
means that the compiler can assume x, set to arg, is at least 16-byte aligned, while:
void *x = __builtin_assume_aligned (arg, 32, 8);
means that the compiler can assume for x, set to arg, that (char *) x - 8 is 32-byte aligned.
Based on some other questions and answers on Stack Overflow circa 2010, it appears the built-in was not available in GCC 3 and early GCC 4. But I do not know where the cut-off point is.