Skip to content

Commit 01865a2

Browse files
committed
move unused header file to archive
1 parent 6f122cf commit 01865a2

File tree

4 files changed

+140
-142
lines changed

4 files changed

+140
-142
lines changed

Filtered_kernel/TODO

Lines changed: 140 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
[See also the file TODO_static_filters]
2-
31
Concerning the main code:
42
-------------------------
53
- Policy for overlapping comparisons : another good (faster) solution
@@ -70,3 +68,143 @@ Concerning the test-suite:
7068
The script could output information to test them generically somehow.
7169
- Test NaN propagation. Comparisons with these should throw the exception...
7270
Check that they are correctly propagated (by min(), max(), even operator*...)
71+
72+
Special TODO list for the static filters.
73+
-----------------------------------------
74+
It's a lot of work here for a "minor" optimization, so it's "low" priority,
75+
except we could merge stuff with Olivier's Fixed !
76+
77+
- Known problems with the current approach:
78+
- Match operator<(a,b) and co...
79+
- What to do with branches (e.g. collinearC3() and power_test()):
80+
- The epsilon computation type should return ZERO/EQUAL as default.
81+
This way, collinearC3() works.
82+
- The user can provide the epsilon variant inside the source code,
83+
delimited by special symbols /*CGAL_FILTER_BODY ... */. That's the
84+
solution for CGAL.
85+
- Checks that the epsilons have been updated (which will not prove that
86+
it's correct, but is better than nothing).
87+
- Or use G++'s interface as a parser ? See gcc mail archives, 15 august 2000,
88+
"XML output for GCC". An XML description for predicates ?
89+
- /*DEGREE=2*/ attribute to the arguments ?
90+
- # of bounds : one per predicate, or one per argument ? give choice.
91+
- # of epsilons: one per predicate, or one set per sub-predicate ? choice.
92+
- Check that the compiler optimizes the epsilon computation (use
93+
__attribute__((const)) for Static_filter_error operators) ?
94+
- As Fred pointed out: the scheme is not thread safe.
95+
- Remove the assertions in the original code.
96+
- In case there are loops, we must take the max() of the epsilons. This should
97+
not happen often, imho... Wait and see.
98+
- Move static_infos in src/.
99+
- Replace: NEW_bound = max(NEW_bound, fabs(px.to_double())); by: if (NEW_bound
100+
< fabs(px.to_double())) NEW_bound = fabs(px.to_double()); or even, using a
101+
.bound() member function: if (NEW_bound < px.bound()) NEW_bound = px.bound();
102+
Moreover, to_double() is not exact, we should use abs(to_interval(x)).sup() !
103+
- Member function access for generic type should be (?): .dbl_approx()
104+
.bound() (basically a bound on: fabs(.dbl_approx())) .error()
105+
- Add a "number of bits" field in Static_filter_error ? (so that we get the
106+
same thing as Fixed for 24 bits)
107+
108+
- Another approach to consider : Implement predicates taking one or several
109+
epsilons as additional parameters, and have the functionality found in Open
110+
CasCade, using sign(a, epsilon). Then with a special traits or something,
111+
we can define sign(a,epsilon) = sign(a), and get the traditionnal template
112+
predicates from that... So that the epsilons are removed at compile time ?
113+
It would be nice to know exactly the desired functionality for epsilons...
114+
115+
- Where to put the context of the predicates ? different possibilities :
116+
1- static data member of the predicate object (~as it is now)
117+
2- data member of the predicate object
118+
3- static data member of the kernel
119+
4- data member of the kernel
120+
5- global data
121+
122+
Things to take into account :
123+
- I want to be able to initialize the bounds externally.
124+
This can't be done if we choose 2-.
125+
- I want to be able to have different contexts depending where I use the
126+
predicate, this can't be done with 5- nor 3- nor 1-.
127+
- If I add a failure_counter, it should be at the same place as the context,
128+
and I should be able to access it from the outside. If we do that like
129+
triangulation, treating geom_traits as a data member of triangulatino, then
130+
it's ok.
131+
- So it remains 2 possibilities :
132+
a- data member of the predicate object.
133+
b- data member of the kernel.
134+
135+
So 1-, 3-, 5- are out since we can't have different contexts.
136+
2- and 4- are basically equivalent if we can access the context of an object
137+
via the kernel object (_gt in triangulation). So, Orientation_2_object(),
138+
for this particular kernel, would return a const ref to a data member of the
139+
kernel...
140+
So the good choice seems to be to have data stored in each predicate object,
141+
and having the kernel store a predicate object for each predicate.
142+
Then the orientation_2_object() simply returns a reference to it.
143+
144+
Then it means algorithms should use one "global" object per predicate (e.g.
145+
one orientation object for a whole Triangulation). Except for cases where
146+
they actually want different contexts.
147+
148+
// Additional kernel for storage type ?
149+
template <class SK, class EK, class IK = Cartesian<Interval_nt> >
150+
class Filtered_Point_2
151+
{
152+
const CK::Point_2 storage;
153+
154+
// IK cached ? It doesn't make sense to do it lazily because it's going to
155+
// be used. BUT, what is worth is the case when the storage number type is
156+
// like a double : in this case, no approximation needs to be stored.
157+
158+
IK::Point_2 app;
159+
const IK::Point_2 & approx() { return app; }
160+
161+
#if No_cache_EK // via a traits parameter ? Have a generic caching mechanism ?
162+
EK::Point_2 exact() { return EK::Point_2(storage); }
163+
#else
164+
EK::Point_2 ex;
165+
const EK::Point_2 & exact { return ex; }
166+
#endif
167+
};
168+
169+
// For filtered constructions, we should be able to re-use the same predicates,
170+
// but have different constructions and objects Point_2...
171+
template <class EK, class IK = Cartesian<Interval> >
172+
class Filtered_kernel
173+
{
174+
public:
175+
176+
Filtered_kernel()
177+
: ik(), ek(),
178+
orientation_2_obj(ik.orientation_2_object(), ek.orientation_2_object())
179+
// ...
180+
{}
181+
182+
typedef CGAL::Filtered_Point_2<...> Point_2;
183+
// ...
184+
185+
typedef CGAL::Filtered_p_Orientation<IK, EK> Orientation_2;
186+
Orientation_2 orientation_2_obj;
187+
const Orientation_2 & orientation_2_object() const
188+
{ return orientation_2_obj; }
189+
190+
const IK & get_ik() const { return ik; }
191+
const EK & get_ek() const { return ek; }
192+
193+
private:
194+
195+
EK ek;
196+
IK ik;
197+
};
198+
199+
Then you use this thing as a kernel :
200+
Filtered_kernel<Cartesian<leda_real> >
201+
eventually adding profiling template parameters...
202+
Just like we have at the NT level : Lazy_exact_nt<leda_real>.
203+
204+
Maybe have a unique (Cartesian) kernel that includes filtering and caching
205+
capabilities which are toggleable by a simple traits ? The predicate objects
206+
would include the (currently so-called) update_epsilon() member functions...
207+
Or probably better, a filtering wrapper that can be used by homogeneous as
208+
well...
209+
210+

Filtered_kernel/TODO_static_filters

Lines changed: 0 additions & 138 deletions
This file was deleted.
File renamed without changes.

Filtered_kernel/dont_submit

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)