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//////////////////////////////////////////////////////////////////////////////
43template <typename TValue>
45DGtal::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.
57template <typename TValue>
60DGtal::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.
78template <typename TValue>
81DGtal::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.
101template <typename TValue>
103DGtal::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.
120template <typename TValue>
122DGtal::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 )
136template <typename TValue>
138DGtal::SignalData<TValue>::~SignalData()
140 if ( data != 0 ) delete[] data;
145 * @param other the data to clone.
147template <typename TValue>
149DGtal::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.
168template <typename TValue>
170DGtal::SignalData<TValue> &
171DGtal::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.
204template <typename TValue>
207DGtal::SignalData<TValue>::defaut() const
215///////////////////////////////////////////////////////////////////////////////
216// IMPLEMENTATION of inline methods.
217///////////////////////////////////////////////////////////////////////////////
219///////////////////////////////////////////////////////////////////////////////
220// ----------------------- Standard services ------------------------------
223/////////////////////////////////////////////////////////////////////////////
225/////////////////////////////////////////////////////////////////////////////
229template <typename TValue>
231DGtal::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.
243template <typename TValue>
245DGtal::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.
261template <typename TValue>
263DGtal::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 );
276template <typename TValue>
278DGtal::Signal<TValue>::~Signal()
284 * @param other the object to clone.
285 * Forbidden by default.
287template <typename TValue>
289DGtal::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.
300template <typename TValue>
302DGtal::Signal<TValue> &
303DGtal::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.
319template <typename TValue>
322DGtal::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.
338template <typename TValue>
341DGtal::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.
354template <typename TValue>
356DGtal::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.
374template <typename TValue>
376DGtal::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.
399template <typename TValue>
401DGtal::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.
422template <typename TValue>
424DGtal::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.
437template <typename TValue>
439DGtal::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.
455template <typename TValue>
457DGtal::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 )
500template <typename TValue>
502DGtal::Signal<TValue>::G2()
504 Signal<TValue> G = H2();
510 * @return the binomial signal of order 2.
512template <typename TValue>
514DGtal::Signal<TValue>::H2()
516 Signal<TValue> H( 3, 1, false, TValue( 0 ) );
524 * @return the right difference signal.
526template <typename TValue>
528DGtal::Signal<TValue>::Delta()
530 Signal<TValue> D( 2, 0, false, TValue( 0 ) );
536template <typename TValue>
538DGtal::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.
547template <typename TValue>
549DGtal::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.
558template <typename TValue>
560DGtal::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.
573template <typename TValue>
576DGtal::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.
589template <typename TValue>
592DGtal::Signal<TValue>::isValid() const
599///////////////////////////////////////////////////////////////////////////////
600// Implementation of inline functions //
602template <typename TValue>
605DGtal::operator<< ( std::ostream & out,
606 const Signal<TValue> & object )
608 object.selfDisplay( out );
613///////////////////////////////////////////////////////////////////////////////