DGtal  1.4.beta
VoronoiCovarianceMeasure.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file VoronoiCovarianceMeasure.ih
19  * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20  * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
21  *
22  * @date 2014/02/09
23  *
24  * Implementation of inline methods defined in VoronoiCovarianceMeasure.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 
30 //////////////////////////////////////////////////////////////////////////////
31 #include <cstdlib>
32 //////////////////////////////////////////////////////////////////////////////
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // ----------------------- Standard services ------------------------------
40 
41 //-----------------------------------------------------------------------------
42 template <typename TSpace, typename TSeparableMetric>
43 inline
44 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
45 ~VoronoiCovarianceMeasure()
46 {
47  clean();
48 }
49 //-----------------------------------------------------------------------------
50 template <typename TSpace, typename TSeparableMetric>
51 inline
52 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
53 VoronoiCovarianceMeasure( double _R, double _r, Metric aMetric, bool verbose )
54  : myBigR( _R ), myMetric( aMetric ), myVerbose( verbose ),
55  myDomain( Point::diagonal(0), Point::diagonal(0) ), // dummy domain
56  myCharSet( 0 ),
57  myVoronoi( 0 ),
58  myProximityStructure( 0 )
59 {
60  mySmallR = (_r >= 2.0) ? _r : 2.0;
61 }
62 //-----------------------------------------------------------------------------
63 template <typename TSpace, typename TSeparableMetric>
64 inline
65 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
66 VoronoiCovarianceMeasure( const VoronoiCovarianceMeasure& other )
67  : myBigR( other.myBigR ), mySmallR( other.mySmallR ),
68  myMetric( other.myMetric ), myVerbose( other.myVerbose ),
69  myDomain( other.myDomain )
70 {
71  if ( other.myCharSet ) myCharSet = new CharacteristicSet( *other.myCharSet );
72  else myCharSet = 0;
73  if ( other.myVoronoi ) myVoronoi = new Voronoi( *other.myVoronoi );
74  else myVoronoi = 0;
75  if ( other.myProximityStructure )
76  myProximityStructure = new ProximityStructure( *other.myVoronoi );
77  else myProximityStructure = 0;
78 }
79 //-----------------------------------------------------------------------------
80 template <typename TSpace, typename TSeparableMetric>
81 inline
82 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>&
83 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
84 operator=( const VoronoiCovarianceMeasure& other )
85 {
86  if ( this != &other )
87  {
88  myBigR = other.myBigR;
89  mySmallR = other.mySmallR;
90  myMetric = other.myMetric;
91  myVerbose = other.myVerbose;
92  myDomain = other.myDomain;
93  clean();
94  if ( other.myCharSet ) myCharSet = new CharacteristicSet( *other.myCharSet );
95  if ( other.myVoronoi ) myVoronoi = new Voronoi( *other.myVoronoi );
96  if ( other.myProximityStructure )
97  myProximityStructure = new ProximityStructure( *other.myVoronoi );
98  }
99  return *this;
100 }
101 //-----------------------------------------------------------------------------
102 template <typename TSpace, typename TSeparableMetric>
103 inline
104 typename DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::Scalar
105 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
106 R() const
107 {
108  return myBigR;
109 }
110 //-----------------------------------------------------------------------------
111 template <typename TSpace, typename TSeparableMetric>
112 inline
113 typename DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::Scalar
114 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
115 r() const
116 {
117  return mySmallR;
118 }
119 //-----------------------------------------------------------------------------
120 template <typename TSpace, typename TSeparableMetric>
121 inline
122 void
123 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
124 clean()
125 {
126  if ( myCharSet ) { delete myCharSet; myCharSet = 0; }
127  if ( myVoronoi ) { delete myVoronoi; myVoronoi = 0; }
128  if ( myProximityStructure )
129  { delete myProximityStructure; myProximityStructure = 0; }
130 }
131 
132 //-----------------------------------------------------------------------------
133 template <typename TSpace, typename TSeparableMetric>
134 inline
135 const typename DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::Domain&
136 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
137 domain() const
138 {
139  return myDomain;
140 }
141 //-----------------------------------------------------------------------------
142 template <typename TSpace, typename TSeparableMetric>
143 inline
144 const typename DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::Voronoi&
145 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
146 voronoiMap() const
147 {
148  ASSERT( myVoronoi != 0 );
149  return *myVoronoi;
150 }
151 
152 //-----------------------------------------------------------------------------
153 template <typename TSpace, typename TSeparableMetric>
154 template <typename PointInputIterator>
155 inline
156 void
157 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
158 init( PointInputIterator itb, PointInputIterator ite )
159 {
160  BOOST_CONCEPT_ASSERT(( boost::InputIterator< PointInputIterator > ));
161  // PointInputIterator must be an iterator on points.
162  BOOST_STATIC_ASSERT ((boost::is_same< Point, typename PointInputIterator::value_type >::value ));
163  ASSERT( itb != ite );
164 
165  // Cleaning stuff.
166  clean();
167  myVCM.clear();
168 
169  // Start computations
170  if ( myVerbose ) trace.beginBlock( "Computing Voronoi Covariance Measure." );
171 
172  // First pass to get domain.
173  if ( myVerbose ) trace.beginBlock( "Determining computation domain." );
174  Point lower = *itb;
175  Point upper = *itb;
176  Size nbPts = 0;
177  MatrixNN matrixZero;
178  for ( PointInputIterator it = itb; it != ite; ++it, ++nbPts )
179  {
180  Point p = *it;
181  lower = lower.inf( p );
182  upper = upper.sup( p );
183  myVCM[ p ] = matrixZero;
184  }
185  Integer intR = (Integer) ceil( myBigR );
186  lower -= Point::diagonal( intR );
187  upper += Point::diagonal( intR );
188  myDomain = Domain( lower, upper );
189  if ( myVerbose ) trace.endBlock();
190 
191  // Second pass to compute characteristic set.
192  if ( myVerbose ) trace.beginBlock( "Computing characteristic set and building proximity structure." );
193  myCharSet = new CharacteristicSet( myDomain );
194  myProximityStructure = new ProximityStructure( lower, upper, (Integer) ceil( mySmallR ) );
195  for ( ; itb != ite; ++itb )
196  {
197  Point p = *itb;
198  myCharSet->setValue( p, true );
199  myProximityStructure->push( p );
200  }
201  if ( myVerbose ) trace.endBlock();
202 
203  // Third pass to compute voronoi map.
204  if ( myVerbose ) trace.beginBlock( "Computing voronoi map." );
205  // Voronoi diagram is computed onto complement of K.
206  CharacteristicSetPredicate inCharSet( *myCharSet );
207  NotPredicate notSetPred( inCharSet );
208  myVoronoi = new Voronoi( myDomain, notSetPred, myMetric );
209  if ( myVerbose ) trace.endBlock();
210 
211  // On parcourt le domaine pour calculer le VCM.
212  if ( myVerbose ) trace.beginBlock( "Computing VCM with R-offset." );
213  Size domain_size = myDomain.size();
214  Size di = 0;
215  MatrixNN m;
216  for ( typename Domain::ConstIterator itDomain = myDomain.begin(), itDomainEnd = myDomain.end();
217  itDomain != itDomainEnd; ++itDomain )
218  {
219  if ( myVerbose ) trace.progressBar(++di,domain_size);
220  Point p = *itDomain;
221  Point q = (*myVoronoi)( p ); // closest site to p
222  if ( q != p )
223  {
224  double d = myMetric( q, p );
225  if ( d <= myBigR ) // We restrict computation to the R offset of K.
226  {
227  VectorN v = p - q;
228  // Computes tensor product V^t x V
229  for ( Dimension i = 0; i < Space::dimension; ++i )
230  for ( Dimension j = 0; j < Space::dimension; ++j )
231  m.setComponent( i, j, v[ i ] * v[ j ] );
232  myVCM[ q ] += m;
233  }
234  }
235  }
236  if ( myVerbose ) trace.endBlock();
237 
238  if ( myVerbose ) trace.endBlock();
239 }
240 
241 //-----------------------------------------------------------------------------
242 template <typename TSpace, typename TSeparableMetric>
243 template <typename Point2ScalarFunction>
244 inline
245 typename DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::MatrixNN
246 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
247 measure( Point2ScalarFunction chi_r, Point p ) const
248 {
249  ASSERT( myProximityStructure != 0 );
250  std::vector<Point> neighbors;
251  Point b = myProximityStructure->bin( p );
252  myProximityStructure->getPoints( neighbors,
253  b - Point::diagonal(1),
254  b + Point::diagonal(1) );
255  MatrixNN vcm;
256  // std::cout << *it << " has " << neighbors.size() << " neighbors." << std::endl;
257  for ( typename std::vector<Point>::const_iterator it_neighbors = neighbors.begin(),
258  it_neighbors_end = neighbors.end(); it_neighbors != it_neighbors_end; ++it_neighbors )
259  {
260  Point q = *it_neighbors;
261  Scalar coef = chi_r( q - p );
262  if ( coef > 0.0 )
263  {
264  typename std::map<Point,MatrixNN>::const_iterator it = myVCM.find( q );
265  ASSERT( it != myVCM.end() );
266  MatrixNN vcm_q = it->second;
267  vcm_q *= coef;
268  vcm += vcm_q;
269  }
270  }
271  return vcm;
272 }
273 
274 //-----------------------------------------------------------------------------
275 template <typename TSpace, typename TSeparableMetric>
276 inline
277 const typename DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::Point2MatrixNN&
278 DGtal::VoronoiCovarianceMeasure<TSpace,TSeparableMetric>::
279 vcmMap() const
280 {
281  return myVCM;
282 }
283 
284 ///////////////////////////////////////////////////////////////////////////////
285 // Interface - public :
286 
287 /**
288  * Writes/Displays the object on an output stream.
289  * @param out the output stream where the object is written.
290  */
291 template <typename TSpace, typename TSeparableMetric>
292 inline
293 void
294 DGtal::VoronoiCovarianceMeasure<TSpace, TSeparableMetric>::
295 selfDisplay ( std::ostream & out ) const
296 {
297  out << "[VoronoiCovarianceMeasure]";
298 }
299 
300 /**
301  * Checks the validity/consistency of the object.
302  * @return 'true' if the object is valid, 'false' otherwise.
303  */
304 template <typename TSpace, typename TSeparableMetric>
305 inline
306 bool
307 DGtal::VoronoiCovarianceMeasure<TSpace, TSeparableMetric>::
308 isValid() const
309 {
310  return true;
311 }
312 
313 
314 
315 ///////////////////////////////////////////////////////////////////////////////
316 // Implementation of inline functions //
317 
318 template <typename TSpace, typename TSeparableMetric>
319 inline
320 std::ostream&
321 DGtal::operator<< ( std::ostream & out,
322  const VoronoiCovarianceMeasure<TSpace, TSeparableMetric> & object )
323 {
324  object.selfDisplay( out );
325  return out;
326 }
327 
328 // //
329 ///////////////////////////////////////////////////////////////////////////////
330 
331