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.
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.
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/>.
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
24 * Implementation of inline methods defined in Signal.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
33 //////////////////////////////////////////////////////////////////////////////
36 //////////////////////////////////////////////////////////////////////////////
37 // class SignalData<TValue>
38 //////////////////////////////////////////////////////////////////////////////
43 template <typename TValue>
45 DGtal::SignalData<TValue>::SignalData()
52 * @param s the number of data in the signal.
53 * @param z the index of the zero-th element.
54 * @param p 'true' if the signal is periodic.
55 * @param def the default value.
57 template <typename TValue>
60 DGtal::SignalData<TValue>::init
61 ( unsigned int s, int z, bool p, const Value & def )
63 if ( data != 0 ) delete[] data;
64 size = s; zero = z; periodic = p;
65 data = new TValue[ size + 1 ];
72 * @param t the array containing initial data.
73 * @param s the number of data in the signal.
74 * @param z the index of the zero-th element.
75 * @param p 'true' if the signal is periodic.
76 * @param def the default value.
78 template <typename TValue>
81 DGtal::SignalData<TValue>::init
82 ( const Value* t, unsigned int s, int z, bool p, const Value& def )
84 if ( data != 0 ) delete[] data;
85 size = s; zero = z; periodic = p;
86 data = new TValue[ size + 1 ];
87 for ( unsigned int i = 0; i < size; ++i, ++t )
96 * @param s the number of data in the signal.
97 * @param z the index of the zero-th element.
98 * @param p 'true' if the signal is periodic.
99 * @param def the default value.
101 template <typename TValue>
103 DGtal::SignalData<TValue>::SignalData
104 ( unsigned int s, int z, bool p, const Value & def )
105 : size( s ), zero( z ), periodic( p )
107 data = new TValue[ size + 1 ];
114 * @param t the array containing initial data.
115 * @param s the number of data in the signal.
116 * @param z the index of the zero-th element.
117 * @param p 'true' if the signal is periodic.
118 * @param def the default value.
120 template <typename TValue>
122 DGtal::SignalData<TValue>::SignalData
123 ( const TValue* t, unsigned int s, int z, bool p, const Value & def )
124 : size( s ), zero( z ), periodic( p )
126 data = new TValue[ size + 1 ];
127 for ( unsigned int i = 0; i < size; ++i )
136 template <typename TValue>
138 DGtal::SignalData<TValue>::~SignalData()
140 if ( data != 0 ) delete[] data;
145 * @param other the data to clone.
147 template <typename TValue>
149 DGtal::SignalData<TValue>::SignalData
150 ( const SignalData & other )
151 : size( other.size ), zero( other.zero ), periodic( other.periodic )
153 if ( other.data != 0 )
155 data = new TValue[ size + 1 ];
156 for ( unsigned int i = 0; i <= size; ++i )
157 data[ i ] = other.data[ i ];
165 * @param other the data to clone.
168 template <typename TValue>
170 DGtal::SignalData<TValue> &
171 DGtal::SignalData<TValue>::operator=
172 ( const SignalData & other )
174 if ( this != &other )
176 if ( other.data == 0 )
184 if ( size < other.size )
187 data = new TValue[ other.size + 1 ];
191 periodic = other.periodic;
192 for ( unsigned int i = 0; i <= size; ++i )
193 data[ i ] = other.data[ i ];
202 * @return the default value.
204 template <typename TValue>
207 DGtal::SignalData<TValue>::defaut() const
215 ///////////////////////////////////////////////////////////////////////////////
216 // IMPLEMENTATION of inline methods.
217 ///////////////////////////////////////////////////////////////////////////////
219 ///////////////////////////////////////////////////////////////////////////////
220 // ----------------------- Standard services ------------------------------
223 /////////////////////////////////////////////////////////////////////////////
225 /////////////////////////////////////////////////////////////////////////////
229 template <typename TValue>
231 DGtal::Signal<TValue>::Signal()
238 * @param asize the size of the signal.
239 * @param z the index of the zero-th element.
240 * @param periodic 'true' if the signal is periodic.
241 * @param def the default value.
243 template <typename TValue>
245 DGtal::Signal<TValue>::Signal
246 ( unsigned int asize, int z, bool periodic, const TValue & def )
247 : m_data( new SignalData<TValue>() )
249 m_data->init( asize, z, periodic, def );
255 * @param t the array containing initial data.
256 * @param asize the size of the signal.
257 * @param z the index of the zero-th element.
258 * @param periodic 'true' if the signal is periodic.
259 * @param def the default value.
261 template <typename TValue>
263 DGtal::Signal<TValue>::Signal
264 ( const TValue* t, unsigned int asize, int z, bool periodic,
266 : m_data( new SignalData<TValue>() )
268 m_data->init( t, asize, z, periodic, def );
276 template <typename TValue>
278 DGtal::Signal<TValue>::~Signal()
284 * @param other the object to clone.
285 * Forbidden by default.
287 template <typename TValue>
289 DGtal::Signal<TValue>::Signal( const Signal & other )
290 : m_data( other.m_data )
296 * @param other the object to copy.
297 * @return a reference on 'this'.
298 * Forbidden by default.
300 template <typename TValue>
302 DGtal::Signal<TValue> &
303 DGtal::Signal<TValue>::operator=( const Signal & other )
305 if ( this != & other )
306 m_data = other.m_data;
314 * @param aSize the size of the signal.
315 * @param z the index of the zero-th element.
316 * @param periodic 'true' if the signal is periodic.
317 * @param def the default value.
319 template <typename TValue>
322 DGtal::Signal<TValue>::init
323 ( unsigned int aSize, int z, bool periodic, const TValue & def )
325 m_data = CowPtr< SignalData<TValue> >( new SignalData<TValue>() );
326 m_data->init( aSize, z, periodic, def );
332 * @param t the array containing initial data.
333 * @param aSize the size of the signal.
334 * @param z the index of the zero-th element.
335 * @param periodic 'true' if the signal is periodic.
336 * @param def the default value.
338 template <typename TValue>
341 DGtal::Signal<TValue>::init
342 ( const TValue* t, unsigned int aSize, int z, bool periodic,
345 m_data = CowPtr< SignalData<TValue> >( new SignalData<TValue>() );
346 m_data->init( t, aSize, z, periodic, def );
352 @return the number of elements in the signal.
354 template <typename TValue>
356 DGtal::Signal<TValue>::size() const
362 ///////////////////////////////////////////////////////////////////////////////
363 // ----------------------- Signal services ----------------------------
367 * Protected rw access to value. If index is out of bound, return 0
368 * if not periodic or the correct value otherwise.
370 * @param i the index in the signal .
372 * @return the i-th value in the signal.
374 template <typename TValue>
376 DGtal::Signal<TValue>::operator[]( int i )
378 SignalData<TValue> & sd = *m_data;
379 int idx = i + sd.zero;
380 if ( ( idx >= 0 ) && ( idx < (int) sd.size ) )
381 return sd.data[ idx ];
382 else if ( sd.periodic )
384 idx = idx - ( idx / (int) sd.size ) * sd.size;
385 return sd.data[ ( idx + sd.size ) % sd.size ];
388 return sd.data[ sd.size ];
392 * Protected ro access to value. If index is out of bound, return 0
393 * if not periodic or the correct value otherwise.
395 * @param i the index in the signal .
397 * @return the i-th value in the signal.
399 template <typename TValue>
401 DGtal::Signal<TValue>::operator[]( int i ) const
403 const SignalData<TValue> & sd = *m_data;
404 int idx = i + sd.zero;
405 if ( ( idx >= 0 ) && ( idx < (int) sd.size ) )
406 return sd.data[ idx ];
407 else if ( sd.periodic )
409 idx = idx - ( idx / (int) sd.size ) * sd.size;
410 return sd.data[ ( idx + sd.size ) % sd.size ];
413 return sd.data[ sd.size ];
418 * The signal becomes a constant signal of value [val].
420 * @param val the value of the whole signal.
422 template <typename TValue>
424 DGtal::Signal<TValue>::setAll( const TValue & val )
426 SignalData<TValue> & sd = *m_data;
427 for ( unsigned int i = 0; i <= sd.size; ++i )
433 * External product of a signal by a scalar value.
435 * @param l the external value.
437 template <typename TValue>
439 DGtal::Signal<TValue>::multiply( const TValue & l )
441 SignalData<TValue> & sd = *m_data;
442 for ( unsigned int i = 0; i <= sd.size; ++i )
448 * Convolution product of two signals (F = this).
449 * F*G( a ) = sum F(a-i)G(i)
451 * @param G the second signal (not periodic)
453 * @return the signal that is the convolution of F and G, of type F.
455 template <typename TValue>
456 DGtal::Signal<TValue>
457 DGtal::Signal<TValue>::operator*( const Signal<TValue>& G )
459 const SignalData<TValue>& Fd = *m_data;
460 const SignalData<TValue>& Gd = *G.m_data;
463 unsigned int aSize = Fd.periodic ? Fd.size : Fd.size + Gd.size - 1;
464 int zero = Fd.periodic ? Fd.zero : Fd.zero + Gd.zero;
465 Signal<TValue> FG( aSize, zero, Fd.periodic, Fd.defaut() );
466 SignalData<TValue>& FGd = *FG.m_data;
470 for ( int a = 0; a < (int) FGd.size; ++a )
472 TValue sum = TValue( 0 );
473 for ( unsigned int i = 0; i < Gd.size; ++i )
475 sum += this->operator[]( a - ( i - Gd.zero ) )
483 for ( unsigned int a = 0; a < FGd.size; ++a )
485 TValue sum = TValue( 0 );
486 for ( unsigned int i = 0; i < Gd.size; ++i )
488 sum += this->operator[]( a - ( Fd.zero + Gd.zero )
500 template <typename TValue>
501 DGtal::Signal<TValue>
502 DGtal::Signal<TValue>::G2()
504 Signal<TValue> G = H2();
510 * @return the binomial signal of order 2.
512 template <typename TValue>
513 DGtal::Signal<TValue>
514 DGtal::Signal<TValue>::H2()
516 Signal<TValue> H( 3, 1, false, TValue( 0 ) );
524 * @return the right difference signal.
526 template <typename TValue>
527 DGtal::Signal<TValue>
528 DGtal::Signal<TValue>::Delta()
530 Signal<TValue> D( 2, 0, false, TValue( 0 ) );
536 template <typename TValue>
537 DGtal::Signal<TValue>
538 DGtal::Signal<TValue>::G2n( unsigned int n )
540 if ( n <= 1 ) return G2();
541 else return G2n( n - 1 ) * G2();
545 * @return the binomial signal of order 2n.
547 template <typename TValue>
548 DGtal::Signal<TValue>
549 DGtal::Signal<TValue>::H2n( unsigned int n )
551 if ( n <= 1 ) return H2();
552 else return H2n( n - 1 ) * H2();
556 * @return the differential operator with binomial weights of order 2n.
558 template <typename TValue>
559 DGtal::Signal<TValue>
560 DGtal::Signal<TValue>::D2n( unsigned int n )
562 return H2n( n ) * Delta();
566 ///////////////////////////////////////////////////////////////////////////////
567 // Interface - public :
570 * Writes/Displays the object on an output stream.
571 * @param out the output stream where the object is written.
573 template <typename TValue>
576 DGtal::Signal<TValue>::selfDisplay ( std::ostream & out ) const
578 out << "[Signal" << std::fixed << std::setprecision( 5 );
579 for ( unsigned int i = 0; i < size(); ++i )
580 out << " " << ( ( i == (unsigned int) m_data->zero ) ? "*" : "" )
581 << m_data->data[ i ];
586 * Checks the validity/consistency of the object.
587 * @return 'true' if the object is valid, 'false' otherwise.
589 template <typename TValue>
592 DGtal::Signal<TValue>::isValid() const
599 ///////////////////////////////////////////////////////////////////////////////
600 // Implementation of inline functions //
602 template <typename TValue>
605 DGtal::operator<< ( std::ostream & out,
606 const Signal<TValue> & object )
608 object.selfDisplay( out );
613 ///////////////////////////////////////////////////////////////////////////////